这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【CH582M】CH582M的ADC功能(7)-----单通道DMA模式采集数据

共1条 1/1 1 跳转至页

【CH582M】CH582M的ADC功能(7)-----单通道DMA模式采集数据

专家
2026-10-17 22:39:19     打赏

单通道DMA模式下,需要增加ADC中断处理、设置DMA相关参数。采集用电路与单通道的模式一样:

image.png

代码为:

#include "CH58x_common.h"

uint16_t adcBuff[40];

volatile uint8_t adclen;
volatile uint8_t DMA_end = 0;

/*********************************************************************
 * @fn      DebugInit
 *
 * @brief   调试初始化
 *
 * @return  none
 */
void DebugInit(void)
{
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
    UART1_DefInit();
}

/**
 * @brief  将ADC原始值转换为实际电压(mV)
 * @param  adc_raw: 12位ADC原始值
 * @param  pga_gain: 初始化时使用的增益,用于电压换算
 * @return 电压值,单位mV
 */
uint32_t ADC_RawToVoltage_mV(uint16_t adc_raw, uint8_t pga_gain)
{
    // CH58x的Vref ≈ 1050mV(典型值),实际应在1.035V~1.065V之间
    const uint32_t VREF_MV = 1050;

    // 增益换算系数 P:0dB→1,6dB→2,-6dB→1/2,-12dB→1/4
    // 公式基于差分模式中间码0x800(2048)计算:
    // 单端模式下,Vin = (|adc_raw - 2048| / 2048 / P) * Vref
    // 此处简化为0dB增益下的正向电压换算(adc_raw通常>2048)
    uint32_t voltage_mv;
    if (adc_raw >= 2048) {
        voltage_mv = ((uint32_t)(adc_raw - 2048) * VREF_MV) / (2048 * pga_gain);
    } else {
        voltage_mv = ((uint32_t)(2048 - adc_raw) * VREF_MV) / (2048 * pga_gain);
    }
    return voltage_mv;
}

/*********************************************************************
 * @fn      main
 *
 * @brief   主函数
 *
 * @return  none
 */
int main()
{
    uint8_t      i;
    signed short RoughCalib_Value = 0; // ADC粗调偏差值

    SetSysClock(CLK_SOURCE_PLL_60MHz);

    /* 配置串口调试 */
    DebugInit();

    /* DMA单通道采样:选择adc通道0做采样,对应 PA4引脚 */
    GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);

    // 单通道模式:采样频率3.2MHz,增益0dB
    ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);

    // 获取 ADC 内部粗调偏差值,提高精度
    RoughCalib_Value = ADC_DataCalib_Rough();

    /* 4. 选择 ADC 通道 0(对应 PA4/AIN0) */
    ADC_ChannelCfg(0);

    // 采样周期为 (256-192)*16个系统时钟
    ADC_AutoConverCycle(192);

    // 配置DMA 
    ADC_DMACfg(ENABLE, (uint16_t)(uint32_t)&adcBuff[0], (uint16_t)(uint32_t)&adcBuff[40], ADC_Mode_Single);

    // 允许ADC中断
    PFIC_EnableIRQ(ADC_IRQn);

    // 开启自动连续 ADC 采集
    ADC_StartDMA();

    // 等待DMA完成
    while(!DMA_end);


    while(1) {
        // 等待DMA完成
        while(!DMA_end);
        DMA_end = 0;

        for(i = 0; i < 40; i++) {
            // 转换为电压数据(mV)输出
            PRINT("%d \n", ADC_RawToVoltage_mV(adcBuff[i], 1));
        }

        DelayMs(100);

        // 重新配置DMA 
        ADC_DMACfg(ENABLE, (uint16_t)(uint32_t)&adcBuff[0], (uint16_t)(uint32_t)&adcBuff[40], ADC_Mode_Single);
       
        // 开启自动连续 ADC 采集
        ADC_StartDMA();

    }
}

输出结果同样用串口绘制曲线的形式:

image.png

产生了锯齿状的波形,最大最小值在8mV左右,这个精度也能接受吧。




关键词: CH582M     ADC    

共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]