STM32学习——ADC

一、ADC是什么

        ADCAnalog-Digital Converter)模拟-数字转换器,可以将引脚上连续变换的模拟电压转换为数字变量储存,建立了模拟量与数字量之间的桥梁。

        在我所使用的STM32中,是一个12位逐次逼近型ADC,转换时间最快为1us。

        12位逐次逼近型ADC是什么意思?12位,就是ADC转换的精度,范围,也就是2^12。主次逼近型,这是他的工作原理,ADC是将输入值与一个标准值比较,标准值比输入值大,就减小标准值,比输入值小,就增大标准值。这个过程采用的是二分法,即下一个标准值取当次两者的中间值,而二分法在二进制数中的表现就是移位,所以在用二分法比较大小的时候,就是在二进制数中不断移位的过程,一直进行到两者相等,此时标准值就是输入值,将标准值移入寄存器,以用于后续读取,这就是逐次逼近。ADC转换需要一定时间,这个时间具体参考手册。

二、ADC的结构

        

        ADC最多有18个输入(型号不同数量也会有所不同),其中16个GPIO口的输入是外部的,在32内部有两个输入,一个是温度,一个是标准值,这两个是内部自带的,只需要用过代码调用即可。选好输入通道后,要通过一个多路选择器,选中你所使用的那一路。随后数据进入ADC.

        在ADC内部,有两个组,规则组和注入组。

2.1、规则组

        规则组一次性最多可以输入16个数据,但是转换的结果寄存器中只有一个位置,也就是说,如果单单使用ADC的规则组,一次输入16个数据,那么前15个数据转化的结果都会被第16个数据转化的结果覆盖,最终得到的只有第16个数据转化的结果。所以要使用规则组一次性转化多个数据,需要配合DMA使用,这个暂时没学到。

2.2、注入组

        注入组一次性最多可以输入4个数据,并且注入组的输出寄存器也有四个位置,所以采用注入组比较简单,适合入门。

2.3、工作模式

        1.ADC有单ADC工作和双ADC工作模式。暂时不了解

        2.单次转换和连续转换:

        单次转换,完成一组数据转换后就停止了,想要继续转换需要再次触发。

        连续转换,完成一组数据转换后不会停止,而是继续从头到尾转换数据。

        3.扫描模式和非扫描模式:

        扫描模式:对于一组数据中有不止一个数据的,扫描模式会按设置的扫描数量,转换对应数量的数据

        非扫描模式:无论一组数据中有多少数据,都只转换第一个数据,然后就结束此次转换。

2.4、其他

        START:触发控制,用来开始转换。

        RCC:时钟信号

        开关控制:给ADC上电,用函数控制。

        EOC:标志位,0为未转换完成,1为转换完成。

        模拟看门狗:用来检测数据,如果数据不在事先设置好的范围内,则触发对应的操作。

三、Keil5代码

3.1、常用函数

RCC_ADCCLKConfig									配置ADCCLK分频器,可以对APB2的72MHZ进行2/4/6/8分频输入到ADCCLK

ADC_DeInit												反初始化
ADC_Init													ADC初始化
ADC_StructInit										结构体初始化
ADC_Cmd														ADC上电允许(开关控制)
ADC_DMACmd												开启DMA输出信号
ADC_ITConfig											终端输出控制

ADC_ResetCalibration							复位校准
ADC_GetResetCalibrationStatus			获取复位校准状态
ADC_StartCalibration							开始校准
ADC_GetCalibrationStatus					获取开始校准状态

ADC_SoftwareStartConvCmd					软件触发ADC
ADC_GetSoftwareStartConvStatus		获取软件触发状态(注意,标志位在软件触发开始后就被清零0了)
ADC_GetFlagStatus									获取标志位状态

ADC_DiscModeChannelCountConfig		每隔几个通道间断一次
ADC_DiscModeCmd										是不是启用间断模式
ADC_RegularChannelConfig					ADC规则组通道配置
ADC_ExternalTrigConvCmd						ADC外部触发转换控制
ADC_GetConversionValue						ADC获取转换值
ADC_GetDualModeConversionValue		双ADC模式读取转换结果

ADC_TempSensorVrefintCmd					ADC温度传感器,内部参考电压控制(开启内部两个通道)

ADC_GetFlagStatus									获取标志位状态
ADC_ClearFlag											清除标志位
ADC_GetITStatus										获取中断状态
ADC_ClearITPendingBit							清除中断状态挂起位

3.2初始化函数

void AD_Init(void)
{
	//第一步,初始化时钟RCC--ADC的时钟和GPIO的时钟以及ADCCLK
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//第二步,初始化GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//第三步,选择通道
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	
	//第四步,初始化ADC
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	//第五步,给ADC上电
	ADC_Cmd(ADC1,ENABLE);
	
	//第六步,使用前校准一下
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1) == SET);
}

  • 20
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值