ในการใช้งาน 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
AIN0PA2
AIN1PA1
AIN2PC4
AIN3PD2
AIN4PD3
AIN5PA5
AIN6PA6

สรุปง่าย ๆ:

  • ถ้าต้องการวัดค่า ADC ช่อง 0 → ให้ต่อสัญญาณที่ ขา PA2
  • ถ้าต้องการวัดช่อง 5 → ต่อที่ PA5 เป็นต้น

📋 ลำดับขั้นตอนการเขียนโปรแกรม ใช้งาน ADC

จะเรียงเป็น Step-by-Step นะครับ

ลำดับรายละเอียดฟังก์ชันที่ใช้
1เปิด Clock ของ GPIO และ ADCRCC_APB2PeriphClockCmd()
2ตั้งค่า Pin ให้เป็น InputGPIO_Init() (เป็น Floating Input)
3ตั้งค่า ADC (Mode, Align, Scan, Trigger)ADC_Init()
4เปิดใช้งาน ADCADC_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)
}

🎯 สรุปลำดับการทำงานจริง

  1. เปิด Clock Peripheral ที่เกี่ยวข้อง (GPIO, ADC)
  2. ตั้งค่า Pin เป็น Input Mode (แนะนำ Floating input หรือ Analog input)
  3. Init ADC ด้วยโหมดที่ต้องการ
  4. ทำ Calibration เพื่อความแม่นยำ
  5. ตั้ง ADC ให้อ่านช่องที่ต้องการ (AINx)
  6. Start Conversion
  7. อ่านค่า 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 → อ่านค่า