ADC采集如何减少误差
同样的程序,不同的测试版,我拿的测得结果误差为0.1内,但是另一块给测试组的结果误差为0.3内。测一下两块板子的参考电压,把精度高的那一个地方的电阻换到精度低的里面,用电阻检测仪器测一下电阻误差。建议买一个参考电压芯片,那个输出的3.3V很准,或者我们直接先用电源输出3.3V给参考电压。
ADC减少误差
软件上:过采样,去极大极小值,采样周期拉长,ADC校准,看时钟是否满足要求
硬件上:提高ADC参考电压的精度(可以直接用参考电压芯片),提高分压电阻的精度(目前无法避免的误差),电压转换芯片的反馈引脚和输出引脚本身也是有误差的,采用误差低的转换芯片。
时钟是否满足要求
把软件的时钟配置放到CUBEMX里面,配置这里都报警告了。所以要改到指定范围内。

ADC有时候准,有时候不准,是ADC的时钟配置的有问题导致。
HSI时钟精度是比较差的百分之1,HSE采用外部晶振,外部晶振误差万分之一。
所以用精度高的晶振。如果不需要精度高,需要低功耗那么选HSI
也可以直接用外部晶振不经过PLL(倍频分频)。
c
static void BOB_ADC_Clock_Config(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLL3.PLL3M = 8;
PeriphClkInitStruct.PLL3.PLL3N = 40;
PeriphClkInitStruct.PLL3.PLL3P = 2;
PeriphClkInitStruct.PLL3.PLL3Q = 2;
PeriphClkInitStruct.PLL3.PLL3R = 2;
PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_2;// 输入时钟范围 4-8 40(HSE)/PLL3M = 5
PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;// VCO频率范围
PeriphClkInitStruct.PLL3.PLL3FRACN = 0.0;// 分数部分
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL3;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)//当前配置的PLL3输出,P分频:100MHz
{
//Error_Handler();
}
}

晶振也分为有源晶振和无源晶振。
无源晶振便宜,需要起振电路,也是比较简单的,大多工程都是无源晶振。
在CUBEMX或者代码里都可以选择ADC的时钟源
CUBEMX上选择:
代码中选择:
c
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_CLKP;//PER_CK
//参考上面代码.把pll设置删掉即可
默认PER_CK就是HSI,如果感觉HSI时钟误差大,也可以把PER_CK设置为HSE
PER_CK(Peripheral Clock)是指外设时钟,它是一个独立的时钟源,用于为某些外设提供时钟信号。默认是采用HSI作为PER_CK
你怎么看你的PER_CK为哪里的时钟源呢?
可直接观察寄存器
如我的芯片STM32H743IIT6,HSI是固定的64MHz

系统时钟和外设时钟配置

延长采集时间
c
//分辨率为:16bit
ADC2_Handle.Init.Resolution = ADC_RESOLUTION_16B;
ADC2_Config.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
/*转换周期为810.5+7.5=818周期,频率为25MHz,则采集转化一次需要32.72us,1s可以执行30562次≈30.5kHz的采样速率*/
采样精度越大,采样周期越长,数据越准
使用高精度分压电阻
不要用百分之1误差的电阻,用千分之一的,而且虽然他说是千分之一,但是国产不要太相信他标的,可能还会超过千分之一呢。
确保参考电压稳定为3.3V

量一量参考电压,想要ADC测得准,参考一定一定要准
电源转换芯片也有误差

算一下误差为2%
如果有预算,直接买一个参考电压芯片,就不用自己设计了
ADC_DMA
STM32H743_ADC的DMA很灵活,不像STM32F103那样(F103是DMA对应指定的ADC通道),ADC3可以使用任意DMA的任意通道。
H743有 DMA1 DMA2 BDMA三个DMA
DMAMUX是STM32微控制器中用于管理DMA请求的一个重要组件。它通过复用多个外设的DMA请求到有限的DMA通道上,提高了DMA资源的使用效率,并提供了灵活的优先级管理和通道映射功能。STM32H7的机制可以让ADC3选择任意的DMA通道,而不是像STM32F103一样选择对应的DMA通道。
参考B友DMA笔记
DMA可能就是不行,我搞不出来,ADC3_DMA存档,然后用PLL3来当ADC的时钟来搞
生成CUBEMX代码