ในการใช้งาน 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 → อ่านค่า
