打印

请教定时器中断扫描数码管怪问题

[复制链接]
4210|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1加1等于几|  楼主 | 2007-4-6 17:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用T0动态扫描12个数码管的时候,出现怪问题:
先把我程序给大家描述一下
void T0_ISR()interrupt 1{
   ++count;
   if(count ==1){
     xiaoying();//消隐,所以数码管处于不选中状态
     disp1();//扫描第一个数码管
   }
   else if(count ==2){
     xiaoying();//把这个数码管不选中状态
     disp2();//扫描第一个数码管
   }
   ........
   else if(count ==12){
     xiaoying();//把这个数码管不选中状态
     disp12();//扫描第一个数码管
   }
}
本来这个程序没有xiaoyin();这行代码的,今天自己加上的,也解决不了问题的。
出现的问题是:
比如一行一直显示72.12,过一会(很不随机的时间)就突然这个数字“哗”的散一下,或者第一个数字7变了一下(或2下)8,然后又变回来。

没遇到过这种问题,请教大家,谢谢!

相关帖子

沙发
ayb_ice| | 2007-4-6 18:04 | 只看该作者

随便说说

disp2();//扫描第一个数码管
上面的代码没有,看不出来什么问题....

使用特权

评论回复
板凳
dai_weis| | 2007-4-6 21:27 | 只看该作者

程序执行时间太长了

改改看看,
把数据放到数组中,第一个就是data[0],等
扫描时:
消隐时间不用太多关闭位和段的端口,就可以,长时间消隐则给空值

使用特权

评论回复
地板
1加1等于几|  楼主 | 2007-4-6 21:44 | 只看该作者

谢谢楼上二位指教

to 随便说说:我这12个数码管的位选是通过4选16译码器来选择的0000~1111。所以当我P口1111是什么也没有选中,(即屏幕为黑,消隐)
所以xiaoying();这个函数的内容是{P1_0=1;P1_1=1;P1_2=1;P1_3=1;_nop_();_nop_();}
to dai_weis:我的数据就是放在一个缓冲里的(也就是你说的数组),而且我定时是1ms,所以消隐知识6条语句。不存在长时间消隐的。

我觉得动态扫描都是在定时器里进行的,希望大家多多指教啊。
谢谢!

使用特权

评论回复
5
ayb_ice| | 2007-4-7 08:12 | 只看该作者

随便说说

  根本就不需要消隐,因为4选16永远只能选中其一,选中的同时已经关闭了其它位,即使要用P1_0=1;P1_1=1;P1_2=1;P1_3=1这句话也可以优化成P0|=0xFF,动态扫描最重要是时间观念,更何况12个有点多。。。
我要看的是下面的函数
disp2();//扫描第一个数码管
上面的代码没有,看不出来什么问题....
我觉得应该是类似这样的代码:
  DISPLAY_PORT = display_buffer[display_position];
你的定时中断可以更优化些如下的示意代码:
void isr_timer0(void) interrupt 1
{
    unsigned char code LED_SELECT[] = {0,1,2,3,4,5,6,7,8,9,10,11,12};

    ++display_position;
    display_position %= 12

    DISPLAY_PORT = 0;       // LED OFF
    P1 &= ~0x0F;
    P1 |=LED_SELECT[display_position];  // 选择位
    DISPLAY_PORT = display_buffer[display_position];    // 送数据
}
上面的程序比你的执行要快,重要的是程序执行时间是固定,没有附加的抖动,你的程序如果要显示第12位,显然与第一位有区别。。。
以上随便说说。。。

使用特权

评论回复
6
1加1等于几|  楼主 | 2007-4-7 10:23 | 只看该作者

谢谢随便说说的指教

我开始实验中动态扫描的15个数码管,亮度稍微有点低,但是我把电阻改小点后,看上去也差不多了。
其实我的4选16不是像我说的那样P0口连续的(上边的帖子我只是为了说明我的思路,不好意思误导你了)。为了走线方便,有2个接P2,2个接P3的。所以也不能用1条语句实现的。

在“disp2();//扫描第一个数码管”这个函数中:里边代码确实和你说的一样。大体是一条语句送段,一条是位选,另外就是显示符号,小数点判断以及一些判断该显示变量一类。(大约10多条语句把)。
我觉得如果把disp1()....disp12()不写成函数,而直接放在void isr_timer0(void) interrupt 1 这个里边,感觉太杂,有点看不过去。虽然写成函数增加了点切换什么的,但是这样感觉看起来舒服点了。

再次谢谢随便说说的指教,可惜没有像51BBS那样送给你分。我想这个显示问题应该不会是我定时中断的原因,我再找找其它地方把。

使用特权

评论回复
7
ayb_ice| | 2007-4-7 10:37 | 只看该作者

随便说说

建议你设2个缓冲区,显示中断从2取数显示,而主程序最后把待显示数据(1个里的数据)一次送至2个缓冲区里,我怀疑你看到的是两部分的数据。。。

使用特权

评论回复
8
free_tech| | 2007-4-7 12:18 | 只看该作者

你看我分析得对不对

你的主程序改变显示数时,被中断打断了,显示的数据不对,但是下几个周期又对了

就好像 FF FF FF +1 应该显示00 00  00
                   
                  有时会显示 FF FF 00 一样
 
                  或者       FF 00 00

 显示与数据处理不同步

多开缓存就行了        

使用特权

评论回复
9
1加1等于几|  楼主 | 2007-4-7 12:25 | 只看该作者

to 随便说说

我怎么没想到呢。晕!
按照你的意见:。
我现在
1》开2个缓冲
2》把采集到并转化为可显示的数据,放在一个临时缓冲内(全局变量),
3》然后在T0中断里在显示第一个数据的前边把这个临时缓冲放到实时缓冲里并用于显示
4》(disp1()..disp4()显示一个完整数据),依次类推。这样就避免了两部分的数据的冲突。
5》多谢随便说说的帮助

使用特权

评论回复
10
1加1等于几|  楼主 | 2007-4-7 12:40 | 只看该作者

free_tech 很有道理啊,谢谢。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

22

帖子

0

粉丝