STM32ADC转换速度(以F103为例)

懵懂的女人 提交于 2020-01-29 04:28:45

系统时间查看

在这里插入图片描述
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转换
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!