久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 單片機按鍵消抖有反應,但是仿真的時候數碼管顯示亂抖 [打印本頁]

作者: skcxks    時間: 2019-6-9 10:14
標題: 單片機按鍵消抖有反應,但是仿真的時候數碼管顯示亂抖
#include<reg51.h>
#include<intrins.h>
#include<ctype.h>
#include<string.h>
#include<math.h>
#include<stdio.h>


#define uchar unsigned char
#define uint unsigned int
#define key_group P1

uint time=0;
uint ss=00;
uint key_time;

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共陽極0-9的段碼
uchar key,key_temp,state_key;



int clock=0;   //時鐘初值,默認為0
int coundown=60; //倒計時,默認60s
int kaiji=0;  //上電后進行時鐘的設置
char num_show[4];
int show_num=0;
int up=0;  //按鍵松開
int choose_num=0;
int state=0;
int count_state=0;
int count=0;
int num1=0,num2=0;
int result=0,add_state=0;
int stopwatch_state=0;
int clock_time=0,clock_ss=0;
int mm=0;

void Display();
void Type();
void anjian4();
void anjian3();
void anjian2();
void anjian1();
void jiafa();
void shizhong();
void miaobiao();
void daojishi();
void keyscan();

void main()
{
                        num_show[0]=clock/60/10;
                        num_show[1]=clock/60%10;
                        num_show[2]=clock%60/10;
                        num_show[3]=clock%60%10;
        TMOD=0x01;//計時器0以工作方式1計時
        EA=1;//打開全局中斷允許
        ET0=1;//打開定時器0中斷允許位
        TR0=1;//啟動定時器0
        TH0=(65535-1000)/256;    //定時器初值  1ms
        TL0=(65535-1000)%256;
        
        while(1)
        {
                Display();         
        }
}




void ET_T0() interrupt 1
{
        TH0=(65535-1000)/256;    //定時器初值  1ms
        TL0=(65535-1000)%256;
        show_num++;
        if(show_num>7)
                show_num=0;
        key_time++;
        keyscan();
        if(kaiji==2)   //兩個初值都設置完畢
        {
  anjian1();
  }
  anjian3();
  anjian2();
        anjian4();
        if(count_state==1)  //倒計時的狀態變量
        {
         daojishi();
        }
        if(stopwatch_state==1)  //秒表的狀態變量
        {
                miaobiao();
        }                        
        if(kaiji==2)
        {
    shizhong();
        }
}




void Display(void)
{
switch(show_num)
{
        case 0:
                        
                                 P2=0XF0;
              P0=table[num_show[0]];
                                break;
        case 1:
               P0=table[num_show[0]];
              P2=0XF1;
                          break;
        case 2:
                         P2=0XF0;
             P0=table[num_show[1]];
                         break;
  case 3:        
              P0=table[num_show[1]];
              P2=0xF2;
                          break;
  case 4:
                         P2=0XF0;
             P0=table[num_show[2]];
                         break;
  case 5:        
             P0=table[num_show[2]];
             P2=0xF4;
                         break;
        case 6:
                                P2=0XF0;
              P0=table[num_show[3]];
                                break;
        case 7:
              P0=table[num_show[3]];
              P2=0xF8;
              break;
        default:break;
}
}

void Type(void)
{
switch(state)
  {
         case 0:  //時鐘模式
                                count_state=0;
                                stopwatch_state=0;
                                num_show[0]=clock/60/10;
                                num_show[1]=clock/60%10;
                                num_show[2]=clock%60/10;
                                num_show[3]=clock%60%10;                                
              break;
         case 1: //加法模式
                                count_state=0;
                                stopwatch_state=0;
                                choose_num=0;
                                num_show[0]=num1/1000;
                                num_show[1]=num1%1000/100;
                                num_show[2]=num1%100/10;
                                num_show[3]=num1%10;                                
                          break;
          case 2: //倒計時模式
                                count_state=0;
                                stopwatch_state=0;
                                time=0;
                                ss=0;
                                num_show[0]=coundown/1000;
                                num_show[1]=coundown%1000/100;
                                num_show[2]=coundown%100/10;
                                num_show[3]=coundown%10;                                
                          break;
                        case 3:  //秒表模式
                                count_state=0;
                                stopwatch_state=0;
                                time=0;
                                ss=0;
                                num_show[0]=ss/1000;
                                num_show[1]=ss%1000/100;
                                num_show[2]=ss%100/10;
                                num_show[3]=ss%10;                                
                          break;
      default:break;
        }
}




void keyscan(void)
{
switch(state_key)
{
  case 0:
                key_temp=(key_group&0x0f);
          if(key_temp!=0x0f)
                 {
                  key_time=0;
                        state_key=1;
                 }
  break;
        case 1:if(key_time>=1000)
               {
                                 if(key_temp==0x0f)
                                  {
                                         state_key=0;
                                        }
                                 else
                                 {
                                        state_key=2;
                                  break;
                                        }
                                 }
                                 break;
        case 2:if(key_temp==0x0e)
                    {key=1;}
                                 else if(key_temp==0x0d)
                                      {key=2;}
                                 else if(key_temp==0x0b)
                                      {key=3;}
                                 else if(key_temp==0x07)
                                      {key=4;}
                                 else
                                 {
                                  key_temp=0x0f;
                                        state_key=0;
                                        key=0;
                                        break;
                                 }
         state_key=3;
                                 break;
        case 3:if((key_group&0x0f)==0x0f)
               {
                                  key_temp=0x0f;
                                  state_key=0;
                                 }
         break;
}
}




void anjian4(void)
{
if(key==4)  //切換數字|等于按鍵/倒計時,秒表開始暫停按鍵
        {
                if(kaiji==0)
                {
                        kaiji=1;
                        choose_num=0;
                        if((num_show[0]*10+num_show[1])<=23&&num_show[2]*10+num_show[3]<=59)  //小于23:59
                                 clock=(num_show[0]*10+num_show[1])*60+num_show[2]*10+num_show[3];   //不然還是默認值
                        
                        num_show[0]=coundown/1000;
                        num_show[1]=coundown%1000/100;
                        num_show[2]=coundown%100/10;
                        num_show[3]=coundown%10;                        
                }
                else if(kaiji==1)
                {
                        kaiji=2;
                        choose_num=0;
              coundown=num_show[0]*1000+num_show[1]*100+num_show[2]*10+num_show[3];
      //開始時鐘
                        num_show[0]=clock/60/10;
                        num_show[1]=clock/60%10;
                        num_show[2]=clock%60/10;
                        num_show[3]=clock%60%10;                              
                }
                if(state==2)  //倒計時
                {
                        if(count_state==0)
                        {
                                count_state=1;    //開始
                        }
                        else
                        {
                                count_state=0;   //暫停
                        }
                }
                else if(state==3)  //秒表
                {
                        if(stopwatch_state==0)
                        {
                                stopwatch_state=1;    //開始
                        }
                        else
                        {
                                stopwatch_state=0;   //暫停
                        }
                }
                else if(state==1)  //加法
                {
                        jiafa();
                }
        }
}


void anjian3()
{
        if(key==3)  //切換數碼管按鍵||秒表清零鍵||倒計時復位鍵
        {
                up=1;
                if(kaiji<=1||state==1)
                {
                        choose_num++;
                        if(choose_num>=4)
                                choose_num=0;
                }
                if(state==2)
                {
                        if(count_state==0)
                        {
                                num_show[0]=coundown/1000;
                                num_show[1]=coundown%1000/100;
                                num_show[2]=coundown%100/10;
                                num_show[3]=coundown%10;                                
                                ss=0;
                                time=0;
                        }
                }
                if(state==3)
                {
                        if(stopwatch_state==0)
                        {
                                ss=0;
                                num_show[0]=ss/1000;
                                num_show[1]=ss%1000/100;
                                num_show[2]=ss%100/10;
                                num_show[3]=ss%10;                                
                                
                                time=0;
                        }
                }
        }
}


void anjian2(void)
{
        if(key==2)  //加1鍵
        {
                if(kaiji<=1||state==1)
                {
                        if(num_show[choose_num]<9)
                        {
                                num_show[choose_num]++;
                        }
                        else
                                num_show[choose_num]=0;
                }
        }
}



void anjian1(void)
{
                if(key==1)   //模式切換按鍵
                {
                        state++;
                        Type();
                        if(state>3)
                        state=0;
                }
}



/**************加法模塊***************/
void jiafa()
{
      add_state++;
                        if(add_state==1)
                        {
                                num1=num_show[0]*1000+num_show[1]*100+num_show[2]*10+num_show[3];
                                choose_num=0;   //位選歸0
                                        num_show[0]=num2/1000;
                                        num_show[1]=num2%1000/100;
                                        num_show[2]=num2%100/10;
                                        num_show[3]=num2%10;                                
                        }
                        if(add_state==2)  //計算結果
                        {
                                num2=num_show[0]*1000+num_show[1]*100+num_show[2]*10+num_show[3];
                                result=num1+num2;
                                if(result<=9999)
                                {
                                        num_show[0]=result/1000;
                                        num_show[1]=result%1000/100;
                                        num_show[2]=result%100/10;
                                        num_show[3]=result%10;                                       
                                }
                                else
                                {
                                        num_show[0]=9999/1000;
                                        num_show[1]=9999%1000/100;
                                        num_show[2]=9999%100/10;
                                        num_show[3]=9999%10;                                
                                }
                        }
                        if(add_state>=3)
                        {
                                add_state=0;
                                num1=0;
                                num2=0;
                                result=0;
                                choose_num=0;
                                num_show[0]=num1/1000;
                                num_show[1]=num1%1000/100;
                                num_show[2]=num1%100/10;
                                num_show[3]=num1%10;                                       
                        }
}


/*************時鐘模塊************/
void shizhong(void)
{
                clock_time++;
                if(clock_time>=1000) //1ms*1000=1s
                {
                        clock_time=0;
                        clock_ss++;
                        if(clock_ss>=60)
                        {
                                clock++;
                                clock_ss=0;
                                if(clock==1440)
                                        clock=0;
                                if(state==0)
                                {
                                 num_show[0]=clock/60/10;
                           num_show[1]=clock/60%10;
                           num_show[2]=clock%60/10;
                           num_show[3]=clock%60%10;
                                }
      }
    }
}



/*************秒表模塊*************/
void miaobiao(void)
{
time++;
                if(time==1000)  //1ms*1000=1s
                {
                        time=0;
                        if(ss!=9999)
                          ss++;
                        else
                                stopwatch_state=0;
                                num_show[0]=ss/1000;
                                num_show[1]=ss%1000/100;
                                num_show[2]=ss%100/10;
                                num_show[3]=ss%10;        
    }
}


/**********倒計時模塊**********/
void daojishi(void)
{
        time++;
                if(time==1000)  //1s
                {
                        if(ss!=coundown)
                          ss++;
                        else
                                count_state=0;
                        time=0;
                                num_show[0]=(coundown-ss)/1000;
                                num_show[1]=(coundown-ss)%1000/100;
                                num_show[2]=(coundown-ss)%100/10;
                                num_show[3]=(coundown-ss)%10;        
     }
}

捕獲.PNG (24.06 KB, 下載次數: 39)

這是我的電路圖

這是我的電路圖

作者: skcxks    時間: 2019-6-9 10:14
請大家幫忙看一下按鍵消抖和按鍵功能模塊那里哪里出錯了
作者: xianfajushi    時間: 2019-6-9 20:02
幾個按鍵實現什么功能?請說清楚。
作者: 佩西范    時間: 2019-6-9 20:07
消抖的時間?
作者: suncat0504    時間: 2019-6-9 23:29
按鍵掃描放定時器處理里,顯示處理倒是放在了主循環處理中了?感覺邏輯挺奇怪的。一般鍵盤掃描在主循環中做啊。消除抖動的處理邏輯一般是:判斷按鍵是否按下?是,則延遲20ms后再次檢查是不是這個按鍵被按下。是則繼續檢測按鍵是否松開,是則表示一次完整的按鍵按下和松開。松開那部分也可以不做,主要是避免速度太快,按下還沒有松開時,相同處理被多次執行。




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 81精品国产乱码久久久久久 | 成人免费视频观看 | 一本综合久久 | 国产在线视频一区二区董小宛性色 | 久久久久综合 | 91麻豆精品国产91久久久久久久久 | 日韩精品一区二区三区中文在线 | 九九在线视频 | 亚洲精品国产精品国自产在线 | 国产黄色麻豆视频 | 欧美成人自拍视频 | 国产精品综合一区二区 | 国产一区二区三区 | 日韩欧美一区二区三区免费观看 | 久久久激情视频 | 搞黄网站在线观看 | 国产欧美一区二区三区久久 | 久久成人一区二区三区 | 精品国产欧美一区二区三区不卡 | 91精品国产麻豆 | 日韩一区二区三区av | 亚洲小说图片 | 欧美成人二区 | 亚洲精品福利在线 | 久久久免费毛片 | 日本人爽p大片免费看 | 看av在线 | 日韩欧美在线视频观看 | 国产乱码精品一区二区三区中文 | 久久亚洲视频 | 东方伊人免费在线观看 | 中文字幕一区二区三区在线观看 | 中文字幕亚洲欧美日韩在线不卡 | 天天曰夜夜操 | 国产一级一级 | 久久久精品 | 精品日韩一区 | 成人免费日韩 | 亚洲精品视频免费观看 | 久久久久久国产精品mv | 国产成人福利在线 |