当前位置:首页 > 单片机 > 单片机
[导读] 一、Adc特性1.1 Adc概述Stm32的Adc具有12位的精度,共有16个外部通道和2个内部通道。不同通道的 A/D 转换可以在单一、连续、扫描或者间断模式下进行。它的其他特性还包括支持模拟看门狗和DMA。1.2 Adc初

一、Adc特性1.1 Adc概述

Stm32的Adc具有12位的精度,共有16个外部通道和2个内部通道。不同通道的 A/D 转换可以在单一、连续、扫描或者间断模式下进行。它的其他特性还包括支持模拟看门狗和DMA。

1.2 Adc初始化

和大多数外设一样,Adc在使用前必须初始化时钟源,并从掉电模式唤醒该设备。建议在初始化Adc后立即运行一次校准,以减少准确性错误。

1.3 通道的选择

对于16个可复用的通道,可以将通道分成两种类型的组。常规组和注入组,组序列保存在寄存器ADC_SQRx和ADC_JSQR中。常规组可以包含最多16个通道,注入组最多包含4个通道。

注入组可以理解为常规组的一种中断,当注入组的采集被触发时,常规组的采集会被中断。直到注入组采集完之后,常规组才开始继续采集。

如果只想采集一个通道的数值,只将一个通道写入组里。想采集多个通道的数值,就将多个通道写入组里。当一个组包含多个通道时,要开启扫描模式, adc对组中的每一个通道根据寄存器里的序列进行一次转换。

1.4 触发方式

要触发一次ad转换,可以由内部软件触发,或者外部触发。要不要使用外部触发由控制寄存器里的EXTTRIG位来指定。

内部触发自然是通过写控制寄存器里的相应位来触发。而外部触发则可以有八种触发源可供选择,所以常规组和注入组在控制寄存器里各有3个位来指定哪个外部事件可触ad转换。外部触发源一般是定时器或者是外部中断线事件。

1.5 单一和连续

一次采集被由内部或者外部触发后,可以只采集一次,也可以一直连续采集。如果是一组通道,采集完最后一个通道时,会回到序列中的第一个通道继续采集。

每次采集完成后都会将转换后的数据存在一个寄存器里,并置位采集完成位,根据设定产生中断。

1.6 间断模式

间断模式是将常规和注入组里的序列再切割成更小的组。

比如一个常规组含有9个频道,利用间断模式并设置控制寄存器的位,可以将9个频道分成3组。这样一次触发只会采集3个通道,而不是采集9个通道,连续触发3次才能采集完9个通道。

1.7 采样频率

Adc模块允许对采样频率进行修改,以满足对采样速率的不同需求。考虑到Adc时序里需要一个稳定期,实际使用时还要面临各种DMA请求和中断嵌套,建议不要使用过高的采样频率,并考虑系统运行时负载的临界值。

可以通过修改ADC_SMPR1 和 ADC_SMPR2 寄存器中的 SMP[2:0]来设置采样频率。

1.8 模拟看门狗

设置相应的寄存器可以为Adc指定上下阀值,当采集到电压值超过阀值时,系统会产生中断。

1.9 DMA

当在扫描模式和连续模式下,显然每次都将保存采集值的寄存器数据读出来处理是来不及的。设置Adc的DMA使能,可以让每次转换过的数值都经DMA传到指定的内存空间里。

1.10 字节序

对于转换后的数据,可以设置左对齐或是右对齐,以支持不同的处理和传输的需要。

1.11 双adc模式

具有两个adc的设备可以使用的模式。在这种模式下,通常adc1做主设备,adc2做从设备。从设备的触发有主设备来发起。

主设备的常规组/注入组的触发成为从设备触发的条件,而主设备可以被设置为等待从设备采集一段时间后才开始采集,双adc模式下有许多种方式可以支持不同的主从同步。

二、Adc的库函数

HAL里的Adc函数相较stmlib里的结构更加简单,它的私有成员就不做叙述了,因为如何实现HAL的结构性代码并不是我们关心的问题。这里只描述一下Adc的输出函数。

2.1 初始化函数

同GPIO的初始化一样,Adc的初始化使用几个结构体来进行。不同的是由于Adc较之GPIO更加复杂,所以对Adc属性的描述分成了几个不同的结构体。

ADC_InitTypeDef结构体原型

typedef struct

{

uint32_t DataAlign;

uint32_t ScanConvMode;

uint32_t ContinuousConvMode;

uint32_t NbrOfConversion;

uint32_t DiscontinuousConvMode;

uint32_t NbrOfDiscConversion;

uint32_t ExternalTrigConv;

}ADC_InitTypeDef;

从上到下依次描述:

字节序、是否使用扫描模式、单一/连续模式、常规组序列、是否使用间断模式、间断模式中一个组的通道数量、外部触发的方式。

HAL_ADC_init函数的参数是一个指向ADC_HandleTypeDef结构体的指针,这个结构体的第一个元素,就是一个指向ADC_InitTypeDef结构体的指针。所以初始化ADC前,要先定义一个ADC_InitTypeDef结构体,赋值给每个成员变量。然后把它的地址写入一个ADC_HandleTypeDef结构体的成员。

ADC_InitTypeDef结构体原型

/**

* @brief ADC handle Structure definition

*/

typedef struct

{

ADC_TypeDef *Instance; /*!< Register base address */


ADC_InitTypeDef Init; /*!< ADC required parameters */


__IO uint32_t NbrOfConversionRank ; /*!< ADC conversion rank counter */


DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */


HAL_LockTypeDef Lock; /*!< ADC locking object */


__IO HAL_ADC_StateTypeDef State; /*!< ADC communication state */


__IO uint32_t ErrorCode; /*!< ADC Error code */

}ADC_HandleTypeDef;


可以看到它除了包含一个指向ADC_InitTypeDef的指针之外,还包含指向寄存器的指针、互斥锁、一个描述状态的变量、一个保存错误代码的变量、一个指向DMA结构体的指针。所有与对Adc进行操作的函数都使用这个结构体的指针作为参数。

HAL有一个自己的锁,这样即使程序员在多个线程里没有使用信号量来对外设进行读写控制,HAL层也会独立保证对外设进行特殊操作时的原子性。

ADC_InitTypeDef结构体只描述了一部分Adc的属性。所以有ADC_ChannelConfTypeDef结构体来描述单个通道在组序列里的排序位置及它的工作速率,ADC_AnalogWDFConfTypeDef结构体来描述一个模拟看门狗的阀值和中断模式。而HAL_ADC_ConfigChannel和HAL_ADC_AnalogWDGconfig()函数用来处理这两个结构体。

在初始化Adc时钟和使能设备后,至少需要设置四个结构体,调用三个函数,才能将Adc初始化完毕。

2.2 Adc的操作

开始与结束

HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);

HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);


HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);

HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);


HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);

HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);


HAL_ADC_START()、HAL_ADC_START_DMA()、HAL_ADC_START_IT()三个函数分别表示开始一次采集(直接软触发或者等待外部触发),后两个函数表示数据用DMA传输和使能中断。中断处理函数是HAL_ADC_IRQHander()。


callback函数


void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc);

void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc);

void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc);


Adc中断、DMA传输、看门狗超过阀值、发生Adc错误,这些函数返回前都调用了Callback函数,用来在非中断模式下处理Adc数据,如果想进行一些操作可以直接修改Callback函数。


取转换后的数值


/* ADC retrieve conversion value intended to be used with polling or interruption */

uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);


HAL_ADC_GetValue()用来区寄存器值。


等待函数


HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);

HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout);

1

2

在非中断和DMA模式下,采集数据需要等待一次采集的完成,或者某些事件的发生。HAL_ADC_PollForConversion函数和HAL_ADC_PollForEvent函数用来等待这两者。


三、例子


只用一个通道采集的初始化例子

static void ADC_Config(void)

{

ADC_ChannelConfTypeDef sConfig;

ADC_AnalogWDGConfTypeDef AnalogWDGConfig;


/* Configuration of ADCx init structure: ADC parameters and regular group */

AdcHandle.Instance = ADCx;


AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;

AdcHandle.Init.ScanConvMode = ADC_SCAN_DISABLE;

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

特朗普集团近日取消了其新推出的T1智能手机“将在美国制造”的宣传标语,此举源于外界对这款手机能否以当前定价在美国本土生产的质疑。

关键字: 特朗普 苹果 AI

美国总统特朗普在公开场合表示,他已要求苹果公司CEO蒂姆·库克停止在印度建厂,矛头直指该公司生产多元化的计划。

关键字: 特朗普 苹果 AI

4月10日消息,据媒体报道,美国总统特朗普宣布,美国对部分贸易伙伴暂停90天执行新关税政策,同时对中国的关税提高到125%,该消息公布后苹果股价飙升了15%。这次反弹使苹果市值增加了4000多亿美元,目前苹果市值接近3万...

关键字: 特朗普 AI 人工智能 特斯拉

3月25日消息,据报道,当地时间3月20日,美国总统特朗普在社交媒体平台“真实社交”上发文写道:“那些被抓到破坏特斯拉的人,将有很大可能被判入狱长达20年,这包括资助(破坏特斯拉汽车)者,我们正在寻找你。”

关键字: 特朗普 AI 人工智能 特斯拉

1月22日消息,刚刚,新任美国总统特朗普放出重磅消息,将全力支持美国AI发展。

关键字: 特朗普 AI 人工智能

特朗普先生有两件事一定会载入史册,一个是筑墙,一个是挖坑。在美墨边境筑墙的口号确保边境安全,降低因非法移民引起的犯罪率过高问题;在中美科技产业之间挖坑的口号也是安全,美国企业不得使用对美国国家安全构成威胁的电信设备,总统...

关键字: 特朗普 孤立主义 科技产业

据路透社1月17日消息显示,知情人士透露,特朗普已通知英特尔、铠侠在内的几家华为供应商,将要撤销其对华为的出货的部分许可证,同时将拒绝其他数十个向华为供货的申请。据透露,共有4家公司的8份许可被撤销。另外,相关公司收到撤...

关键字: 华为 芯片 特朗普

曾在2018年时被美国总统特朗普称作“世界第八奇迹”的富士康集团在美国威斯康星州投资建设的LCD显示屏工厂项目,如今却因为富士康将项目大幅缩水并拒绝签订新的合同而陷入了僵局。这也导致富士康无法从当地政府那里获得约40亿美...

关键字: 特朗普 富士康

今年5月,因自己发布的推文被贴上“无确凿依据”标签而与推特发生激烈争执后,美国总统特朗普签署了一项行政令,下令要求重审《通信规范法》第230条。

关键字: 谷歌 facebook 特朗普

众所周知,寄往白宫的所有邮件在到达白宫之前都会在他地进行分类和筛选。9月19日,根据美国相关执法官员的通报,本周早些时候,执法人员截获了一个寄给特朗普总统的包裹,该包裹内包含蓖麻毒蛋白。

关键字: 美国 白宫 特朗普
关闭