CSDN专栏:
- 嵌入式程序开发实战
- 嵌入式双范式AI编程
- 嵌入式开发必掌握
- 嵌入式求职面试技术资料
第33讲:实战——ADC采集、电压采样快速代码生成
一、ADC基础
ADC(模数转换器)是模拟量采集的核心,用于读取传感器模拟信号、电压采样等。
1.1 ADC配置要点
基本参数:
- 分辨率:12位(STM32F103)
- 采样时间:影响精度
- 触发方式:软件触发、定时器触发
- 转换模式:单次、连续、扫描
通道配置:
ADC1通道:
- 通道0:PA0
- 通道1:PA1
- 通道2:PA2
- 通道3:PA3
- 通道4:PA4
- 通道5:PA5
- 通道6:PA6
- 通道7:PA7
二、单通道ADC采集
2.1 基础采集
Prompt:
生成STM32F103 ADC采集代码: - ADC1通道0:PA0 - 功能:采集电压值 - 使用HAL库AI生成:
#include"stm32f1xx_hal.h"ADC_HandleTypeDef hadc1;voidADC1_Init(void){hadc1.Instance=ADC1;hadc1.Init.ScanConvMode=ADC_SCAN_DISABLE;hadc1.Init.ContinuousConvMode=DISABLE;hadc1.Init.ExternalTrigConv=ADC_SOFTWARE_START;hadc1.Init.DataAlign=ADC_DATAALIGN_RIGHT;hadc1.Init.NbrOfConversion=1;HAL_ADC_Init(&hadc1);// 配置通道ADC_ChannelConfTypeDef sConfig={0};sConfig.Channel=ADC_CHANNEL_0;sConfig.Rank=ADC_REGULAR_RANK_1;sConfig.SamplingTime=ADC_SAMPLETIME_55CYCLES_5;HAL_ADC_ConfigChannel(&hadc1,&sConfig);}uint16_tADC_Read(void){HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1,100);uint16_tvalue=HAL_ADC_GetValue(&hadc1);HAL_ADC_Stop(&hadc1);returnvalue;}floatADC_ReadVoltage(void){uint16_traw=ADC_Read();floatvoltage=(float)raw*3.3f/4095.0f;returnvoltage;}intmain(void){HAL_Init();SystemClock_Config();ADC1_Init();UART_Init();while(1){floatvoltage=ADC_ReadVoltage();printf("Voltage: %.2fV\r\n",voltage);HAL_Delay(100);}}2.2 多次采样滤波
平均值滤波:
#defineSAMPLE_COUNT10uint16_tADC_ReadFiltered(void){uint32_tsum=0;for(uint8_ti=0;i<SAMPLE_COUNT;i++){sum+=ADC_Read();}returnsum/SAMPLE_COUNT;}中值滤波:
#defineMEDIAN_COUNT5uint16_tADC_ReadMedian(void){uint16_tvalues[MEDIAN_COUNT];for(uint8_ti=0;i<MEDIAN_COUNT;i++){values[i]=ADC_Read();}// 排序for(uint8_ti=0;i<MEDIAN_COUNT-1;i++){for(uint8_tj=i+1;j<MEDIAN_COUNT;j++){if(values[i]>values[j]){uint16_ttemp=values[i];values[i]=values[j];values[j]=temp;}}}returnvalues[MEDIAN_COUNT/2];}三、多通道ADC采集
3.1 扫描模式
Prompt:
生成STM32F103 多通道ADC采集代码: - ADC1通道0-3:PA0-PA3 - 功能:采集4路电压 - 使用DMA传输 - 使用HAL库AI生成:
#defineADC_CHANNELS4uint16_tadcBuffer[ADC_CHANNELS];voidADC1_Multi_Init(void){hadc1.Instance=ADC1;hadc1.Init.ScanConvMode=ADC_SCAN_ENABLE;// 扫描模式hadc1.Init.ContinuousConvMode=ENABLE;// 连续转换hadc1.Init.ExternalTrigConv=ADC_SOFTWARE_START;hadc1.Init.DataAlign=ADC_DATAALIGN_RIGHT;hadc1.Init.NbrOfConversion=ADC_CHANNELS;HAL_ADC_Init(&hadc1);// 配置各通道ADC_ChannelConfTypeDef sConfig={0};sConfig.Channel=ADC_CHANNEL_0;sConfig.Rank=ADC_REGULAR_RANK_1;sConfig.SamplingTime=ADC_SAMPLETIME_55CYCLES_5;HAL_ADC_ConfigChannel(&hadc1,&sConfig);sConfig.Channel=ADC_CHANNEL_1;sConfig.Rank=ADC_REGULAR_RANK_2;HAL_ADC_ConfigChannel(&hadc1,&sConfig);sConfig.Channel=ADC_CHANNEL_2;sConfig.Rank=ADC_REGULAR_RANK_3;HAL_ADC_ConfigChannel(&hadc1,&sConfig);sConfig.Channel=ADC_CHANNEL_3;sConfig.Rank=ADC_REGULAR_RANK_4;HAL_ADC_ConfigChannel(&hadc1,&sConfig);// 启动DMAHAL_ADC_Start_DMA(&hadc1,(uint32_t*)adcBuffer,ADC_CHANNELS);}floatADC_GetVoltage(uint8_tchannel){if(channel>=ADC_CHANNELS)return0.0f;return(float)adcBuffer[channel]*3.3f/4095.0f;}四、典型应用场景
4.1 电压监测
需求:
监测电池电压,低于阈值报警代码:
#defineBATTERY_LOW_THRESHOLD3.3fvoidBattery_Monitor(void){floatvoltage=ADC_ReadVoltage();printf("Battery: %.2fV\r\n",voltage);if(voltage<BATTERY_LOW_THRESHOLD){printf("Warning: Battery low!\r\n");// 报警}}4.2 温度采集(NTC热敏电阻)
需求:
使用NTC热敏电阻测量温度代码:
// NTC参数#defineNTC_R2510000.0f// 25°C时的电阻(10kΩ)#defineNTC_BETA3950.0f// B值#defineNTC_R_REF10000.0f// 参考电阻(10kΩ)floatNTC_ReadTemperature(void){uint16_traw=ADC_Read();// 计算NTC电阻floatr_ntc=(float)raw*NTC_R_REF/(4095.0f-raw);// 计算温度(B值方程)floattempK=1.0f/(1.0f/298.15f+log(r_ntc/NTC_R25)/NTC_BETA);floattempC=tempK-273.15f;returntempC;}4.3 光照采集
需求:
使用光敏电阻测量光照强度代码:
floatLight_ReadIntensity(void){uint16_traw=ADC_Read();// 转换为光照强度(简化)// 实际需要根据光敏电阻特性曲线计算floatintensity=(float)raw/4095.0f*100.0f;// 0-100%returnintensity;}五、本讲核心要点
6.1 记住这三句话
ADC配置:分辨率、采样时间、触发方式、转换模式
数据滤波:平均值滤波、中值滤波,提高精度
典型应用:电压监测、温度采集、光照采集
6.2 下讲预告
第34讲将深入讲解:实战:PWM输出调速、控灯原型开发
PWM是电机控制、LED调光的基础,如何快速生成PWM代码?下一讲将详细讲解。