STM32ADC转换速度(以F103为例)
程序员文章站
2022-05-26 16:20:33
...
系统时间查看
ADC挂在APB2上,对应的时钟为PCLK2,由系统时钟SYSCLK 分频得到,一般不做分频,也就是说ADC模块的时钟等于系统时钟,F103也就是72MHz,如下代码也可获取并查看:
RCC_ClocksTypeDef get_rcc_clock;
RCC_GetClocksFreq(&get_rcc_clock);
ADC转化时间
手册中也有提到ADC的频率不能超过14MHz,也就是说F103需要至少6分配分频(最低只有这个分频系数h合适,再有就是4分频已经超过14MHz)。
转化时间计算公式为:
Tconv = Sampling time + 12.5 cycles
如果ADC配置如下:
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
ADC的工作频率为:72MHz/6 = 12MHz
采样周期为:239.5+12.5=252
总时间为:1000000us/12000000Hz*252=21us
也就是ADC转换一次需要耗时21us。
采集精度
VREF参考电压值3.3V情况下,12位采集精度如果用于采集3.3V电压,那么3300mV/4095≈0.8mV,也就是说理想情况下最多达到0.8mV的识别精度。
提高稳定性
一般也就是硬件和软件两个方面,硬件上可在ADC引脚与GND之间跨接一个1uF的电容,或者选择适合自己采集信号的滤波器。软件方面也是只能选择自己合适的软件滤波器。
示例代码
如下是F103的ADC1通道1的DMA使用(PA1引脚),连续自动转换。
uint16_t ADC_Data;
void ADC_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_Init(GPIOA,&GPIO_InitStructure);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);;//ADC地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Data; //内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //方向(从外设到内存)
DMA_InitStructure.DMA_BufferSize = 1; //传输内容的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址固定
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord ; //外设数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord ; //内存数据单位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; //DMA模式:循环传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High ; //优先级:高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止内存到内存的传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //配置DMA1的1通道
DMA_Cmd(DMA1_Channel1,ENABLE);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //禁止扫描方式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目
ADC_Init(ADC1, &ADC_InitStructure);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟,为PCLK2的6分频,即12MHz
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);//配置ADC1通道1为239.5个采样周期 239.5 + 12.5 = 252
//21微妙
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);//复位校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));//等待校准寄存器复位完成
ADC_StartCalibration(ADC1);//ADC校准
while(ADC_GetCalibrationStatus(ADC1));//等待校准完成
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//由于没有采用外部触发,所以使用软件触发ADC转换
}