STM32初识及运用—ADC

(本博客所有关于32的文章都是基于stm32f103c8t648引脚))

ADC初识——理论讲解

Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字
ADC跟其名字一样完成的是一个模拟量转换为数字量的过程,为什么要把模拟信号转换为数字信号呢,这是因为在显示生活中很多模拟信号太抽象,不好定性分析,如果将其按一定方式转化为容易分析的数值信号,就会变得很容易。

基本原理:

总共有三个ADC控制器,最多能支持23个通道,21个外部和2个内部
Vref+ Vref-分别ADC采集正负参考电源,输入采集的电压不能超过这两个值。
在这里插入图片描述

关于32的讲解在官方的技术手册中讲解的很清楚,我这里对其中一些难理解的词做一些注释,方便大家能够更容易看懂技术手册
名词讲解:
规则通道:顾名思义就是最普通,最常用的通道,平时大多数ADC转化都是利用规则通道实现的。
注入通道:注入通道是相对于规则通道而言的,注入通道可以在规则通道转化时,强行插入转换,当有注入通道需要转换时,规则通道的转换会停止,优先执行注入通道的转换,当注入通道的转换执行完毕后,再回到之前的规则通道进行转换。(相当于中断吧)
转换顺序:规则通道只有一个数据寄存器,当多个通道进行转换时就涉及到一个优先级的问题,通过SQRX寄存器可以对进行设置。
注入通道的顺序寄存器为JSQR(只有当JL=4的时候,注入通道的转换顺序才会按照JSQ1、JSQ2、JSQ3、JSQ4的顺序执行。当JL<4时,注入通道的转换顺序恰恰相反,也就是执行顺序为:JSQ4、JSQ3、JSQ2、JSQ1。)
触发源:ADC转化的触发方式 其一就是通过直接配置寄存器CR2的ADON位,写1的时候开始转换,写入0的时候停止转换。此外还可以通过内部定时或外部IO触发,定时器触发就是利用内部时钟让ADC进行周期性的转换;也可以利用外部IO在使ADC在需要的时候进行转换,都是通过配置CR2寄存器来决定的。
转换时间:转换时间 = 采样时间+12.5个周期
采样时间可以通过寄存器设置为多少个周期(例如1.5个周期),用这个周期时间乘以ADC的一个时钟周期即可
数据寄存器(注意):
数据寄存器分为规则数据寄存器和注入数据寄存器。值得注意的是使用多个通道的时候,会产生多个转换数据,但是数据寄存器就一个,所以在一个通道完成转换后就看立刻将数据取出来,方便下一个数据存储。
对于规则数据寄存器而言:总共有32位,当使用ADC独立模式(只使用一个ADC,可以使用多个通道),数据存放在低16位中,使ADC多模式时高16位存放ADC2的数据。
此外ADC传回来的数据是12位的,而数据寄存器预留的空间为16位的,所以说还需要设置字节对齐模式,是左对齐还是右对齐。(但注入通道的数据寄存器是12位的所以就不用设计)

寄存器配置讲解

(1)ADC状态寄存器(ADC_SR)
此寄存器主要存储ADC采集时的各种状态信息
记录当前时间 ADC转换是否开始或者结束,以及一个模拟看门狗标志位。
(2)ADC控制寄存器1(ADC_CR1)
(3)ADC控制寄存器2(ADC_CR2)
这两个寄存器主要完成ADC的基本配置与模式设定。
其中我们所用到的有
CR1:
工作方式的设定(多ADC还是单ADC)
扫描模式的设定(单通道还是多通道)
CR2:
转换模式的设定(单次转换模式还是连续转换)
触发方式的设定(外部,时钟,软件)
数据对齐方式的设定(左对齐还是右对齐)
使能AD转换器
开启校准

(4)ADC采样时间寄存器1(ADC_SMPR1)
(5)ADC采样时间寄存器2(ADC_SMPR1)
采样时间的设定

(6)ADC注入通道寄存器数据偏移寄存器x(ADC_ JOFRx)

(7)ADC看门狗高/低阈值寄存器(ADC_HTR/ADC_LTR)

(8)ADC规则序列寄存器(ADC_SQRx)
(9)ADC注入序列寄存器(ADC_JSQR)
规则转换的顺序设定
规则转换的数目设定

(10)ADC注入数据寄存器(ADC_JDRx)
(11)ADC规则数据寄存器(ADC_DR)
存储采样返回值

ADC初识——实际运用

注意:为了提高32在进行小项目开发的速度,本篇文章所用的代码都是笔者自己基于32标准库进行二次开发 ,方便能够快速调用单片机外设

关于代码,工程文件会附在文章的末尾。

ADC的初始化

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ADC初始化
//  @param      adcn            选择ADC模块(ADC1,ADC2)
//  @param      ch              选择ADC通道
//  @return     void
//  Sample usage:               adc_init(ADC1, CH0_PA0);
//-------------------------------------------------------------------------------------------------------------------
void HYJ_ADC_Init(ADC_TypeDef* adc,chx_enum ch)
{
	ADC_InitTypeDef ADC_InitStructure; 

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1	, ENABLE );	  //使能ADC1通道时钟
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

	HYJ_GPIO_Init(get_adc_pin(ch),GPIO_Mode_AIN,0);

	ADC_DeInit(adc);  //复位ADC
	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(adc, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   
	ADC_Cmd(adc, ENABLE);	//使能指定的ADC
	
	ADC_ResetCalibration(adc);	//使能复位校准  	 
	while(ADC_GetResetCalibrationStatus(adc));	//等待复位校准结束	
	
	ADC_StartCalibration(adc);	 //开启AD校准
	while(ADC_GetCalibrationStatus(adc));	 //等待校准结束
}


这里为了方便快速调用初始化,入口参数只设置了adc模块和通道,其他设置统一设置为
单通道,单次转换,时钟为12M

ADC的运用和实例

完成初始化后就可以调用

//-------------------------------------------------------------------------------------------------------------------
//  @brief      ADC转换一次
//  @param      adcn            选择ADC模块(ADC1、ADC2)
//  @param      ch              选择ADC通道
//  @return     void
//  Sample usage:               adc_convert(ADC1,CH0_PA0);
//-------------------------------------------------------------------------------------------------------------------
u16	HYJ_ADC_Getdata(ADC_TypeDef* adc,chx_enum	ch)
{
	//设置指定ADC的规则组通道,一个序列,采样时间
	ADC_RegularChannelConfig(adc, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道,采样时间为239.5周期	  			    
	
	ADC_SoftwareStartConvCmd(adc, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
	while(!ADC_GetFlagStatus(adc, ADC_FLAG_EOC ));//等待转换结束

	return ADC_GetConversionValue(adc);	//返回最近一次ADC1规则组的转换结果
}

示例

 int main(void)
 {	
		HYJ_ADC_Init(ADC1, CH0_PA0);
  while(1)		
	{
		HYJ_ADC_Getdata(ADC1,CH0_PA0);
	}
 }

工程文件链接地址:
链接:https://pan.baidu.com/s/1abTvUt44NiH5B_o7IiPa3Q
提取码:cxm6
复制这段内容后打开百度网盘手机App,操作更方便哦–来自百度网盘超级会员V1的分享

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值