AD转换速率问题,还请指教

barryan2007 2010-07-12 10:39:55
小弟最近在做一个AD降采样的算法。

在ISR中,采用连续转换模式,每采集一个数据就让FLAG=1,随后在MAIN函数中,进行降采样的算法,随后通过UART发到终端

为了缓解ISR与MAIN的速度之差,以及让AD值能够快速传递。现在我用的方法是,设置一个全局变量数组,将ISR中转换的数据写入数组,同时在main中读取数组的值。

当转换频率为8KHZ时,在ISR中,每转换一次AD值,就将转换的AD值放入全局数组a[500]中,随后让flag=1;

在Main中,等待flag==1,然后从数组中依次读取AD值。随后进行降采样运算,随后发送UART



但是现在发现由于ISR中,放入数组的速度比main中读取的速度快,过一段时间后,原来写入数组的AD值会被新的值覆盖。main来不急读原来的值,就读取新的值了。也就是说写入的指针比读取的指针快了500超过。这样的话,读取的数据就不对了

请问这个问题怎么解决?
...全文
1446 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
liulei99 2011-07-14
  • 打赏
  • 举报
回复
双缓存,存完一个BUFFER存另一个
Vincent-Fu 2011-03-22
  • 打赏
  • 举报
回复
楼上说:
所以说ADC虽然是8KHZ,但是实际UART的速率为ADC的1/8。 这样算起来的话,256000波特率的UART应该能满足条件的。也就是说main中的UART应该来得及处理的。
怎么说实际的UART是ADC的1/8 ,又说256000波特率的UART这样不是有两个速度?
barryan2007 2010-07-26
  • 打赏
  • 举报
回复
我漏说了一点:

采样24个数据为一组数据,另外用一个pointer作为数据的序号。24个数据通过平均算法后通过UART只发送3个数据。(pointer分别为8,16,24时,就通过UART发送)

所以说ADC虽然是8KHZ,但是实际UART的速率为ADC的1/8。 这样算起来的话,256000波特率的UART应该能满足条件的。也就是说main中的UART应该来得及处理的。

那这样来说的话,还是main函数中算法的问题,还不够简洁?
dreamjack 2010-07-26
  • 打赏
  • 举报
回复
对的


你降压采样,采样多少次为一组数据?


是否可以先讲一组处理一下,较少通讯的数据量
barryan2007 2010-07-26
  • 打赏
  • 举报
回复
我上午自己算了一下UART发送的时间和ADC转换的时间。

我把自己所理解的说一下,请各位大侠看看我理解的是否正确,谢谢。

(1)、ADC的转换频率是8KHZ,那么这样算起来,1秒ADC的值就会转换8000次,即adccount=8000
(2)、UART的波特率是256000,它的单位应该是 bits/秒

我现在假设每次通过UART 发送的数据是4个字节。(格式是"%d\r\n",%d对应数字11,后面两个各占一个字节),设置起始位和停止位各1位,那么4个字节就是 4*10 = 40bits (这里我不确定自己理解是否正确)

那么256000/40=6400,也就是说1秒能够发送6400次。

所以光这样看的话,ADC的转换速度就比main中的UART发送速度快,再加上main中还有一点算法在,增加了CPU的时间。

所以说ADC中断中的 adccount数值比 main中的 maincount数值大也就是很自然的事了。

不知道我这样想是否正确,还请各位赐教,不胜感激。

schlafenhamster 2010-07-26
  • 打赏
  • 举报
回复
如果CPU时间不够,UART发送要改成中断方式,否则查询方式占时间太长。
barryan2007 2010-07-25
  • 打赏
  • 举报
回复
帮自己再顶一下。这个问题纠结了两个星期。

总是发现ISR中AD的8KHZ转换频率时,它的cnt1++数值比较大;

而在main中的cnt2++数值比cnt1++数值小,而且随着时间的增加相差越来越大。

我就不明白,为什么main中的速度比ADC转换频率的8KHZ速度还慢。

难道是因为在main中的UART每次要发送好几个字节导致速度降低? 我将UART设置成最高的256000了,速度应该很快的啊,还请指教

barryan2007 2010-07-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 schlafenhamster 的回复:]
main中”降采样的算法“用的时间过长。
一般来说中断程序所用的时间只能占主循环时间的的40%到60%。否则要换高速CPU。
你的“降采样的算法”如果只是平均,可以想法减少计算时间。
[/Quote]

通过调试发现 Main函数中的 读取缓冲区数组的速度 比 ISR的ADC中断中, 写入缓冲区数组的速度 慢。

我现在就是不太确定,到底是Main中由于算法导致速度降低,还是因为main中的UART速度比较慢,从而导致整个Main速度降低。

当ADC转换频率降低为1khz时,读取速度和写入速度几乎相等。
Great_Bug 2010-07-21
  • 打赏
  • 举报
回复
用两个缓冲区....一边用一个...
dreamjack 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dreamjack 的回复:]
换USB接口,或者带有40MHz的CPU

只有一条,通信速度比采样速度快就可以了!
[/Quote]
否则,你采样再快,数据还是丢失的
dreamjack 2010-07-21
  • 打赏
  • 举报
回复
换USB接口,或者带有40MHz的CPU

只有一条,通信速度比采样速度快就可以了!
schlafenhamster 2010-07-21
  • 打赏
  • 举报
回复
main中”降采样的算法“用的时间过长。
一般来说中断程序所用的时间只能占主循环时间的的40%到60%。否则要换高速CPU。
你的“降采样的算法”如果只是平均,可以想法减少计算时间。
barryan2007 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 great_bug 的回复:]
用两个缓冲区....一边用一个...
[/Quote]

不太明白您的意思。 两个缓冲区,怎么读,怎么写呢?

还能详细点吗?谢谢
Linux_lee 2010-07-13
  • 打赏
  • 举报
回复
LS正解,速度瓶颈在UART
dreamjack 2010-07-13
  • 打赏
  • 举报
回复
问题是UART发送的时间比较长,大于AD 500的周期

所以在只能在UART发送完后,将FLAG=0;

在ISR中,只有FLAG=0是才能更新缓冲区数据
DISINHUI 2010-07-13
  • 打赏
  • 举报
回复
1.main中读完后清零该位置的数据,
2.ISR中发现数据不为零,不覆盖,找空写入,没有空,则写入缓冲区,若缓冲区满,则报警或者抛弃当前数据。
barryan2007 2010-07-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dreamjack 的回复:]
问题是UART发送的时间比较长,大于AD 500的周期

所以在只能在UART发送完后,将FLAG=0;

在ISR中,只有FLAG=0是才能更新缓冲区数据
[/Quote]

你好,首先很感谢你的解答。
我根据你说的,在ISR中,只有当FLAG=0时才能更新缓冲区a[]中的数据,即写入新的AD值.

这时候,的确不会遗漏数据了。正当我微笑之际,领导一句话让我又陷入了沉思。。。。


我把大致程序写出来,和大家讨论一下,定义了一个全局数组a[500]

main()
{
寄存器配置;
while(1)
{
if(flag==1) //等待AD中断完成标志
{
sum2=a[readpoint]*f(p); //a[readpoint]是从数组a中读取AD值
readpoint++;
if(readpoint>=500)
{
readpoint=0;
}
out=sum2/k;
当中都是降采样算法...

UART发送一个AD数据;

flag=0; //flag=0
}
}
}

ISR
{
if(AD中断)
{
if(flag==0) //等待main完成UART发送的标志
{
a[writepoint]=ADCDATA;
writepoint++;
if(writepoint>=500)
{
writepoint=0;
}
flag=1; // flag=1给main函数信号
}
}
}

现在公司要求ADC的转换频率要为8KHZ,不能减少采样速度。

但是如果在ISR中添加if(flag==0)后,要等待main处理完才获取第二个AD值,那么它采样AD的频率应该低于8KHZ了吧?(感觉main限制了AD采样的速度)

不知道我理解的是否正确,ISR中AD的采样频率是否比8KHZ低了?

如果低于8KHZ的话,那就不能用这个方法了,还有其他好的方法吗?

还请各位多多指教,谢谢。

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧