本文主要是介绍STM32F103ZET6【标准库函数开发】------06 ADC实验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行。 ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(在 ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降。
STM32 将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。
STM32F103ZET 包含有 3 个 ADC,分别为ADC1,ADC2,ADC3。
对于每个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降
低 ADC 的转换速率。 ADC 的转换时间可以由以下公式计算:
Tcovn=采样时间+12.5 个周期
其中: Tcovn 为总转换时间,采样时间是根据每个通道的 SMP 位的设置来决定的。例如,当 ADCCLK=14Mhz 的时候,并设置 1.5 个周期的采样时间,则得到: Tcovn=1.5+12.5=14 个周期=14*1/14us=1us。
我们介绍一下我们执行规则通道的单次转换,需要用到的 ADC 寄存器。
1.ADC 控制寄存器(ADC_CR1 和 ADC_CR2)
2. ADC 采样事件寄存器(ADC_SMPR1 和 ADC_SMPR2),这两个寄存器用于设置通道 0~17 的采样时间,每个通道占用 3 个位。
3.ADC 规则序列寄存器(ADC_SQR1~3) ,该寄存器总共有 3 个,这几个寄存器的功能都差不多。
4.ADC 规则数据寄存器(ADC_DR)。规则序列中的 AD 转化结果都将被存在这个寄存器里面,而注入通道的转换结果被保存在 ADC_JDRx 里面。
5.ADC 寄存器为 ADC 状态寄存器(ADC_SR),该寄存器保存了 ADC 转换时的各种状态。
一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一
本次将利用 STM32F1 的 ADC1通道 1(PA1) 来采样外部电压值,并通过串口调试助手打印出来。
1)开启PA和ADC1时钟+PA1初始化:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );//使能PA和ADC1通道时钟
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
2)复位ADC1+ 设置分频因子:
ADC_DeInit(ADC1); //复位ADC1
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(在 ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降。
3)ADC初始化ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
4)ADC使能并校准
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 ADC_ResetCalibration(ADC1); //复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //ADC1校准while(ADC_GetCalibrationStatus(ADC1)); //等待ADC1校准结束 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1的软件转换启动功能
5)读取ADC的值
u16 Get_Adc(u8 ch)
{//设置指定ADC的规则组通道,一个序列,采样时间ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}u16 Get_Adc_Average(u8 ch,u8 times) //多次测量求平均值
{u32 temp_val=0;u8 t;for(t=0;t<times;t++){temp_val+=Get_Adc(ch);delay_ms(5);}return temp_val/times;
}
/*******************************************************************************/
ch是ADC通道,可选择如下
#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17))
6)主函数
int main(void){ u16 adcx;float temp;delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200 Adc_Init(); //ADC初始化while(1){adcx=Get_Adc_Average(ADC_Channel_1,10);temp=(float)adcx*(3.3/4096);printf("ADC的值为:%.8f\r\n",temp);//将采集到的ADC的值打印到串口delay_ms(250); }}
![]() | ![]() |
这篇关于STM32F103ZET6【标准库函数开发】------06 ADC实验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!