0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【有那么点详细的CW32学习笔记】ADC“自动模式”

CW32生态社区 来源:CW32生态社区 作者:CW32生态社区 2024-03-04 18:09 次阅读

上个章节介绍了ADC的基本框架和用法,本章节会较为全面地讲解如何灵活地使用ADC功能。

通常来说,外设执行的各种命令都是由CPU发出的,比如我们需要进行AD转换,就通过某个寄存器标志位启动ADC,随后用判断函数去检测执行情况,亦或是开启中断功能,转换完成之后会提示CPU,再由CPU判断接下来该做什么。

这当然没问题,不过有些时候,我们需要实现一些循环重复的功能,比如在做傅里叶分析的时候,需要按照固定间隔采集一定数量的数据,比如采样率1000Hz,共采集1024个数据。为了实现这个目标,当然可以使用软件定时实现,也可以使用定时器外设,在中断服务函数中直接进行AD转换来定时获取数据,但数据很多,若是还要进行快速傅里叶变换,CPU会在定时器中断中花费很多时间来采集数据,留给计算的时间就少了很多。有一种方案可以完美解决这类问题,不仅可以保证数据采集的精确性,还几乎不需要CPU参与,那就是使用定时器触发ADC转换,而AD转换完成之后会由DMA进行数据搬运,若CPU需要使用这批数据,直接访问数据进行读取即可 。具体的逻辑关系如下图所示。

图片

这种组合涉及到DMA、ADC、定时器的使用,文章将详细介绍上图的联动过程。

  • 按照顺序,首先是定时器触发AD转换。

前文也提到过,一般来讲可以用软件开关去启动AD转换,此处并没有用到这一功能,而是使用定时器触发,这是一种硬件触发方式,且触发源不属于ADC外设本身,故而也是一种外部触发方式。在ADC外设的配置项中,可以设置AD转换的开启是否由外部信号触发,只要ADC能正常使用,再配置好外部触发源,我们就能用外部硬件信号触发AD采集了。

注意!在实际使用中,外部触发源不一定非得是定时器,它也可以是某个片外模块提供的事件电平(完成事件会改变指定IO的电平,就和中断一样),最简单的就是按键触发的IO中断。

  • 接下来是第二个部分,DMA功能的配置。

DMA,全名叫直接存储器访问,这个外设可以像CPU一样访问单片机内部的各个存储区(包括RAM和外设寄存器),但它只能做一件事情,就是数据搬运。通俗来说,数据存放在0-9共10个格子里面,DMA可以把这10个数据搬运到其他地方(并不会改变原本的值,效果类似赋值语句),而其他地方可以是同一个地方(将10个数据按顺序搬运10次,最终一层层覆盖到同一个地址),也可以是不同地方(将10个数据搬运10次并最终存放在10个不同地址的存储空间)。

总体上来讲DMA只做搬运这一个功能,除了搬运转换完成的AD数据,他还能用于各种数据接口(比如UART、SPI等),或是其他需要大量赋值的场合。

注意!****DMA并不能完全代替CPU进行数据转移,因为DMA*不像* CPU那样拥有全部存储区域的访问权限。

  • 最后是定时器的配置,这一部分没什么变化,就是选择一个可以用来触发AD采集的定时器,按需求配置即可。不过需要注意的是,记得把溢出中断打开,这个是AD转换的启动开关

介绍完了每一步需要做的事情,下面说说代码应该怎么写。我会贴出主要代码,对于一些变量我会做说明但不做代码展示(变量什么的自己随便定义一个就行了呀!)

图片

这段就是正常配置一个定时器,本案例中选择的是通用定时器2,根据手册,它可以触发AD采集。

图片

除最后一行,其余代码与上一章节的初始化过程没太大差别,只需把DMA功能开启即可。这里补充一下其他配置项的说明:

  1. 时钟频率和采样时钟周期,如上一章说到的,采样时间当然是越长越好,其中的时钟频率就是ADC外设从内部时钟电路获得的时钟信号,频率越高,ADC速度越快,这个时钟速度一定程度上决定了一个ADC的最大采样速率(1秒内完成的转换次数)。
  2. 右对齐设置。AD转换的结果是存放在一个寄存器里面的,它本质上是个二进制数,右对齐就是将转换结果的第0位放到最右边,高位不为1的补0,若仍不清楚,可自行百度。
  3. 转换结果累加。为满足一些需求,ADC结果可能需要进行数据处理来减小误差,求加权平均值是一种很常用的办法,该功能开启之后,每次转换的结果都会直接累加,方便开发者取出后直接求平均值(所以实际上不要这个功能也可以)。
  4. 我们使用的是定时器触发采样,所以只需要使用单次采集模式就行了,ADC会在每次转换完成之后停止并等待下一次采集的启动信号(定时器溢出中断)。

总的来说,一定记住要把外部触发打开并绑定定时器2,随后只要定时器2的标志位被置位一次,ADC就会启动一次。

相对来说比较麻烦的是DMA的配置,要配置一个DMA,首先需要确定数据搬运的起点和终点 ,我们搬运的起点只有一个,就是ADC转换结果寄存器,搬运的终点是一个1024大小的数组,其中起点被称为源地址,终点被称为目标地址,且这两个地址都可以设置成自增模式(完成一次搬运之后,地址自动+1)。

图片

关于DMA的初始化,DMA通常会有不止一个通道,每个通道都能独立进行数据搬运,初始化函数需要开启DMA的时钟总线,打开要用的DMA通道的中断。

图片

关于DMA的启动和配置:

传输模式 :DMA帮助CPU进行数据搬运,这难免会出现DMA和CPU传输冲突的情况,非锁定传输会在DMA搬运数据的间隔内预留时间间隙,必要时候CPU会抢占对外设的访问权限,届时CPU可进行数据传输,DMA只能等待CPU放弃对该外设的使用权限后才能继续自己的数据传输。相对应的,还有锁定传输,具体的功能在用户手册DMA章节有详细介绍。

传输位宽 :根据需要搬运的数据长度进行选择即可。

触发方式和触发源 :由于我们需要的是在AD转换完成之后立刻进行数据搬运,所以DMA的触发方式选择为硬件触发,触发源应该设置为ADC转化为完成,这会让DMA在每次ADC转换完成之后都进行一次数据搬运,且不论ADC处于什么模式。

源地址和目标地址 :源地址设置为ADC数据寄存器,具体的地址有两种办法来获取,一种是用图中的办法,对寄存器取地址,另一种办法是直接查用户手册,找到ADC数据寄存器的基地址和偏移量计算得到地址(这种办法最终填进去的是一个hex数)。目标地址也是直接取地址数组即可。

地址自增 :我们不希望源地址有变动,故源地址设置成不自增;目标地址是一个数组,所以每搬运一次数据都要让目标地址自增一个元素,这样下一次搬运的时候,数据就会被正确写入下一个格子。

传输次数 :需求是采集1024个数据,那传输次数自然是1024次。

全部配置完后完成DMA的功能初始化,随后只需要启动ADC、定时器、DMA功能即可,图中代码做了一个开关启动,方便随时关闭。关闭的时候清零定时器计数器是为了在下次启动的时候让定时采集依然准确。

准备工作基本完成,接下来还剩一些小细节需要处理,我们打开了DMA和定时器的中断功能,他们会在完成搬运之后进入中断服务函数,至少得写个清除标志位的语句,除此之外还要加一些小功能。

图片

图片

定时器的中断服务函数只需要清除标志位即可,DMA的中断函数除了清除标志位,还需要将采样功能关掉(至少得把定时器关了)。如果使用的不是定时器触发,而是ADC的连续采样模式,需要在这里手动关闭ADC,不然即使DMA完成了搬运,ADC还会继续进行AD转换,由于DMA搬运已经完成了,自增的地址也不会自己变回去,之后就会出现“意想不到的”DMA错误搬运,但本案例中使用的是单次采集模式,ADC只在启动之后采集一次,所以不必担心ADC会连续采样导致程序异常的问题。

现在快速编写一个按键检测函数并调用刚刚写好的启动代码,其中的key_down变量会在按键中断服务函数中被置位。

图片图片

再在main函数中循环调用这个按键检测函数,按键按下抬起后就会自动采集ADC数据,这里我用vofa+上位机显示一下采集的数据。

图片

我这里采集的是单片机上定时器1输出的50Hz方波,占空比为50%,周期为20ms,效果还不错。

图片

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ADC
    ADC
    +关注

    关注

    0

    文章

    100

    浏览量

    16845
  • CW32
    +关注

    关注

    1

    文章

    154

    浏览量

    472
收藏 人收藏

    评论

    相关推荐

    那么点详细CW32学习笔记】单片机启动\库函数构成

    此篇文章是CW32F030C8T6的参考资料,很详细,适合初学者。
    的头像 发表于 08-10 11:13 925次阅读
    【<b class='flag-5'>有</b><b class='flag-5'>那么点</b><b class='flag-5'>详细</b>的<b class='flag-5'>CW32</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>】单片机启动\库函数构成

    那么点详细CW32学习笔记】通用定时器——输出比较

    个要点步骤: 有时钟源输入、计数器工作、一个可以比较的值(自动重装载值) 。其工作流程是这样的:计数器会随着时钟源对时钟源提供的脉冲进行计数,计数值不断上涨(或下降),如果计数值和自动重装载值一样,
    的头像 发表于 12-28 11:24 1155次阅读
    【<b class='flag-5'>有</b><b class='flag-5'>那么点</b><b class='flag-5'>详细</b>的<b class='flag-5'>CW32</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>】通用定时器——输出比较

    那么点详细CW32学习笔记】看手册配置时钟树

    本章针对CW32F030C8T6的时钟树进行详细解析,续第一章启动文件的相关讲解。
    的头像 发表于 08-17 14:54 816次阅读
    【<b class='flag-5'>有</b><b class='flag-5'>那么点</b><b class='flag-5'>详细</b>的<b class='flag-5'>CW32</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>】看手册配置时钟树

    那么点详细CW32学习笔记】模数转换器

    来说,想要判断大小就需要有对比,因此该数字指示的电压大小实际上是一个比较的结果。 ADC将需要测量的电压信号Ut与已知电压的信号U作比较,并最终输出一个数字表示Ut相当于多少比例的U。 接下来就可以看看CW32ADC外设结构框
    的头像 发表于 02-29 09:41 581次阅读
    【<b class='flag-5'>有</b><b class='flag-5'>那么点</b><b class='flag-5'>详细</b>的<b class='flag-5'>CW32</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>】模数转换器

    【应用笔记CW32 自举程序中使用的 ISP 协议

    提供的 ISP 模式,通过 UART 串口方便地实现对 CW32 微控制器片上 FLASH主存储器的擦除和烧写。本应用笔记将介绍如何进入 CW32 微控制器 ISP
    发表于 06-06 13:26

    应用笔记(二)| 武汉芯源CW32自举程序中使用的ISP协议

    CW32微控制器片上FLASH主存储器的擦除和烧写。本应用笔记将介绍如何进入CW32微控制器ISP模式,以及所使用的ISP协议,并详细介绍
    的头像 发表于 07-11 16:08 1247次阅读
    应用<b class='flag-5'>笔记</b>(二)| 武汉芯源<b class='flag-5'>CW32</b>自举程序中使用的ISP协议

    CW32 低功耗模式的特性介绍

    CW32系列芯片支持3种工作模式,运行模式、休眠模式以及深度休眠模式,本文以CW32L083为例
    的头像 发表于 12-30 10:53 886次阅读
    <b class='flag-5'>CW32</b> 低功耗<b class='flag-5'>模式</b>的特性介绍

    cw32和gd32的区别

    cw32和gd32的区别 CW32和GD32是两种不同的芯片系列,分别由WCH和GigaDevice公司推出,两者很多不同之处,下面我们来详细介绍。 首先从
    的头像 发表于 08-16 11:15 1578次阅读

    浅谈CW32系列模数转换器(ADC

    CW32系列模数转换器(ADC
    的头像 发表于 10-25 15:43 875次阅读
    浅谈<b class='flag-5'>CW32</b>系列模数转换器(<b class='flag-5'>ADC</b>)

    CW32的SPI单工模式主从通信介绍

    CW32的SPI单工模式主从通信介绍
    的头像 发表于 10-24 15:50 627次阅读
    <b class='flag-5'>CW32</b>的SPI单工<b class='flag-5'>模式</b>主从通信介绍

    应用笔记-CW32 自举程序中使用的 ISP 协议

    ,通过UART串口方便地实现对CW32微控制器片上FLASH主存储器的擦除和烧写。本应用笔记将介绍如何进入CW32微控制器ISP模式,以及所使用的ISP协议,并
    发表于 06-06 13:37 7次下载

    基于CW32的物联网应用

    CW32】基于CW32的物联网应用
    的头像 发表于 11-02 15:55 564次阅读
    基于<b class='flag-5'>CW32</b>的物联网应用

    那么点详细CW32学习笔记】通用异步收发器—发送篇

    本章介绍CW32通用异步收发器的使用。 虽然大部分时候会被简单称为“串口”,但实际上 用“串口”来指代UART并不正确 。串口对应并口的概念,在串口通信中,数据被以二进制形式发送,并且每次发送都只
    的头像 发表于 11-17 17:30 566次阅读
    【<b class='flag-5'>有</b><b class='flag-5'>那么点</b><b class='flag-5'>详细</b>的<b class='flag-5'>CW32</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>】通用异步收发器—发送篇

    那么点详细CW32学习笔记】IIC接口-主机发送

    例程链接 : https://pan.baidu.com/s/1s1XwqDFkO8fK4SRSTKsNhA?pwd=mshk 提取码 :mshk 本章将介绍CW32的IIC接口,并最终点亮一块
    的头像 发表于 01-11 09:53 426次阅读
    【<b class='flag-5'>有</b><b class='flag-5'>那么点</b><b class='flag-5'>详细</b>的<b class='flag-5'>CW32</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>】IIC接口-主机发送

    那么点详细CW32学习笔记】IIC接口-OLED驱动

    ,实际上就是密集LED点阵,所以必定有用于控制大量LED灯的驱动器,本教学使用的OLED驱动是SSD1306,该驱动器多种通信接口,这里使用IIC接口(具体使用什么接口,数据手册上会有详细介绍) 根据SSD1306数据手册的描述,该设备的从机地址取决于SA0的电平,但
    的头像 发表于 01-11 09:49 490次阅读
    【<b class='flag-5'>有</b><b class='flag-5'>那么点</b><b class='flag-5'>详细</b>的<b class='flag-5'>CW32</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>】IIC接口-OLED驱动