Trong thế giới nhúng, hầu hết các tín hiệu tự nhiên như nhiệt độ, ánh sáng, âm thanh hay điện áp pin đều tồn tại ở dạng tương tự (Analog). Tuy nhiên, vi điều khiển chỉ hiểu được các con số nhị phân (Digital). Để kết nối hai thế giới này, chúng ta cần đến “người phiên dịch” ADC và DAC. Bài viết hôm nay sẽ giúp các bạn làm chủ quy trình chuyển đổi dữ liệu và thực hành đọc/xuất tín hiệu analog trên dòng STM32.
🎯 Mục tiêu học tập
- Hiểu nguyên lý chuyển đổi tín hiệu Analog sang Digital (ADC) và ngược lại (DAC).
- Nắm vững các khái niệm: Độ phân giải (Resolution), Thời gian lấy mẫu (Sampling Time), và các chế độ chuyển đổi.
- Thành thạo cấu hình ADC kết hợp với UART để giám sát dữ liệu trên máy tính.
- Lập trình xử lý ADC bằng phương pháp Ngắt (Interrupt) để tối ưu hiệu năng.
- Khám phá khả năng tạo dạng sóng (Sine, tam giác) của bộ DAC nội trong STM32.
1. Ngoại vi ADC (Analog-to-Digital Converter)
a) Khái niệm
ADC là một mạch điện tử thực hiện việc đo mức điện áp tương tự tại cổng vào và chuyển đổi nó thành một giá trị số nhị phân tương ứng. Đây là thành phần không thể thiếu để vi điều khiển “cảm nhận” được môi trường xung quanh thông qua các cảm biến.
b) Các thông số kỹ thuật cốt lõi
- Độ phân giải (Resolution): Là số bit được sử dụng để đại diện cho giá trị điện áp. STM32 thường có độ phân giải 12-bit, nghĩa là dải điện áp đầu vào được chia nhỏ thành $2^{12} = 4096$ mức (từ 0 đến 4095).Ví dụ: Với điện áp tham chiếu $V_{ref} = 3.3V$, mỗi bước nhảy (LSB) sẽ tương đương: $3.3V / 4096 \approx 0.8 mV$.
- Thời gian lấy mẫu (Sampling Time): Là khoảng thời gian bộ ADC giữ tín hiệu đầu vào để thực hiện số hóa. Thời gian lấy mẫu càng dài thì kết quả càng ổn định và chính xác, đặc biệt với các nguồn tín hiệu có trở kháng cao.
- Cờ EOC (End Of Conversion): Sau khi quá trình chuyển đổi hoàn tất, phần cứng sẽ tự động bật cờ EOC để báo cho CPU biết dữ liệu đã sẵn sàng trong thanh ghi.
c) Các chế độ hoạt động của ADC trên STM32
- Single Conversion Mode: Chuyển đổi đúng một lần rồi dừng lại.
- Continuous Conversion Mode: Chuyển đổi liên tục, vừa xong lần này sẽ tự động bắt đầu lần tiếp theo.
- Scan Mode: Quét qua một danh sách các kênh đầu vào đã chọn theo thứ tự.
- Discontinuous Mode: Chia nhóm các kênh và chuyển đổi theo từng cụm nhỏ.
2. Thực hành: Cấu hình ADC và UART giám sát dữ liệu
Chúng ta sẽ cấu hình chân PA6 để đọc điện áp Analog (từ biến trở hoặc cảm biến) và gửi giá trị đó lên màn hình máy tính thông qua UART.
Các bước cấu hình trên STM32CubeMX:
- Pinout: Chuột phải vào chân
PA6, chọn ADC1_IN6.
- Connectivity: Kích hoạt
USART1 (Mode: Asynchronous) để truyền dữ liệu.
- ADC Settings:
- Resolution: 12 bits.
- Continuous Conversion Mode: Enable.
- Sampling Time: Chọn mức trung bình (ví dụ 15 hoặc 56 Cycles) để đảm bảo độ chính xác.
- NVIC Settings: Tích chọn “ADC1, ADC2 and ADC3 global interrupts” để xử lý bằng ngắt.
- Clock: Cấu hình Clock hệ thống (HCLK) lên mức tối đa (vd: 216MHz) để hệ thống chạy mượt mà.
Mã nguồn xử lý bằng Ngắt (Interrupt):
/* Biến lưu trữ giá trị ADC */
uint16_t adc_value = 0;
char msg[50];
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
/* Cho phép ngắt ADC và bắt đầu chuyển đổi */
HAL_ADC_Start_IT(&hadc1);
while (1)
{
/* Chuyển đổi giá trị số sang chuỗi ký tự và gửi qua UART */
sprintf(msg, "ADC Value: %d\r\n", adc_value);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 100);
HAL_Delay(500); // Gửi dữ liệu mỗi 0.5 giây
}
}
/* Hàm Callback được gọi tự động khi ADC hoàn tất chuyển đổi */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1)
{
// Đọc giá trị từ thanh ghi dữ liệu ADC
adc_value = HAL_ADC_GetValue(&hadc1);
}
}
3. Ngoại vi DAC (Digital-to-Analog Converter)
Ngược lại với ADC, DAC nhận dữ liệu số từ vi điều khiển và xuất ra mức điện áp tương tự tương ứng tại chân DAC_OUT.
Tính năng và Ứng dụng:
- Độ phân giải: Thường là 12-bit, hỗ trợ căn lề trái hoặc phải.
- Tạo dạng sóng: Tích hợp bộ tạo sóng hình Sin, sóng Tam giác tự động mà không cần can thiệp quá nhiều bằng code.
- Âm thanh: Là thành phần cốt lõi trong các thiết bị chơi nhạc, giải mã MP3/WAV.
- Điều khiển: Dùng để xuất điện áp điều khiển tốc độ biến tần hoặc các driver công suất yêu cầu tín hiệu analog thay vì PWM.
💡 Lưu ý về Buffer: DAC của STM32 có một bộ đệm đầu ra (Output Buffer). Khi bật bộ đệm này, trở kháng đầu ra sẽ thấp hơn, giúp lái tải tốt hơn nhưng điện áp đầu ra sẽ không thể đạt sát mức 0V hoặc VDD.
🚀 Bài tập thực hành
Để củng cố kiến thức về Ngắt và ngoại vi, các bạn hãy thực hiện yêu cầu sau:
- Cấu hình DAC: Xuất một mức điện áp cố định 1.5V tại chân DAC và dùng đồng hồ VOM đo kiểm chứng.
- Logic Chuyển Đổi (State Machine):
- Hàm
main chỉ chứa vòng lặp while(1) trống.
- Sử dụng ngắt nút bấm (External Interrupt) để thay đổi trạng thái hệ thống.
- Lần nhấn 1: Thực thi
main1 (Nháy LED Xanh).
- Lần nhấn 2: Thực thi
main2 (Nháy LED Đỏ).
- Lần nhấn 3: Quay lại
main1.
📝 Tóm tắt: ADC giúp chúng ta “nghe” tín hiệu từ thế giới bên ngoài, còn DAC giúp chúng ta “nói” bằng ngôn ngữ của điện áp. Việc kết hợp nhuần nhuyễn hai bộ chuyển đổi này cùng với kỹ thuật xử lý ngắt sẽ giúp ứng dụng của bạn trở nên chuyên nghiệp và đáp ứng thời gian thực tốt hơn.
“Kỹ sư nhúng là người xây dựng cây cầu nối giữa những con số 0-1 khô khan và những tín hiệu tương tự mềm mại của tự nhiên.”
Gợi ý bài tiếp theo: Làm Chủ Giao Tiếp UART Và SPI Trong Hệ Thống Nhúng.