ממיר מדיגיטלי-לאנלוגי: הסבר והדגמה של מודול DAC

בפוסט קודם דיברנו על מודול החומרה NCO במיקרו-בקרים. כעת נעבור למודול אחר, נפוץ קצת יותר אך עדיין לא מוכר למשתמש הארדואינו הטיפוסי: DAC (ראשי תיבות של Digital to Analog Converter), שהוא בעצם ההיפך של ADC המוכר: לוקח ערך מספרי וממיר אותו לפלט מתח אנלוגי.

תקריב מיקרו-בקר על לוח פיתוח
כי איך אפשר לצלם DAC? 🙂

חשוב להבהיר שבניגוד לפקודת analogWrite בארדואינו, שבה הפלט הוא למעשה דיגיטלי לגמרי (HIGH או LOW) ורק מתחלף במהירות, הפלט של מודולי DAC הוא מתח אנלוגי אמתי וקבוע, שיכול להיות כל ערך בין ה-GND לבין מתח האספקה של המודול עצמו – במגבלות הרזולוציה. את הרזולוציה הזו מבטאים כמספר ביטים, שקובעים את מספר הרמות השונות האפשריות. כמו שב-ADC של ארדואינו (בעל 10 ביט) יש 2-בחזקת-10 ערכים מספריים שונים שאפשר לקבל, כך ב-DAC של 5 ביט אפשר לקבל 2-בחזקת-5, או 32, מתחים שונים. למיקרו-בקר מדגם PIC18F57Q43, שבו אשתמש כאן, יש מודול DAC יחיד ברזולוציה נוחה של 8 ביט – 256 ערכים.

יש כל מיני דרכים לממש DAC בחומרה. במיקרו-בקר שלנו כאן, הוא מבוסס על שרשרת ארוכה של נגדים, ומולטיפלקסר שבוחר – לפי הערך שאנחנו מבקשים – נקודה כלשהי לאורך השרשרת. ערכי הנגדים המצטברים לפני ואחרי אותה נקודה יוצרים "מחלק מתח" קלאסי ואת המתח שמתקבל בפועל ביציאה. בגלל צורת העבודה הזו, הזרם שאפשר להוציא מהמודול הוא אפסי: אם חשבתם לחקות בעזרתו סוללת אלקליין 1.5V לפנס או משהו כזה, צפויה לכם אכזבה מרה. ה-DAC הזה הוא למתחי רפרנס בלבד.

המבנה הפנימי של מודול DAC ב-PIC18F57Q43 (מתוך ה-datasheet של הרכיב)
המבנה הפנימי של מודול DAC ב-PIC18F57Q43 (מתוך ה-datasheet של הרכיב)

עם זאת, גם מתח רפרנס יכול להספיק כדי להפעיל מתמר פיאזו, מה שאומר שאנחנו יכולים בעיקרון להפיק סאונד אנלוגי סביר בפשטות, וזה מה שבחרתי לעשות לצורך ההדגמה. למיקרו-בקר שלנו יש 128KB של זיכרון FLASH – די והותר בשביל דגימת אודיו קצרה או שתיים!

ההדגמה

הקלטתי את עצמי אומר "נא ללחוץ" ו"נא לעזוב", שמרתי את ההקלטות בפורמט PCM גולמי, 8-ביט ללא סימן (קצב דגימה 44.1KHz, למה לא), ובעזרת תוכנת פייתון קצרה המרתי את הערכים שבקבצים האלה למספרים כתובים כטקסט ומופרדים בפסיקים, כדי שאוכל להעתיק-ולהדביק אותם כמערכי בייטים ענקיים בקוד התוכנה של המיקרו-בקר. המערך הראשון תפס 32,640 בייטים, והשני 31,616.

כדי להשמיע את הדגימות צריך משהו שיתזמן את שליחת הבייטים מהמערך לפיאזו, בקצב זהה (או קרוב ככל האפשר) לקצב הדגימה. טיימר הוא המועמד הטבעי, אך ה-NCO הפשוט מהפוסט שהזכרתי למעלה יספיק גם כן: עם שעון מערכת של 64MHz, אפשר להגיע איתו לתדר של 44.128KHz. כאן, במקום לחבר את הפלט של ה-NCO לפין פיזי, נגרום לו להפעיל פסיקה, ובתוך פונקציית הפסיקה נכתוב את הקוד ששולח בייט חדש כל פעם ל-DAC. כמובן, אני גם אגדיר פין אחר בתור פין קלט ללחצן, כדי שתהיה משמעות מעשית לדגימות הקול שהקלטתי.

כדי להפעיל את ה-DAC עצמו ב-PIC18F57Q43 צריך להכיר רק שני רגיסטרים: DAC1DATL, שהוא פשוט הערך שאנחנו רוצים לשלוח למודול (בין 0 ל-255), ו-DAC1CON ששולט באופציות השונות: ביט EN בו מפעיל/משבית את המודול כולו, צמד הביטים OE קובע לאן יילך הפלט (פין RA2, פין RB7 או ללא פלט חיצוני), צמד הביטים PSS קובע מה יהיה מקור המתח העליון עבור שרשרת הנגדים (מתח המערכת, מתח מפין חיצוני, או רפרנס פנימי קבוע) והביט NSS קובע את מקור המתח התחתון (שוב, GND של המערכת או מתח מפין חיצוני).

המבנה וחלק מהפירוט של הרגיסטר DAC1CON (נקרא ב-datasheet בשם גנרי DACxCON)
המבנה וחלק מהפירוט של הרגיסטר DAC1CON (נקרא ב-datasheet בשם גנרי DACxCON)

כהערת שוליים, המיקרו-בקר גרם לי להתקף לב קטן כשגיליתי שהסיגנל מהפוסט על ה-NCO המשיך להופיע בפין הפלט שהגדרתי שם, אף על פי שהקוד החדש שהעליתי לא כלל שום הפניית פלט כזו. בסופו של דבר, האותיות הקטנות ב-datasheet גילו שכל עוד אין POR (אתחול כתוצאה מניתוק מהחשמל וחיבור-מחדש, Power-On Reset), מודול ה-PPS ממשיך עם הפניות הפלט האחרונות שהוגדרו לו – גם אם צורבים קוד חדש לגמרי שדורס לכאורה את כל הזיכרון!

כל קוד האתחול הדרוש לפינים ולמודולי החומרה השונים בהדגמה
כל קוד האתחול הדרוש לפינים ולמודולי החומרה השונים בהדגמה

אחרי שכתבתי עוד קצת קוד בלולאה הראשית ובפונקציית הפסיקה, שהחליט איזו דגימת קול להשמיע בהתאם לקלט מהלחצן ושלח את הבייטים הרלוונטיים ל-DAC, הפרויקט הושלם. הבעיה היחידה הייתה שהצליל יצא חלש מאוד, ברמה שצריך לקרב את האוזן לפיאזו כדי לשמוע.

פונקציית הפסיקה של ה-NCO, ששולחת בייטים מהמערך שמייצג את דגימת הקול אל ה-DAC
פונקציית הפסיקה של ה-NCO, ששולחת בייטים מהמערך שמייצג את דגימת הקול אל ה-DAC

שני פתרונות קופצים מיד לראש: להיעזר ברכיב מגבר שרת עם מקור מתח גבוה יותר כדי להגביר את המתח לפיאזו, או (מה שבחרתי בסוף) להיעזר במגבר שרת כ-buffer פשוט, שייתן את אותו המתח אך יהיה מסוגל גם לתת קצת יותר זרם, ואת זה לחבר לרמקול "קלאסי" קטן. התוצאה היא עדיין לא משהו שיגרום לשכנים להתלונן למוקד של העירייה, אך מספיק בשביל לשמוע ממרחק סביר בחדר שקט:

להרשמה
הודע לי על
1 תגובה
מהכי חדשה
מהכי ישנה לפי הצבעות
Inline Feedbacks
הראה את כל התגובות

מגניב