ในการใช้งาน ADC ของ CH32V003 จำเป็นที่จะต้องรู้ว่า วงจรของ ADC ทำงานอยู่กับ Port / Pin ไหนของ MCU ถ้าเราใช้งานไม่ถูกต้อง ก็จะไม่สามารถวัดค่าสัญญาณ ADC ได้ โดยทั่วไปแล้ว จะมีเอกสารบอกว่า Port / Pin ไหนที่เชื่อมต่อกับ วงจร ADC ไว้ เรามาดูวิธีการหา และ วิธีการเขียนโปรแกรม เพื่อใช้งานกัน
1. ดูในเอกสาร Datasheet ของ MCU (CH32V003)

จาก ข้อมูลของ Data Sheet MCU
สรุปว่า CH32V003 มี 8 ช่อง ADC (AIN0 – AIN7)
Pin Mapping (ต่อออกขาจริงๆ) มีดังนี้:
ADC Channel | เชื่อมต่อกับ GPIO Pin |
---|---|
AIN0 | PA2 |
AIN1 | PA1 |
AIN2 | PC4 |
AIN3 | PD2 |
AIN4 | PD3 |
AIN5 | PA5 |
AIN6 | PA6 |
สรุปง่าย ๆ:
- ถ้าต้องการวัดค่า ADC ช่อง 0 → ให้ต่อสัญญาณที่ ขา PA2
- ถ้าต้องการวัดช่อง 5 → ต่อที่ PA5 เป็นต้น
📋 ลำดับขั้นตอนการเขียนโปรแกรม ใช้งาน ADC
จะเรียงเป็น Step-by-Step นะครับ
ลำดับ | รายละเอียด | ฟังก์ชันที่ใช้ |
---|---|---|
1 | เปิด Clock ของ GPIO และ ADC | RCC_APB2PeriphClockCmd() |
2 | ตั้งค่า Pin ให้เป็น Input | GPIO_Init() (เป็น Floating Input) |
3 | ตั้งค่า ADC (Mode, Align, Scan, Trigger) | ADC_Init() |
4 | เปิดใช้งาน ADC | ADC_Cmd() |
5 | ทำ Calibration (รีเซ็ตและปรับเทียบ) | ADC_ResetCalibration() , ADC_StartCalibration() |
6 | ตั้งค่า Channel, ลำดับ (Rank), เวลาสุ่ม (SampleTime) | ADC_RegularChannelConfig() |
7 | สั่งเริ่มการแปลงข้อมูล (Software หรือ Hardware Trigger) | ADC_SoftwareStartConvCmd() |
8 | อ่านค่า ADC เมื่อแปลงเสร็จ | ADC_GetConversionValue() |
🚀 ตัวอย่างโค้ดจริง (อ่านขา PC4 = AIN2)
#include "ch32v00x_rcc.h" #include "ch32v00x_gpio.h" #include "ch32v00x_adc.h" void ADC_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; /* 1. เปิด Clock ของ GPIOC และ ADC1 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1, ENABLE); /* 2. ตั้งค่า PC2 เป็น Input Floating (ค่า default) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); /* 3. ตั้งค่า ADC */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* 4. เปิด ADC */ ADC_Cmd(ADC1, ENABLE); /* 5. ทำ Calibration */ ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)); /* 6. ตั้งค่าให้ใช้ AIN2 (PC2) เป็นช่องที่อ่าน */ ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_55Cycles5); /* 7. สั่งเริ่มการแปลง */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); } uint16_t Read_ADC_Value(void) { while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // รอให้แปลงเสร็จ return ADC_GetConversionValue(ADC1); // อ่านค่า 10-bit (0-1023) }
🎯 สรุปลำดับการทำงานจริง
- เปิด Clock Peripheral ที่เกี่ยวข้อง (GPIO, ADC)
- ตั้งค่า Pin เป็น Input Mode (แนะนำ Floating input หรือ Analog input)
- Init ADC ด้วยโหมดที่ต้องการ
- ทำ Calibration เพื่อความแม่นยำ
- ตั้ง ADC ให้อ่านช่องที่ต้องการ (AINx)
- Start Conversion
- อ่านค่า Output 10-bit (0-1023)
📌 หมายเหตุเสริม:
- CH32V003 ไม่ได้มีฟังก์ชัน Auto-detect input ต้องกำหนด
Channel
ตรง ๆ เลย - Sample Time (Sampling Time) มีผลต่อความถูกต้อง ถ้า source impedance สูง → ต้องตั้ง SampleTime ยาวขึ้น
- ถ้าจะอ่านหลายช่อง (multi-channel) ต้องเปิด Scan Mode และกำหนดจำนวน Channels ให้ถูกด้วย
🚀 สรุปภาพรวมโครงสร้างโปรแกรม
เปิด Clock → ตั้งค่า GPIO → ตั้งค่า ADC → Calibration → เลือก Channel → Start → อ่านค่า