STM32采集AD电压

发布者:innovator8最新更新时间:2019-10-30 来源: eefocus关键字:STM32  采集AD电压  DMA传输 手机看文章 扫描二维码
随时随地手机看文章

是否使用DMA传输

使用DMA传输,那么流程为:

ADC初始化,DMA初始化,TIM2初始化 

其中:TIM2作为ADC的中断源

当发生一次定时器的中断时,进入AD转换,在DMA的初始化时与ADC-DR寄存器进行绑定,在该寄存器获得数据时,直接通过DMA通道将该寄存器的数据保存在给定的数组里面,把缓存数组装满后,会触发一次DMA的中断,在DMA的中断里面将缓存数组保存到100个电压值的数组里面。

定时器设为200us发生一次中断,来进行一次AD转换,获得寄存器里面的数据以后,保存在数组,保存100个数组后停止定时器的工作以及DMA的工作,对这份数据进行处理。 

至此,DMA工作的流程已经结束,那么其中又怎样的缺漏导致不用DMA进行操作,按照上述流程获得的100个离散点的电压是较为准确的(PS:这里可以把TIM2的定时中断时间改为采集32个点的625us或者采集64个点的312us),但是,如果只是放置在采集单相电压电流可以考虑,如果采集多相的电流电压,就要考虑到相位的问题,在之前的思路中

使用定时采集,流程为:

ADC初始化、定时器TIM3初始化 

这里的TIM3的中断时间为100us

进过200us,即0.2ms,启动AD转换,比如三相交流电压,依次对A,B,C三通道AD进行转换,获得当前的电压值,保存在数组里面。

当保存了100个数据以后,如果不考虑误差,那么0.2ms*100=20ms,即为50Hz电压的一个周期的时间采集到的电压值,采集到的100个离散点使用均方根公式进行求值获得该通道的电压的有效值。

在此转换中,进过0.2ms进行一次转换,不停止,功耗比较大,但是每次获得数据后,都要通过数据是否过上升沿下降沿开始,判断有无错相。(关于是否错相算法见下文)

总结

对比两个流程可以知道:如果不考虑相位问题,那么可以使用DMA+ADC采集数据,比如0.5s开启一下DMA与定时器采集一次,采集到的100个数据保存在数组里面,关闭定时器与DMA,采集好以后进行处理一下存储在当前电压值的变量里面,但是这样的一组周期内的电压,存在着可能无法判断是否错相的情况,比如采集ABC三相,当A出现下降沿过抬高电压位置时,开始计时,可能从这时开始到这个周期结束没有发生B相出现上升沿过抬高电压的情况,这样判断错相就会出现问题,当然,也可以直接使用DMA+ADC去类似0.2ms就进行一次转换,不间断的进行这个流程,这个方式我认为与0.2ms手动开启AD转换,不经过DMA传输直接读取寄存器ADC-DR的值相差的功耗不大。(待测)


算法

采集

AD采集到的数据进行处理获得当前的瞬时电压值: 

ADC_DR/当前电压值 = 4096/3300毫伏 

即 当前电压值 = (ADC_DR*3300)/4096; 

在程序中我们对其进行了简化,最终的公式为 

当前电压值 = (ADC_DR*825)>>10 

就这样,我们保存了一个周期内100个点的电压值,也就是100个正弦波形上的离散点。

计算

根据100个离散点求得该引脚的电压的有效值: 

均方根公式:


这个网上不少,直接百度即可

Xi为离散点的电压值,N为100,Xrms为电压有效值 

其中要注意的是:Xi²实则为(引脚处电压 – 抬高电压)²


错相判断

下面为正相序时的波形图:


改天抽时间重画,原来的文件没了

譬如检测AB有无错相,当A出现下降沿并且过0点时(实际程序中是过抬高电压值时),开始计时,当B出现上升沿并且过0点时停止计时,这段时间T = 16.67ms,如果考虑一些特殊情况,比如电压的频率波动,开启计时的时间存在误差,可以假定T ≥15.5ms,AB为正相序。 

下面为反相序时的波形图:


由此图我们可以看出,依旧像上面说的那样,在A(假定是A)相电压出现下降沿过0点时开启计时,在B相电压出现上升沿过零点时停止计时,此时时间远远小于正相序时的时间,如果无误差时T = 3.3ms,考虑到上述误差影响,那么我们把时间T ≤3.6ms时判断得AB为反相序。在程序中扩大了一下范围,把这个判断是否为反相序的时间调整为4.0ms,如果这段时间小于4.0ms,那么就认为是错相,大于的话默认为正相序。


错相与缺相的逻辑判断:

<1>. 当存在缺相时,不执行错相判断函数; 

<2>. 当存在缺相时,将通信返回的内容里面的错相位置为0,只将缺相对应位置为1。 

<3>. 当不存在缺相时,只判断AB是否错相,从A出现下降沿过0点开始计时,B出现上升沿过0点关闭计时,判断是否小于4.0ms,若是,则将错相位全部置为1,如果不是,全部置为0。 

<4>. 关于缺相判断,在求得电压的有效值后,有一个范围,目前设定为50mv,如果小于50mv,说明该相电压缺相。


关键字:STM32  采集AD电压  DMA传输 引用地址:STM32采集AD电压

上一篇:stm32学习笔记---ADC电压采集
下一篇:STM32F103实现双ADC同步采集电压信号

推荐阅读最新更新时间:2024-11-11 09:12

基于STM32的超声波HC-SR04历程
HC-SR04基本工作原理: (1)采用IO口TRIG触发测距,给最少10us的高电平信呈。 (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回, 通过IO口ECHO输出一个高电平, 高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2。 程序编写思路是:1、配置好使用到的GPIO以及定时器; 2、给模块TRIG端口发送大于10us的高电平信号,当收、收到ECHO回响信号是,打开定时器开始定时; 3、当回响信号消失,关闭定时器; 4、通过定时器定时时间来确定距离。 /*Systick延时函数 Systick 延时初始化*/ void SysTi
[单片机]
什么是GPIO? STM32中关于GPIO口的介绍
一、什么是GPIO? GPIO的英文全称是General-Purpose IO ports,也就是通用输入输出口。 在嵌入式系统中,经常需要控制许多结构简单的外部设备或者电路,这些设备有的需要通过CPU控制,有的需要CPU提供输入信号。并且,许多设备或电路只要求有开/关两种状体就够了,比如LED的亮与灭。对这些设备的控制,使用传统的串口或者并口就显得比较复杂,所以,在嵌入式微处理器上通常提供了一种“通用可编程I/O端口”,也就是GPIO。 一个GPIO端口至少需要两个寄存器,一个做控制用的“通用IO端口控制寄存器”,还有一个是存放数据的“通用I/O端口数据寄存器”。数据寄存器的每一位是和GPIO的硬件引脚对应的,而数据的传递方向是
[单片机]
什么是GPIO? <font color='red'>STM32</font>中关于GPIO口的介绍
浅谈STM32的端口输出方式
STM32有两个寄存器可以控制IO输出, 一个是ODR寄存器, 只使用了低16位. 向此寄存器写数据, 就可以控制某个引脚的输出电平. BSRR寄存器是端口位设置/清除寄存器. 此寄存器和ODR寄存器有类似的功能, 都可以来用设置GPIO端口输出.此寄存器分为高16位和低16位, 向高16位的某位写1清除对应ODR寄存器位(输出0), 写0无影响. 向低16位某位写1置位对应ODR寄存器位(输出1), 写0无影响. 可见两个寄存器均可以控制IO输出, 从上文可知写BSRR实际上是可以影响ODR寄存器的值的, 那么使用这两个寄存器控制输出有什么区别呢? 在ST的手册中有这样的说明(RM0090 266页): Each I/O por
[单片机]
STM32片内FLASH被异常改写的问题分享
某STM32客户反馈,当STM32F407V芯片频繁的正常通断电的时候,FLASH 会被非法改写,出现各种各样的异常(整片被擦除、中断向量表被改写、写保护被清除等等)。 经过与跟客户沟通了解到: 1、他们是延续之前的项目,进行的一些软硬件简单修改。之前的项目没有出现过类似的问题。 2、确认通断电的时间是足够,即断电后所有的VDD都回到0;上电的时序也正常。 3、原理图参考了ST相关开发板的参考设计。 4、测量工作电压,除了发觉上电时会有些许抖动外,其它一切正常。尝试让他们改善上电电路,去掉这一抖动。再次实验,仍然出现类似的问题。 根据现象初步判断,异常似乎跟硬件没关联了, 接着对客户代码进行删减又做了如下实验: 1,去掉A
[单片机]
<font color='red'>STM32</font>片内FLASH被异常改写的问题分享
STM32软件IIC的实现
接上篇,LIS331的例程终于可以正常运行了,接下来就是将其移植到STM32上了,不过第一次接触STM32的IIC,看例程比较简单,直接复制到工程后却读不出数据,一直停在等待从设备回复ACK的死循环。 经过一天的修改之后,终于还是舍去了硬件IIC改成了用软件实现,最终代码如下: .h文件 #include stm32f10x.h #define ANO_GPIO_I2C GPIOB #define I2C_Pin_SCL GPIO_Pin_3 #define I2C_Pin_SDA GPIO_Pin_4 #define ANO_RCC_I2C RCC_APB2Periph_GPIOB /*******
[单片机]
<font color='red'>STM32</font>软件IIC的实现
STM32开发笔记33:解决USB CDC “该设备无法启动”问题
单片机型号:STM32F401 调试STM32的USB CDC设备已经有好多次了,可以看一下前面写的日志,针对不同的STM32 MCU都进行了调试。原本以为STM32F4会很简单,可处处是坑,已经调到半夜才解决问题,把问题重新梳理。 我现在使用的芯片时STM32F401,在STM32CubeMX中,按照以下步骤设置。 1、设置为全速从设备,不做USB电源检测。 2、使能CDC,其它采用默认设置。 按照上述设置生成的程序,下载到芯片后,接入计算机,默认是这样的 仔细查看细节问题是这样的 找了好久不能解决问题,网上有一种说法是,是更改usbd_conf.h
[单片机]
<font color='red'>STM32</font>开发笔记33:解决USB CDC “该设备无法启动”问题
STM32电容触摸按键原理
RC充放电电路原理 如图: 电阻R和电容C串联 当开关断开时,电阻R,电容0两端电压都是0,无电流 当开关闭合时(瞬间),电阻R两端V1(上端)和0(下端)有电压差,产生电流 此时电子通过电阻R积累在电容正极(上端),直到电容C电压为V1,充电完成 此时R两端电压均为V1,无压差,不再有电流经过 电容C的电压从0-V1,充电过程中,有充电时间t和电容C的电压Vt之间的关系(右图) 看以看出随充电时间越来越长,充电的效率(斜率)越来越低 分析: 当按键按下瞬间,电阻R两端电压V1和0,此时瞬间电流为I = V1 / R 当电容C充电一段时间后,假设电容C此时的电压为Vc,那么此时电阻C两端的电
[单片机]
<font color='red'>STM32</font>电容触摸按键原理
STM32系列是大端还是小端?
ARM的手册上有关于大小端的描述,如下: The processor can access data words in memory in little-endian format or big-endian format. It always accesses code in little-endian format. Note: Little-endian is the default memory format for ARM processors. STM32是固定配置为小端的 The bytes are coded in memory in Little Endian format. The lowest number
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved