打印
[AVR单片机]

数码管按键加1,十位数会闪动,怎么解决

[复制链接]
2906|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liuhuonihao|  楼主 | 2014-8-21 16:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <iom16v.h>
#include <macros.h>
unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned int num=0;
void delay(unsigned int i)       //1ms延时函数         
   {
    while(i--)
    {                          
            unsigned int j;               
        for(j=1;j<=613;j++)   
                           ;               
    }                       
   }
void display(unsigned int shu)   //数码管显示函数
{
int shi,ge;
shi=shu%100/10;
ge=shu%10;

  PORTB=0xfb;
  PORTD=table[shi];
  delay(5);

  PORTB=0xf7;
  PORTD=table[ge];
  delay(5);
}

void keyscan(void)
{
    if((PINC&(1<<PC0))==0)   //按键1判断
          {       
               delay(10);
                   if((PINC&(1<<PC0))==0)
                  {
                          num++;
                          while(!(PINC&(1<<PC0)));       
                  }
               
          }
}

void main(void)
{
DDRD=0XFF;       //端口初始化,D口是段选,B口是位选
PORTD=0Xff;
DDRB=0XFF;
PORTB=0Xff;
DDRC=0X01;
PORTC=0Xff;
PORTB=0x00;  //上电全亮
PORTD=0x3f;
while(1)
{
        keyscan();
        display(num);
}
}

                  

相关帖子

沙发
huangxz| | 2014-8-21 17:26 | 只看该作者
那是因为按键检测占的时间太多了

使用特权

评论回复
板凳
ddllxxrr| | 2014-8-21 19:15 | 只看该作者
while(1)
{
        keyscan();
        display(num);
}

这个太快,加些延时,也就是说你点亮一下不动,它就不会闪,原因是你动得太快了

使用特权

评论回复
地板
liuhuonihao|  楼主 | 2014-8-22 11:22 | 只看该作者
huangxz 发表于 2014-8-21 17:26
那是因为按键检测占的时间太多了

是的,我在按键按下的地方都加数码管扫描就解决了,还有用定时器对数码管扫描都行

使用特权

评论回复
5
ningling_21| | 2014-8-23 09:13 | 只看该作者
liuhuonihao 发表于 2014-8-22 11:22
是的,我在按键按下的地方都加数码管扫描就解决了,还有用定时器对数码管扫描都行 ...

不错的方法

使用特权

评论回复
6
qq4988| | 2014-8-24 12:40 | 只看该作者
是的,就你的程序来说,你在按键扫描那里,当按键按下后,等待抬起的死循环那里,加上一句显示处理,就可以了

使用特权

评论回复
7
LBS18| | 2014-11-1 11:03 | 只看该作者
按键用扫描检测,不要占用过多机器时间应该可以!

使用特权

评论回复
8
dxj520ly| | 2014-11-11 16:39 | 只看该作者
不能再这样学下去了,按键也廷时显示也廷时这是大学的错啊,继续下去永远做不了工程师,建议百度学习状态机编程,

使用特权

评论回复
9
luobiyige| | 2015-2-11 21:22 | 只看该作者
其实这个问题我认为是这样,你数码管显示是动态扫描,数据更新的时候有两种情况:1、先选通对应的数码管,再对段选口更新数据;2、先对段选口更新数据,再选通对应的数码管。如果是情况1,选通数码管,更新数据,那么你选通十位的时候,你段选端的数据对应的是个位的( PORTB=0xfb;PORTD=table[shi];delay(5); PORTB=0xf7; PORTD=table[ge]; delay(5);}),这个时候就出现了误码,现象上看就是有闪烁。注明:亮灭的闪烁小于十分之一秒是看不出来的,但是误码即使再快也能看出来,因给不同的段产生了亮灭。你这个就属于对一种情况。要是你按2的方式来完成,下更新数据,在选通对应的数码管,即;PORTD=table[shi];PORTB=0xfb;个位i就会出现闪烁。好的方法应该是3:即所有的数码管都不选通然后更新对应数码管的数据,最后选通对应的数码管。程序应该为PORTB=0xff;PORTD=table[shi];PORTB=0xfb;...................是不是这样呢?

使用特权

评论回复
10
luobiyige| | 2015-2-11 21:26 | 只看该作者
qq4988 发表于 2014-8-24 12:40
是的,就你的程序来说,你在按键扫描那里,当按键按下后,等待抬起的死循环那里,加上一句显示处理,就可以 ...

要你那种情况就不是十位闪烁了,整体表现是数码管变暗或这是整体闪烁

使用特权

评论回复
11
qq4988| | 2015-2-12 08:31 | 只看该作者
luobiyige 发表于 2015-2-11 21:26
要你那种情况就不是十位闪烁了,整体表现是数码管变暗或这是整体闪烁

这么长时间了,还没弄出来吗?显示不能送的太频繁,你按按键的时间不要太长,应该会好一些吧

使用特权

评论回复
12
一颗心的思考| | 2015-2-12 23:41 | 只看该作者
dxj520ly 发表于 2014-11-11 16:39
不能再这样学下去了,按键也廷时显示也廷时这是大学的错啊,继续下去永远做不了工程师,建议百度学习状态机 ...

正解。有一种方法,把按键处理放到外部中断里头,这种以前用的蛮好,不知道兄台有何高见,求拍砖。还有,状态机的话,万一主程序没扫描到,错过了定时中断的时间片咋整?

使用特权

评论回复
13
dxj520ly| | 2015-2-13 09:28 | 只看该作者
一般中断只做标志功能,比如按键处理只是在中断里做一个按键的标志,主程序有扫描到按键标志则处理之,中断尽量不要做任务或工作(除非响应非常高的)只是做一些相关的标志,所有任务工作还是由主程序来完成。
比如按键的处理,有按键则在中断做一个标志,主程序检测到标志执行后并清除该标志,
LED扫描显示,在定时扫描中断内循环改变段显示标志,主程序检测根据每段需要显示的标志而显示相应的段数据。

使用特权

评论回复
14
一颗心的思考| | 2015-2-13 14:14 | 只看该作者
dxj520ly 发表于 2015-2-13 09:28
一般中断只做标志功能,比如按键处理只是在中断里做一个按键的标志,主程序有扫描到按键标志则处理之,中断 ...

主程序若是执行的事情比较多,(若是里面加了延时)不能够及时的响应按键,这种情况怎么处理呢?

使用特权

评论回复
15
dxj520ly| | 2015-3-2 09:46 | 只看该作者
一颗心的思考 发表于 2015-2-13 14:14
主程序若是执行的事情比较多,(若是里面加了延时)不能够及时的响应按键,这种情况怎么处理呢? ...

按键的实际有效时间一般都是30MS以上,因此对于单片机而然这个时间是很长的了,当然如果执行的事情多做不过来可以提高单片机的频率来加快每个事情所占用的时间,如果主程序有加廷时那就需要将所加的廷时功能改为用计时状态机来处理代替,主程序由于廷时而不能及时响应功能模块是不对的。

使用特权

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

本版积分规则

13

主题

31

帖子

0

粉丝