จากที่ได้อ่านบทความ การใช้งาน STM32 Core Support for Arduino สำหรับบอร์ด Nucleo L432KC ของอาจารย์ เรวัต ศิริโภคาภิรมย์ ทางเราเลยได้จัดหาบอร์ดมาทดลองใช้งานและเชื่อมต่อขาสำหรับส่งข้อมูลออก DAC ไปยัง ADC ตามภาพที่ 1 เพื่อทดสอบการทำงานของภาค DAC และ ADC ของบอร์ดโดยใช้โค้ดการทำงานเหมือนกับบอร์ดไมโครคอนโทรลเลอร์ ESP32, SAM-D21 และ LGT8F328P ว่าเป็นอย่างไร มาติดตามกันครับ
คุณสมบัติของ STM32L432
STM32L432 เป็นไมโครคอนโทรลเลอร์สถาปัตยกรรม ARM แบบ 32 บิต แบบ Cortex-M4 แบบประหยัดพลังงาน โดยคุณสมบัติของชิพตัวนี้จากเอกสาร Data Sheet และเว็บ armMBED กับ Zephyr เป็นดังนี้
- รองรับการคำนวณทศนิยมโดยมี FPU (Floating Point Unit) มาในตัว
- ความถี่สัญญาณนาฬิกา 80MHz
- มี Timer จำนวน 11 ตัว
- ฮาร์ดแวร์รองรับ RTC
- มีขา I/O แบบความเร็วสูงที่รองรับการใช้งานกับ 5V จำนวน 26 ขา
- มี 2 PLL สำหรับสัญญาณนาฬิกาของระบบ, USB, Audio และ ADC
- มีหน่วยความจำแรม 64KB
- มีหน่วยความจำรอม 256KB
- มี ADC ความละเอียด 12 บิต จำนวน 1 ช่องสัญญาณ
- มี DAC ความละเอียด 12 บิต จำนวน 2 ช่องสัญญาณ
- รองรับการทำงาน USB OTG 2.0, SAI (serial audio interface), I2C, USART, SPI, CAN, SWPMI และ IRTIM (Infrared interface)
- ทำ DMA ได้ 14 ช่องสัญญาณ
- รองรับ True random number generator
- มีหน่วยประมวลผลสำหรับคำนวณ CRC
ตัวบอร์ดเป็น Neucleo-32 ดังภาพที่ 2
จากภาพที่ 2 จะพบว่ามีขาสำหรับ ADC และ DAC ดังนี้
- Analogin หรือ ADC อยู่ที่ D3 หรือขา PB_0
- AnalogOut หรือ DAC อยู่ที่ขา A3 และ A4 หรือขา PA_4 และ PA_5
การตั้งค่าสำหรับบอร์ด Neucleo L432KC เป็นตามภาพที่ 3
ตัวอย่างโปรแกรม
ตัวอย่างโปรแกรมวาดกราฟ 3 แบบ คือ กราฟฟันปลา กราฟสามเหลี่ยม และกราฟคลื่นไซน์ มีโค้ดการทำงานดังนี้
กราฟฟันปลา
การสร้างกราฟฟันปลาเป็นการส่งค่า 0 ถึงค่าสูงสุดที่เป็นไปได้ของภาค DAC หลังจากนั้นวนรอบส่งใหม่อีกครั้ง โดยโค้ดสำหรับ STM32L432 เป็นดังนี้ และได้ผลลัพธ์ดังตัวอย่างภาพที่ 4
#include <Arduino.h>
#include <math.h>
#define pinSpk A3 // PA4
#define pinMic D3 // PB0
#define ADC_BITS 12
#define DAC_BITS 12
#define MAX_VALUE pow(2,DAC_BITS)
int adcValue;
void setup() {
Serial.begin(115200);
analogReadResolution(ADC_BITS);
analogWriteResolution(DAC_BITS);
}
void loop() {
for (int i = 0; i < MAX_VALUE; i += 16) {
analogWrite( pinSpk, i);
adcValue = analogRead(pinMic);
Serial.println(adcValue);
}
}
กราฟสามเหลี่ยม
กราฟสามเหลี่ยมมีหลักการคล้ายกับฟันปลาด้วยการเพิ่มการวนรอบเพื่อส่งค่ามากสุดกลับมาเป็น 0 ดังโค้ดของ STM32L432 ดังต่อไปนี้ และตัวอย่างผลลัพธ์เป็นดังภาพที่ 5
#include <Arduino.h>
#include <math.h>
#define pinSpk A3 // PA4
#define pinMic D3 // PB0
#define ADC_BITS 12
#define DAC_BITS 12
#define MAX_VALUE pow(2,DAC_BITS)
int adcValue;
void setup() {
Serial.begin(115200);
analogReadResolution(ADC_BITS);
analogWriteResolution(DAC_BITS);
}
void loop() {
for (int i = 0; i < MAX_VALUE; i += 32) {
analogWrite( pinSpk, i);
adcValue = analogRead(pinMic);
Serial.println(adcValue);
}
for (int i = MAX_VALUE-1; i >= 0; i -= 32) {
analogWrite( pinSpk, i);
adcValue = analogRead(pinMic);
Serial.println(adcValue);
}
}
กราฟคลื่นไซน์
การสร้างกราฟคลื่นรูปไซน์ใช้การกำหนดให้มีการวนรอบเพื่อเพิ่มค่ามุมองศาจาก 0 ไปถึง 359 โดยในแต่ละรอบทำสิ่งต่อไปนี้
- แปลงค่าองศาเป็นเรเดียน
- คำนวณหาไซน์จากมุมเรเดียน
- แปลงค่าทศนิยมให้เป็นจำนวนเต็มในช่วงค่าที่ DAC รองรับ
- อ่านค่าจาก ADC
- ส่งข้อมูลออกทางพอร์ตอนุกรมให้โปรแกรม Serial Plotter
โค้ดสำหรับ STM32L432 เป็นดังนี้ และตัวอย่างผลลัพธ์ดังภาพที่ 6
#include <Arduino.h>
#include <math.h>
#define pinSpk A3 // PA4
#define pinMic D3 // PB0
#define ADC_BITS 12
#define DAC_BITS 12
#define MAX_VALUE pow(2,DAC_BITS)
int adcValue;
void setup() {
Serial.begin(115200);
analogReadResolution(ADC_BITS);
analogWriteResolution(DAC_BITS);
}
void loop() {
int degree = 0;
float radian = 0.0;
float sineValue = 0.0;
int dValue = 0;
for (degree = 0; degree < 360; degree++) {
radian = (float)degree * (2.0 * 3.1415926) / 360.0;
sineValue = sin(radian);
dValue = (int)((1.0 + sineValue) * ((MAX_VALUE/2)-1));
analogWrite( pinSpk, dValue );
adcValue = analogRead(pinMic);
Serial.println(adcValue);
}
}
สรุป
จากบทความนี้จะพบว่า ADC ของ STM32L432 มี 1 ช่องสัญญาณ แต่ให้ DAC มาอีก 2 ช่อง พร้อมความละเอียดในการทำงานที่ 12 บิต ทำให้เหมาะกับการประมวลผลหรือสร้างเสียงเพื่อออกเป็นลำโพงซ้ายและขวาที่มีความละเอียดสูงกว่าไมโครคอนโทรลเลอร์ตัวอื่น ๆ ที่ได้เขียนถึงมาก่อนหน้านี้ สุดท้าย ขอให้สนุกกับการเขียนโปรแกรมครับ
(C) 2020-2022, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-11-21, 2022-01-26