【西门子杯工业嵌入式-6-ADC采样基础】
西门子杯工业嵌入式-6-ADC采样基础
- 一、ADC基础知识
- 二、GD32F470 ADC的硬件特性
- 1.供电设计:
- 2.参考电压:
- 3.输入通道与特性:
- 4.触发方式:
- 5.分辨率与精度:
- 三、抗噪声与滤波处理
- 1.多次采样 + 平均值滤波
- 2.滤波的限制
- 四、ADC采样程序开发(不使用DMA)
- 1.GPIO和ADC初始化:
- 2.ADC功能配置:
- 3.采样逻辑
- 五、应用拓展建议
- 六、结语
链接: B站视频
一、ADC基础知识
ADC(Analog-to-Digital Converter):将模拟信号转换为数字信号的器件。
模拟世界与数字世界的桥梁:
温度、光线、声音、压力等信号是模拟的;
MCU只能处理数字信号,ADC是必不可少的中间环节。
二、GD32F470 ADC的硬件特性
1.供电设计:
使用专门的模拟电源 VDDA(一般为3.3V),地为 VSSA;
要求供电稳定、低噪声,避免数字电路干扰;
可使用滤波电容进行电源净化。
2.参考电压:
参考电压是ADC转换的“尺子”,可使用内部或外部参考源;
精度高的应用需选择稳定高精度参考电压;
不稳定的参考电压会直接影响ADC精度。
3.输入通道与特性:
最多支持16个外部通道;
支持内部温度传感器、电池电压等测量;
输入范围为0~参考电压;
采样阶段输入阻抗较低,转换阶段则较高。
4.触发方式:
软件触发、定时器触发、外部触发;
根据应用需求选择:例如定时采样或响应外部事件。
5.分辨率与精度:
GD32F470支持12位ADC:4096个等级;
假设参考电压3.3V,理论分辨率约为0.8mV;
分辨率越高,采样速度越低,需权衡使用。
三、抗噪声与滤波处理
1.多次采样 + 平均值滤波
有效抑制随机噪声;
平均次数可配置(如2、4、8、16、64等);
适用于缓变信号或噪声较大的环境;
代价是采样速度降低(如8次平均,转换时间增加8倍)。
2.滤波的限制
快速变化信号 → 失真;
周期性噪声 → 可能无效甚至加强噪声;
系统偏差 → 不能通过平均值滤波修正。
四、ADC采样程序开发(不使用DMA)
1.GPIO和ADC初始化:
开启GPIOC和ADC0时钟;
配置 PC0 为模拟输入模式;
设置ADC通道(通道10)采样时间;
使用 定时器触发 启动ADC采样。
void ADC_port_init(void)
{rcu_periph_clock_enable(RCU_GPIOC); // GPIOC时钟使能rcu_periph_clock_enable(RCU_ADC0); // 使能ADC时钟gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0); // 配置PC0为模拟输入adc_clock_config(ADC_ADCCK_PCLK2_DIV8); // adc时钟配置ADC_Init(); // ADC配置adc_software_trigger_enable(ADC0, ADC_ROUTINE_CHANNEL); // 规则采样软件触发}
2.ADC功能配置:
启用连续转换模式;
设置结果右对齐;
配置规则组通道;
校准ADC,提高精度。
void ADC_Init(void)
{adc_deinit(); // 复位ADCadc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE); // 使能连续转换模式adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT); // 数据右对齐 adc_channel_length_config(ADC0, ADC_ROUTINE_CHANNEL, 1); // 通道配置,规则组adc_routine_channel_config(ADC0, 0, ADC_CHANNEL_10, ADC_SAMPLETIME_56); // 对规则组进行配置adc_external_trigger_source_config(ADC0, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_INSERTED_T0_CH3); // ADC 触发配置,利用定时器触发adc_external_trigger_config(ADC0, ADC_ROUTINE_CHANNEL, ENABLE); // 启用触发adc_enable(ADC0); // 使能ADC接口delay_1ms(1); // 等待1msadc_calibration_enable(ADC0); // ADC校准和复位ADC校准
}
3.采样逻辑
在 while(1) 循环中:
清除转换完成标志;
等待转换完成;
读取ADC值并进行电压换算;
打印结果;
滑动变阻器连接3.3V和GND,模拟不同电压输入。
void UsrFunction(void)
{printf("CIMC Sys Init\r\n");while(1){adc_flag_clear(ADC0,ADC_FLAG_EOC); // 清除结束标志while(SET != adc_flag_get(ADC0,ADC_FLAG_EOC)){} // 获取转换结束标志adc_value = ADC_RDATA(ADC0); // 读取ADC数据Vol_Value = adc_value*3.3/4095; // 把数字量转化为工程量printf("Adc_Value=%d Vol_Value%.2f V\r\n",adc_value, Vol_Value); // 结果打印delay_1ms(1000); // 等待10ms}
}
五、应用拓展建议
对测量结果进行更进一步的滤波和补偿处理;
对温度、光照等信号进行数学模型转换;
更高效的方式可使用 DMA方式 读取数据,提高系统效率。
六、结语
本节课我们学习了GD32F470片上ADC的基本原理、配置方法和实际编程使用流程。掌握ADC的使用是嵌入式开发的重要能力,建议同学们多加练习,理解其中的硬件与软件的协同机制。