这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【CW32F030C8T6】:ADC功能调试

共1条 1/1 1 跳转至

【CW32F030C8T6】:ADC功能调试

高工
2026-09-17 20:50:36     打赏

一:ADC知识分享

1.1 ADC 简介

CW32F030 内部集成一个 12 位精度、最高 1M SPS(每秒采样次数)转换速度的逐次逼近型(SAR)模数转换器,最多可将 16 路模拟输入信号转换为数字信号,另含 1 路内部温度传感器通道,可用于芯片温度监测。现实世界中的温度、电压、电流、光强等模拟量,都需要先经 ADC 转换为数字量,才能交给 MCU 进行运算和处理。

1.2 主要特点

12 位分辨率,精度 ±1 LSB,有效位数可达 11.3 ENOB;

最高 1M SPS 转换速率,满足绝大多数中低速采集场景;

最多 16 路外部模拟输入通道,支持多路信号分时采集;

内置信号跟随器(输入缓冲),可直接测量高阻抗信号源;

4 种参考电压可选:VDDA、外部参考 ExRef、内置 1.5V、内置 2.5V;

支持多种转换模式:单次转换、多次转换、连续转换、序列扫描转换、序列断续转换,均支持转换累加功能;

支持 DMA 搬运转换结果,降低 CPU 负担;

内置模拟看门狗,可对转换结果进行阈值监控。

1.3  应用场景

电压、电流检测:如电压电流表、USB 功率计、电池电量监测;

温度测量:配合 NTC 热敏电阻或使用内部温度传感器;

传感器数据采集:光敏、压力、湿度、摇杆等模拟传感器信号;

电源管理与监控:监测电源轨电压、功耗估算;

工业与仪器仪表:便携式测量仪表、数据采集终端;

消费电子:按键/滑条检测、环境光感应、LED 调光反馈等。

1.4 使用注意事项

上电后应执行一次 ADC 校准(ADC_Calibration),否则转换精度会受影响;

采样时间(SampleTime)要与信号源内阻匹配:信号源阻抗较高时,应适当增大采样时间,让采样保持电容充分充电,否则转换结果会偏低;

参考电压选择要与输入信号量程匹配,输入电压不得超过参考电压与 VDDA 的范围;

输入缓冲器(跟随器)开启时可测量高阻抗信号,但会引入一定增益/失调误差,精度要求高时可关闭并在外部做好阻抗匹配;

模拟通道引脚输入电压不应超出 VDDA/AGND 范围,防止损坏或串扰;

PCB 布局上,参考电压和模拟电源应做好滤波,模拟走线远离数字信号,保证地平面完整;

对波动或含噪声的信号,建议在软件中做均值/滑动滤波后再使用;

ADC 时钟分频(ClkDiv)决定转换速率,需在精度与速度之间取舍,分频越小速度越快,但对电源和布局的要求越高。

二:软件代码

2.1 ADC初始化

void ADC_Configuration(void)
{
   ADC_SingleChTypeDef ADC_SingleInitStruct;

  __RCC_ADC_CLK_ENABLE();    // ADC时钟使能
        __RCC_GPIOB_CLK_ENABLE();

        //配置ADC测试IO口  电位器接口
  PB00_ANALOG_ENABLE();
  ADC_SingleInitStruct.ADC_Chmux = ADC_ExInputCH8;         //通道4输入PB00
  ADC_SingleInitStruct.ADC_DiscardEn = ADC_DiscardNull;
  ADC_SingleInitStruct.ADC_InitStruct.ADC_AccEn = ADC_AccDisable;   //转换结果累加不使能
  ADC_SingleInitStruct.ADC_InitStruct.ADC_Align = ADC_AlignRight;   //ADC转换结果右对齐
  ADC_SingleInitStruct.ADC_InitStruct.ADC_ClkDiv = ADC_Clk_Div16;   //PCLK  
  ADC_SingleInitStruct.ADC_InitStruct.ADC_DMAEn = ADC_DmaDisable;   //关闭DMA传输
  ADC_SingleInitStruct.ADC_InitStruct.ADC_InBufEn = ADC_BufEnable;  //开启跟随器
  ADC_SingleInitStruct.ADC_InitStruct.ADC_OpMode = ADC_SingleChOneMode;   
  ADC_SingleInitStruct.ADC_InitStruct.ADC_SampleTime = ADC_SampTime5Clk; //5个ADC时钟周期
  ADC_SingleInitStruct.ADC_InitStruct.ADC_TsEn = ADC_TsDisable;    //内置温度传感器禁用
  ADC_SingleInitStruct.ADC_InitStruct.ADC_VrefSel = ADC_Vref_VDDA;//VDDA参考电压
  ADC_SingleInitStruct.ADC_WdtStruct.ADC_WdtAll = ADC_WdtDisable;    

  ADC_SingleChOneModeCfg(&ADC_SingleInitStruct);
  ADC_Enable();    // 使能ADC
        
        ADC_SoftwareStartConvCmd(ENABLE);
}

2.2 读取ADC功能

    if(timecount>200)//每200ms单次转换一次,并通过OLED显示
    {
        timecount=0;                
        ADC_SoftwareStartConvCmd(ENABLE);
        while(ADC_GetITStatus(ADC_IT_EOC))
        {
            ADC_ClearITPendingBit(ADC_IT_EOC);      
            adcvalue=ADC_GetConversionValue();                
            temp=(float)adcvalue*(3.3/4096);  
            //电压值换算
            sprintf(temp_buff1,"%0.1f V  ",temp);
            Gui_DrawFont_GBK16(40,25,WHITE,BLUE,temp_buff1);        
            
            sprintf(temp_buff,"%05d    ",adcvalue);
            Gui_DrawFont_GBK16(40,45,WHITE,BLUE,temp_buff);                                                 
        }                                                  
    }

三:实物验证如下所示:

四:调试感想:

这次基于 CW32F030C8T6 的 ADC 功能调试整体比较顺利,从搭建工程到在 OLED 上看到电压数值跟随电位器转动线性变化,前后只花了一天多时间,中间也踩了几个小坑,简单记录几点感想。

首先是上手体验。CW32F030 的官方例程和库函数封装得比较友好,初始化 ADC 时只需按结构体逐项配置工作模式、时钟分频、采样时间、参考电压和对齐方式,逻辑清晰、可读性强,几乎不需要直接操作寄存器。对于用惯了 STM32 的人来说迁移成本很低,接口风格很接近。

其次是 ADC 本身的性能。12 位分辨率、最高 1M SPS 的转换速度,对于电位器电压采集这类慢速信号绰绰有余。本次采用单通道单次转换模式,采样时间取 5 个 ADC 时钟周期,参考电压选 VDDA,电压换算直接用 adcvalue x 3.3 / 4096,思路很简单。实测旋转电位器,电压从 0 到 3.3V 跟随得相当线性,与万用表读数基本一致。

调试中印象最深的是输入跟随器的作用。刚开始直接采集电位器分压,数值存在波动和偏低的情况,后来按资料提示开启 ADC 内置跟随器(输入缓冲)后,高阻抗信号源的驱动问题得到解决,采样结果明显稳定。这让我对"信号源阻抗会影响采样精度"有了直观认识,也体会到参考手册中每条注意事项背后都是实际教训。




关键词: CW32F030C8T6     ADC    

共1条 1/1 1 跳转至

回复

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