[经验] 回报论坛,发一个经验帖~有关430精确控制AD采样率

Ben讨厌苦咖啡   2015-5-20 16:24 楼主
这段时间在搞的项目要用到430精确控制AD采样率,感觉自己搞了好久,期间没少问问题,论坛啊,QQ群啊,甚至还问过TI的员工,还和自己的小伙伴讨论了这个问题。非常给力的是最终我终于解决了这个问题。



因为我没有什么写代码的基础,当年的C语言也是水过去的。。。。。。单片机也没有学过,所以搞起来其实还是挺吃力的。最后程序的结构貌似也有些问题,不过先实现了精确控制AD采样的功能,还是挺有成就感。

在程序的结构上面可能我还有些问题,希望论坛的各位大神多给我些指导意见~~~非常感谢~~~~



好,废话不多说了,开搞~~~~我用的是MSP430F5529的板子~~~



首先说说我的思路。



其实思路很简单。设定AD 这里粗略的采样率一定要很大,然后在AD中断里面将ADC12MEM取到并转换的值赋给一个临时的temp 然后设定定时器,通过定时器设定固定时间进入定时器中断,在定时器中断里面将temp的值提取出来并处理~~~~~(我的程序是将temp转换并且通过UART串口发送到PC)




设定AD,AD的采样转换模式设为脉冲采样时序模式,时序图如下,从图上看到其实整个时序图是包含采样和转换的时间的,这里关于采样时间是有个公式:4*ADC12CLK*ADC12SHTx  注意,这里的采样时间其实是说得Tsample~



当时我在这里遇到个问题就是这个采样时间是指Tsample还是说 整个加起来的时间??最后问了TI的员工 ,他们回答我说 只是Tsample。Tsample通过SHT0x和SHT1x来定义,但是我们没有办法知道Tsync的时间,从图上来看差不多3个ADCCLK吧~~~~~~所以,通过这里想要达到精确设定AD采样率的目的就不大可能了,只能说是粗略的设置。



所以,整个的采样转换时间应该是Tsample+Tsync+Tconvert 那么采样率就是这个的倒数了 所以 大概采样转换时间就是 4*ADC12CLK*ADC12SHTx+3ADC12CLK+13ADC12CLK;  通过这里就可以粗略地设定AD采样率。







时序图2.png



其实主要遇到的问题就在这里,我得到的结论就是单单凭设定SHT寄存器是无法精确设定采样率的,想要精确设定采样率还是需要定时器。



网上的大神们给的建议是通过定时器触发AD采样。这个我有点没有太懂,后来也没有搞~~~

其实我这个思路真正的AD采样率是很大的,而且是不确定的,但是通过定时器固定时间将ADC12MEM读取出来其实也就是精确设定了采样率~~~~~



比较简单浅显,我也是个菜鸟,希望大神们别鄙视我~~~~~~谢啦!!!!


回复评论 (18)

2推荐 强仔00001 

进步不错
点赞  2015-5-20 23:08
这样的方法也会有一个问题,比如你一5K左右的ADC采样,后以3K的精准定时器读取temp数据,这时候你每次读取temp数据距离ADC写入temp的时间是不一样的,虽然在整体采样率上看似是精确的,但是结果里的每一个采样点的时间间隔却是不同的, 有兴趣可以去了解一下相位噪声方面的知识。
点赞  2015-5-20 21:58
引用: littleshrimp 发表于 2015-5-20 21:58
这样的方法也会有一个问题,比如你一5K左右的ADC采样,后以3K的精准定时器读取temp数据,这时候你每次读取temp数据距离ADC写入temp的时间是不一样的,虽然在整体采样率上看似是精确的,但是结果里的每一个采样点的时间间隔却是不同的, 有兴趣可以去了解一下相位噪声方面的知识。

嗯~说得没错~~~~~~但是感觉如果按照这个方法可能这个问题就不能避免了吧~
点赞  2015-5-20 22:07
引用: Ben讨厌苦咖啡 发表于 2015-5-20 22:07
嗯~说得没错~~~~~~但是感觉如果按照这个方法可能这个问题就不能避免了吧~

所以在定时器里使能ADC做单次转换会更好些。
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2015-5-20 22:19
本来这个帖子我不想回复了,看到强仔的回复,忍不住点了个赞。
确实,没有过单片机开发经历的人能做到这个地步已经很不错了。

在这里,我需要指出几个问题来。在你上一个帖子里我更关注于代码与程序思路,在这里说说系统设计的思路。

你的标题是“精确控制AD采样率”,一般来说,ADC的采样率是受其性能限制的。越高速,精度越高的ADC售价也就越贵。对于高速ADC而言,控制其采样速率只能通过控制ADC时钟来实现。正因为你的问题问得比较大,所以大家都往复杂了考虑,认为你是希望控制接近于芯片极限的那种采样率,并且还要准确的控制。

然后我们来看看具体的实例,你使用的F5529内置的ADC模块一般采样率是200ksps,而你在程序中的采样率是200sps(5ms)。是ADC模块常用采样率的千分之一,这与标题所描述的控制采样率就千差万别了。你咨询的TI员工,以及各种小伙伴估计都找错方向了。其实你的目的根本就不是去控制ADC时钟来实现精确采样率,而是通过让ADC间歇工作,来实现一个较为精确的低速采样。这么一来,只需要设置好定时器,在合适的时间让ADC转换一次数据就可以了。

另外你的ADC模块不应该工作在连续模式,因为你在一千个周期里只取一个数据,多余的数据转换完不取用是浪费。同时ADC转换过程会消耗能量,使用MSP430实现低功耗的目的也没能办到。

我之前给你的例程应该是单通道单次转换的,每次ADC模块只进行一次转换,转换完成之后自动关闭。每次采样前需要单独配置ADC模块。开始采样之后休眠,转换完成之后唤醒MCU继续工作。单次任务完成之后休眠等待定时器中断来唤醒。
(ADC转换过程中的休眠是为了节省CPU的功耗,在我看来,MSP430的最大优势就是休眠快,唤醒也快,全过程自动实现,几乎不用操心。ADC转换虽然只有几十到一两百个时钟周期,但是这期间MCU几乎不能完成其他任务,必须等待ADC转换结果。与其用while语句空转消耗能量,不如让其休眠,等转换完成用中断服务来唤醒,这样也多不了几个时钟周期。)

这个方案里ADC采样可能会有几个时钟周期的误差,应该在你允许的误差范围之内。
点赞  2015-5-21 01:10

整哭了~~~~~~~~~~~~~~  一直以来谢谢你的帮助啊小伙~~~~~~
点赞  2015-5-21 08:47
引用: littleshrimp 发表于 2015-5-20 22:19
所以在定时器里使能ADC做单次转换会更好些。

好主意啊!后面我可以试试!现在我选的是多次转换模式~~~~
点赞  2015-5-21 08:48
引用: qiushenghua 发表于 2015-5-21 01:10
本来这个帖子我不想回复了,看到强仔的回复,忍不住点了个赞。
确实,没有过单片机开发经历的人能做到这个地步已经很不错了。

在这里,我需要指出几个问题来。在你上一个帖子里我更关注于代码与程序思路,在这里说说系统设计的思路。

你的标题是“精确控制AD采样率”,一般来说,ADC的采样率是受其性能限制的。越高速,精度越高的ADC售价也就越贵。对于高速ADC而言,控制其采样速率只能通过控制ADC时钟来实现。正因为你的问题问得比较大,所以大家都往复杂了考虑,认为你是希望控制接近于芯片极限的那种采样率,并且还要准确的控制。

然后我们来看看具体的实例,你使用的F5529内置的ADC模块一般采样率是200ksps,而你在程序中的采样率是200sps(5ms)。是ADC模块常用采样率的千分之一,这与标题所描述的控制采样率就千差万别了。你咨询的TI员工,以及各种小伙伴估计都找错方向了。其实你的目的根本就不是去控制ADC时钟来实现精确采样率,而是通过让ADC间歇工作,来实现一个较为精确的低速采样。这么一来,只需要设置好定时器,在合适的时间让ADC转换一次数据就可以了。

另外你的ADC模块不应该工作在连续模式,因为你在一千个周期里只取一个数据,多余的数据转换完不取用是浪费。同时ADC转换过程会消耗能量,使用MSP430实现低功耗的目的也没能办到。

我之前给你的例程应该是单通道单次转换的,每次ADC模块只进行一次转换,转换完成之后自动关闭。每次采样前需要单独配置ADC模块。开始采样之后休眠,转换完成之后唤醒MCU继续工作。单次任务完成之后休眠等待定时器中断来唤醒。
(ADC转换过程中的休眠是为了节省CPU的功耗,在我看来,MSP430的最大优势就是休眠快,唤醒也快,全过程自动实现,几乎不用操心。ADC转换虽然只有几十到一两百个时钟周期,但是这期间MCU几乎不能完成其他任务,必须等待ADC转换结果。与其用while语句空转消耗能量,不如让其休眠,等转换完成用中断服务来唤醒,这样也多不了几个时钟周期。)

这个方案里ADC采样可能会有几个时钟周期的误差,应该在你允许的误差范围之内。

非常感谢版主大人的帮助,您详细的回复让我又有了新的理解,像您说的,确实之前我们还有其他小伙伴对我的问题可能理解的不一样,所以导致了其实我的思路和你们的就不一样,后面就一直没办法突破问题~~



其实非常不好意思的说 我之前按照您给的方法没有实现我想要的功能,而且感觉我对程序结构的理解也不够透彻~后面我再试试,现在总感觉我自己的程序是存在很多问题的。。。。。。呃。。。。。。






点赞  2015-5-21 08:55
半路出家的确很不容易,由于基础的限制往往对要求稍严格或深入一点的问题束手无策,所以现在我很认同以前不知道在哪看到一句话:学历很重要,因为基础更重要啊……
点赞  2015-5-21 14:38
引用: gh131413 发表于 2015-5-21 14:38
半路出家的确很不容易,由于基础的限制往往对要求稍严格或深入一点的问题束手无策,所以现在我很认同以前不知道在哪看到一句话:学历很重要,因为基础更重要啊……

哈哈 这个学历很重要。。。。。。我是烟酒僧。。。。。。
点赞  2015-5-21 15:59
引用: Ben讨厌苦咖啡 发表于 2015-5-21 15:59 哈哈 这个学历很重要。。。。。。我是烟酒僧。。。。。。
我是半路杀出的,正因为有些东西我很难深入,所以也认同了这句话…… 本帖最后由 gh131413 于 2015-5-21 17:06 编辑
点赞  2015-5-21 17:04
引用: gh131413 发表于 2015-5-21 17:04
我是半路杀出的,正因为有些东西我很难深入,所以也认同了这句话……

加油吧 亲~
点赞  2015-5-21 18:00
引用: Ben讨厌苦咖啡 发表于 2015-5-21 08:47
整哭了~~~~~~~~~~~~~~  一直以来谢谢你的帮助啊小伙~~~~~~

好好努力
点赞  2015-5-22 00:03
我是新手,刚学MSP430,能看一下你的代码吗,想学习学习
点赞  2015-6-7 20:16
引用: 谁是谁的谁 发表于 2015-6-7 20:16
我是新手,刚学MSP430,能看一下你的代码吗,想学习学习

AD采集的代码都是从例程里面改的,所以基本就是例程
点赞  2015-6-8 17:02
以上讨论都没有解决一个问题:如何在比较高的采样率情况下实现精确控制,比如3KS/s,其周期太短,没法用定时器控制,另一方面Tyscn不知道,很难通过设置ADC12CLK精确计算采样率,用定时器定时读取的做法有掩耳盗铃之嫌。这个问题我也没想到办法,希望各位大神指点。谢谢!
点赞  2016-8-21 08:39
看到有些说咋定时器里面使能单词转换的,但是,采用这种方法的话,是不是要进定时器中断?进中断出中断都是需要时间的。当处在中断处理函数的时候,这时候定时器是不是不工作的?只有出了中断之后定时器才重新开始计数?这样的话,采用定时器启动转换的方式也不是很精确。
点赞  2017-11-24 14:51
有例程吗
点赞  2019-8-10 09:24
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复