历史上的今天
返回首页

历史上的今天

今天是:2025年03月07日(星期五)

正在发生

2019年03月07日 | stm32F4XX之AD采样 HAL库

2019-03-07 来源:eefocus

ADC 简介

          12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道,可测量来自 16 个外部 源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续 采样模式下进行。ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。


ADC 具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限


ADC 主要特性

● 可配置 12 位、10 位、8 位或 6 位分辨率

● 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断

● 单次和连续转换模式

● 用于自动将通道 0 转换为通道“n”的扫描模式

● 数据对齐以保持内置数据一致性

● 可独立设置各通道采样时间

● 外部触发器选项,可为规则转换和注入转换配置极性

● 不连续采样模式

● 双重/三重模式(具有 2 个或更多 ADC 的器件提供)

● 双重/三重 ADC 模式下可配置的 DMA 数据存储

● 双重/三重交替模式下可配置的转换间延迟

● ADC 转换类型(参见数据手册)

● ADC 电源要求:全速运行时为 2.4 V 到 3.6 V,慢速运行时为 1.8 V

● ADC 输入范围:VREF<=VIN <= VREF+

● 规则通道转换期间可产生 DMA 请求


ADC初始化

adc初始化首先我们要做的就是时钟的使能控制,GPIO的配置,如果要用到DMA的话也要使能DMA的时钟,这也是基本所有外设配置都需要的。


ADC通道的选择

有 16 条复用通道。可以将转换分为两组:规则转换和注入转换。每个组包含一个转换序列, 该序列可按任意顺序在任意通道上完成。 一个规则转换组最多由 16 个转换构成。必须在 ADC_SQRx 寄存器中选择转换序列的规 则通道及其顺序。规则转换组中的转换总数必须写入 ADC_SQR1 寄存器中的 L[3:0] 位 一个注入转换组最多由 4 个转换构成。必须在 ADC_JSQR 寄存器中选择转换序列的注入 通道及其顺序。注入转换组中的转换总数必须写入 ADC_JSQR 寄存器中的 L[1:0] 位STM32的ADC可以对一组指定的通道,按照指定的顺序,逐个转换这组通道,转换结束后,再从头循环;这指定的通道组就称为规则组。但是实际应用中,有可能需要临时中断规则组的转换,对某些通道进行转换,这些需要中断规则组而进行转换的通道组,就称为注入组。一个不太恰当的比喻是:规则通道组的转换好比是程序的正常执行,而注入通道组的转换则好比是程序正常执行之外的一个中断处理程序。 


触发方式

        要触发一次ad转换,可以由内部软件触发,也可以通过外部事件(例如,定时器捕获、EXTI 中断线)触发转换。。要不要使用外部触发由控制寄存器里的EXTTRIG位来指定。


单一和连续

       在单次转换模式下,ADC 执行一次转换。CONT 位为 0 时,可通过以下方式启动此模式。在连续转换模式下,ADC 结束一个转换后立即启动一个新的转换。CONT 位为 1 时,可通过外部触发或将 ADC_CR2 寄存器中的 SWSTRT 位置 1 来启动此模式


间断模式

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


采样频率

        Adc模块允许对采样频率进行修改,建议不要使用过高的采样频率,并考虑系统运行时负载的临界值。ADC 会在数个 ADCCLK 周期内对输入电压进行采样,可使用 ADC_SMPR1 和 ADC_SMPR2 寄存器中的 SMP[2:0] 位修改周期数。每个通道均可以使用不同的采样时间进行采样


模拟看门狗

       如果 ADC 转换的模拟电压低于阈值下限或高于阈值上限,则 AWD 模拟看门狗状态位会置 1。这些阈值在 ADC_HTR 和 ADC_LTR 16 位寄存器的 12 个最低有效位中进行编程。可以 使用 ADC_CR1 寄存器中的 AWDIE 位使能中断


DMA通道

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


下面附上相关的驱动代码

init初始化


ADC_HandleTypeDef hadcx;

DMA_HandleTypeDef hdma_adcx;

/**

  * 函数功能: AD转换初始化

  * 输入参数: 无

  * 返 回 值: 无

  * 说    明:无

  */

void MX_ADCx_Init(void)

{

  ADC_ChannelConfTypeDef sConfig;

 

  // ADC功能配置

  hadcx.Instance = ADC1;

  hadcx.Init.ClockPrescaler=ADC_CLOCKPRESCALER_PCLK_DIV4;   //4分频

  hadcx.Init.Resolution=ADC_RESOLUTION_12B;    //12位模式

  hadcx.Init.ScanConvMode = DISABLE;                  //关闭扫描模式

  hadcx.Init.EOCSelection=DISABLE;                      //关闭EOC中断

  hadcx.Init.ContinuousConvMode = ENABLE;           //使能连续扫描

  hadcx.Init.DiscontinuousConvMode=DISABLE;       //禁止不连续采样模式

  hadcx.Init.NbrOfDiscConversion=0;               //不连续采样通道数为0

  hadcx.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;

  hadcx.Init.DMAContinuousRequests=ENABLE;             //打开DMA请求

  hadcx.Init.DataAlign = ADC_DATAALIGN_RIGHT;

  hadcx.Init.NbrOfConversion = 1;

  HAL_ADC_Init(&hadcx);

 

  // 配置采样通道

  sConfig.Channel = ADC_CHANNEL_4;

  sConfig.Rank = 1;

  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;

  HAL_ADC_ConfigChannel(&hadcx, &sConfig);

 

/* DMA外设初始化配置 */  

   hdma_adcx.Instance = DMA1_Stream0;

   hdma_adcx.Init.Channel  =DMA_CHANNEL_0; //通道0 

   hdma_adcx.Init.Direction = DMA_PERIPH_TO_MEMORY;

   hdma_adcx.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_adcx.Init.MemInc = DMA_MINC_ENABLE;

   hdma_adcx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

   hdma_adcx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

   hdma_adcx.Init.Mode = DMA_CIRCULAR;//循环模式

   hdma_adcx.Init.Priority=DMA_PRIORITY_MEDIUM;//DMA传输方式有关数据格式几次传输

   hdma_adcx.Init.FIFOMode=DMA_FIFOMODE_DISABLE;

   hdma_adcx.Init.Priority = DMA_PRIORITY_HIGH;

   HAL_DMA_Init(&hdma_adcx);

   /* 连接DMA */

   __HAL_LINKDMA(hadcx,DMA_Handle,hdma_adcx);

 

}

时钟初始化


/**

  * 函数功能: ADC外设初始化配置

  * 输入参数: hadc:AD外设句柄类型指针

  * 返 回 值: 无

  * 说    明: 该函数被HAL库内部调用

  */

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)

{

  GPIO_InitTypeDef GPIO_InitStruct;

    /* 外设时钟使能 */

    __HAL_RCC_ADC1_CLK_ENABLE();

    

    /* AD转换通道引脚时钟使能 */

    __HAL_RCC_GPIOA_CLK_ENABLE();

    

    /* DMA时钟使能 */

    __HAL_RCC_DMA2_CLK_ENABLE();

      

    /* AD转换通道引脚初始化 */

    GPIO_InitStruct.Pin = GPIO_PIN_0;

    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

获取AD值


void Get_Adc_Average(ADC_HandleTypeDef *hadc,char channel,unsigned int SamplingTime)

{

ADC_ChannelConfTypeDef sConfig;

int data = 0;

// 配置采样通道

sConfig.Channel = channel;

sConfig.Rank = 1;

sConfig.SamplingTime = SamplingTime;

HAL_ADC_ConfigChannel(&hadc, &sConfig)//配置采样通道和采样频率

    HAL_ADC_Start_DMA(hadc,&data,1);

HAL_DMA_PollForTransfer(&hdma_adcx,HAL_DMA_FULL_TRANSFER,0XFFFFFFFF);

HAL_ADC_Stop_DMA(hadc);

}

 


推荐阅读

史海拾趣

CLANDELL公司的发展小趣事

随着国内市场的饱和,CLANDELL公司开始寻求国际化发展。公司通过市场调研和合作伙伴的建立,逐步拓展海外市场。在国际化的过程中,CLANDELL公司不仅提升了自身的品牌影响力,也学习到了国际先进的管理经验和市场策略,为公司的长远发展奠定了坚实基础。

Extech公司的发展小趣事

为了响应国家振兴制造业的号召,培养优秀的数字化设计与制造技术人才,Extech公司在近年来启动了“PLM China”计划。该计划面向全国高校提供价值1000万人民币的软件支持,旨在与教育行业携手合作,共同提升中国制造业的整体设计研发水平。通过这一计划的实施,Extech公司不仅展现了自己的社会责任感,也为中国制造业的发展做出了积极的贡献。

以上五个故事分别从不同角度展现了Extech公司在电子行业中的发展历程和成就。通过持续的创新和努力,Extech公司已经成为了一家在制造业信息化领域具有重要影响力的企业。

Blue Creation公司的发展小趣事

Blue Creation公司在电子行业的起步并不顺利,一度面临资金短缺和技术瓶颈。然而,公司创始人凭借对技术的深厚理解,带领团队开发出一款革命性的电源管理技术。这项技术不仅大幅提高了电子设备的续航能力,还降低了能耗,迅速赢得了市场的青睐。随着技术的不断迭代和完善,Blue Creation逐渐在电子行业崭露头角。

兵字(BingZi)公司的发展小趣事

随着市场的不断变化和客户需求的日益多样化,兵字公司意识到,要想在市场中保持领先地位,就必须不断进行技术创新。于是,公司投入大量研发资源,成功研发出了小型精密互感器。这一创新产品不仅填补了市场空白,还为公司带来了可观的收益。同时,兵字公司也凭借这一技术突破,进一步巩固了在电子元器件领域的领先地位。

联捷(Elinker)公司的发展小趣事

随着国内市场的逐渐饱和,联捷(Elinker)开始寻求海外市场的拓展。公司积极参加国际电子展会,与国外的电子企业建立了广泛的合作关系。同时,公司还通过引进国外先进的技术和管理经验,不断提升自身的竞争力。在国际市场的竞争中,联捷(Elinker)凭借其优质的产品和服务,赢得了越来越多客户的信任和认可。

风华(FH)公司的发展小趣事

福斯特半导体(这里假定为福斯特应用材料股份有限公司的半导体业务部门,因直接名为“福斯特半导体”的公司可能专注于不同领域)的母公司——杭州福斯特应用材料股份有限公司,最初并非涉足半导体行业。2003年,公司创始人林建华在纺织业取得成功后,决定跨界进军光伏胶膜行业。当时,国内光伏组件厂商所需的光伏胶膜主要依赖进口,市场被几家国际巨头垄断。林建华凭借在材料领域的深厚积累和技术优势,成功研制出EVA胶膜产品,并迅速占领市场。至2008年,福斯特已成为全球前三的EVA胶膜供应商,为光伏产业的发展奠定了坚实基础。这一跨界创新不仅推动了光伏胶膜行业的国产化进程,也为福斯特半导体后续在电子行业的拓展提供了宝贵的经验和资源。

问答坊 | AI 解惑

【藏书阁】模拟电子技术基础实验与课程设计

目录: 第一编 模拟电子技术基础实验基本知识 第一章 概述 第二章 实验程序 第三章 模拟电子技术基础实验常用仪器使用练习 第四章 万用表对常用电子元器件的检测 第五章 集成运算放大器的主要参数测试 第六章 电路故障分析、排除及抗干扰 ...…

查看全部问答>

有没有用过几元的AD芯片?

现在发现很多AD芯片价格都降不下来, 有没有用过几元的,请推荐一下…

查看全部问答>

请问各位wince的资源管理器有没有右键菜单?

在win32下,资源管理器里右击一个文件会弹出一个菜单。那在wince下有这个功能吗? 我试了半天也没搞出来。强烈怀疑没这个功能。 …

查看全部问答>

基于arm的大楼灯光控制器需要的硬件设备.

这是我的毕业设计题目,还不知道怎么做,希望得到帮助! …

查看全部问答>

关于NDIS显示数据包内容的问题

如果我要在NDIS中间驱动层拦截网络数据包,那么,如果要把NDIS中间驱动层中截获的一个NDIS封包全部输出来,包括头还有数据部分,以二进制的形式全部显示出来,应如何实现呢?…

查看全部问答>

To 一个简单的提问

我现在想开发一款USB驱动程序,我目前 的操作系统是Win2003,请问使用win2003DDK开发的驱动程序,能够在WIN2000及XP上使用吗?DDK有什么要求吗?谢谢,见笑了.…

查看全部问答>

遇到这事,你怎么办?

接到了二个offer,一个是作电子词典嵌入式开发,一个是作linux计费开发,现在不知去哪个好? 我以前的工作是在linux下的开发,但我有很想往嵌入式那边尝试,但现在不知道作电子词典开发有没有前途?因为那家公司的电子词典的操作系统不是linux,也不 ...…

查看全部问答>

信号切换问题

A,B两路信号选择一路通过,当然这是两路都有信号的情况,如果只有一路有就直接让它通过就是了.现在我用的是ls123触发器来判断哪路有信号但是试验板做出来老是有问题不知道还有没有别的什么思路不用ls123触发器.谢谢希望高手指点…

查看全部问答>

DS1302有关问题求指教

在定入单字节中为什么是for(i=0;i>1;         sck=1;         }这个时候的SDA是怎么样放的,为什么是与上0X01呢?而读出单字节的for(i=0;i>1;               &nbs ...…

查看全部问答>

一些下载的资料拿来分享

一些下载的资料拿来分享…

查看全部问答>