打印

求助大牛,程序按键不灵敏,响应慢

[复制链接]
5822|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gxcmeluopeng|  楼主 | 2013-5-27 23:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   这个程序调试好久了,还是没有成功,在这里求助一下论坛的大虾。程序实现的功能:流水灯流速分为三级,每隔5秒递增一级,级数用数码管显示。按键1为级数的递增,按键2为级数的递减,按键三为启动/停止。
   现在的问题是按键按下数码管显示正常,流水灯响应的速度慢、不灵敏。现在我把程序上传,希望能得到大虾的指点,在此谢谢了。
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit duan=P2^6; //段选
sbit wei =P2^7; //位选
sbit key1=P3^4;
sbit key2=P3^5;
sbit key3=P3^6;
uchar code dis[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管段码
uchar code tableLED[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};  //流水灯查表数据
uchar code speedcode[]={10,5,1}; //速度数据
uchar flag,flag1,t0,t1,num1,num2,num3,speed,i,ID;
uchar key_num;
uchar num2=0;
#define N_key  0
#define S_key  1

#define key_state_0 0
#define key_state_1 1
#define key_state_2 2

uchar read_key()
{
        static uchar key_state=key_state_0;
        uchar key_press,key_return=N_key;
        key_press=key1&key2&key3;
        switch(key_state)
        {
                case key_state_0:if(!key_press) key_state=key_state_1;
                break;
                case key_state_1:if(!key_press)
                                 {
                                                         if(key1==0)
                                                        {
                                                                key_num=1;
                                                        }
                                                        else if(key2==0)
                                                        {
                                                                key_num=2;
                                                        }
                                                        else if(key3==0)
                                                        {
                                                                key_num=3;
                                                        }
                                                        key_return=S_key;
                                                        key_state=key_state_2;
                                                 }
                                                 else
                                                 {
                                                         key_state=key_state_0;
                                                 }
                break;
                case key_state_2:if(key_press) key_state=key_state_0;
                break;
        }
        return key_return;
}
void delay(uint x)
{
        uint i,j;
        for(i=x;i>0;i--)
        for(j=110;j>0;j--);//延时
}
void init()//定时器初始化
{
        TMOD=0x11;
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;
        TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
        ET0=1;
        ET1=1;
        EA=1;
        TR0=1;
        TR1=1;
}
void init2()//定时器2初始化
{
        RCAP2H=(65536-45872)/256;
        RCAP2L=(65536-45872)%256;
        EA=1;
        ET2=1;
        TR2=1;
}
void display(uchar ID)//数码管显示函数
{
        duan=1;
        P0=dis[ID];
        duan=0;
        P0=0xff;
        wei=1;
        P0=0xfe;
        wei=0;
        delay(4);
}
void main()
{
        init();
        init2();
        while(1)
        {  
                if(flag)
                {
                        flag=0;
                        P1=tableLED;//流水灯
                        i++;
                        if(i==8)
                        {
                                i=0;
                        }
                        if(num1==5)
                        {
                                num1=0;       
                                num2++;
                                if(num2==3)
                                {
                                        num2=0;
                                }
                        }
               
                }
            display(num2+1);
        }
}
void timer0() interrupt 1
{
        uchar key;
        TR0=0;
        key=read_key();
        if(key_num==1)
        {       
                if(key==S_key)  //按键按下num2加1
                {
                    num2++;
                        if(num2==3)
                        {
                                num2=0;
                        }
                 }
         }
         if(key_num==2)
         {
                if(key==S_key)//按键按下num2减1
                {
                        num2--;
                        if(num2==-1)
                        {
                           num2=2;
                        }
            }
         }
         if(key_num==3)
         {
                if(key==S_key)
                {
                        TR2=~TR2;//启动和关闭定时器2
                        TR1=~TR1;//启动和关闭定时器1;
                }
         }
         TR0=1;
         TH0=(65536-1000)/256;
         TL0=(65536-1000)%256;
}
void timer1() interrupt 3
{
        TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
        t1++;
        if(t1==20)          //定时1秒
        {
                t1=0;
                num1++;
        }
}
void timer2() interrupt 5
{
        TF2=0;
        t0++;
        if(t0==speedcode[num2])
        {
                t0=0;
                flag=1;
        }
} 小综合.rar (1.18 KB)

相关帖子

沙发
金则立则翔| | 2013-5-28 13:25 | 只看该作者
按键没有消抖啊

使用特权

评论回复
板凳
kagaobin| | 2013-5-29 09:21 | 只看该作者
(1)从void timer0() interrupt 1里来看
按住某个按键是不是得进入好几次中断,并执行对应的按键操作多次并且停在最后的结果里。人手按下一次按键至少是要十几ms,在单片机看来其实是等于按住很长的一段时间。
(2)在开头定义了全局变量无符号字符型 uchar num2=0;  在中断的判断里却出现了负数等式 if(num2==-1),无符号的num2=0时再做减1操作,结果是256-1=255;


使用特权

评论回复
地板
gaoyuaug| | 2013-5-29 15:53 | 只看该作者
流水灯是怎么响应的?

使用特权

评论回复
5
十十一由八| | 2013-5-30 22:03 | 只看该作者
是不是那些应用的程序不该加的加上去,也会影响的,以前我在PLC的时候也会出现逆的情况!

使用特权

评论回复
6
十十一由八| | 2013-5-30 22:03 | 只看该作者

使用特权

评论回复
7
lbr_gao| | 2013-5-30 23:43 | 只看该作者
首先,按键后没有消抖处理
算法上,0定时器判断是否按键的read函数完全可以放在主while中
像你写中断,按键下去的时候,定时器0可能没走完,这样就进不了中断,于是就无法判断按键。
感觉这两个定时器用的没意思,不如写子程序或函数效率来得更高。
纯属个人意见

使用特权

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

本版积分规则

4

主题

5

帖子

1

粉丝