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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2711|回復: 4
打印 上一主題 下一主題
收起左側

單片機按鍵消抖有反應,但是仿真的時候數碼管顯示亂抖

[復制鏈接]
跳轉到指定樓層
樓主
#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)

這是我的電路圖

這是我的電路圖
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:447891 發表于 2019-6-9 10:14 | 只看該作者
請大家幫忙看一下按鍵消抖和按鍵功能模塊那里哪里出錯了
回復

使用道具 舉報

板凳
ID:332444 發表于 2019-6-9 20:02 | 只看該作者
幾個按鍵實現什么功能?請說清楚。
回復

使用道具 舉報

地板
ID:294235 發表于 2019-6-9 20:07 來自手機 | 只看該作者
消抖的時間?
回復

使用道具 舉報

5#
ID:517466 發表于 2019-6-9 23:29 | 只看該作者
按鍵掃描放定時器處理里,顯示處理倒是放在了主循環處理中了?感覺邏輯挺奇怪的。一般鍵盤掃描在主循環中做啊。消除抖動的處理邏輯一般是:判斷按鍵是否按下?是,則延遲20ms后再次檢查是不是這個按鍵被按下。是則繼續檢測按鍵是否松開,是則表示一次完整的按鍵按下和松開。松開那部分也可以不做,主要是避免速度太快,按下還沒有松開時,相同處理被多次執行。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩在线视频一区二区三区 | 国产精品久久久久一区二区三区 | 久久久www成人免费无遮挡大片 | 亚洲免费视频一区 | 久久不卡 | 男女羞羞视频在线 | 亚洲一区日韩 | 亚洲精品久久久久久宅男 | 懂色av一区二区三区在线播放 | 亚洲美女网站 | 国产视频福利一区 | 亚洲网站免费看 | 91成人免费看片 | 国产一级毛片视频 | 精品一区二区三区四区外站 | 久久免费观看一级毛片 | 911精品美国片911久久久 | 犬夜叉在线观看 | 性欧美精品一区二区三区在线播放 | 在线视频一区二区 | 一区二区三区四区免费观看 | 91精品一区二区三区久久久久久 | 中文字幕精品一区久久久久 | 性色av一区二区三区 | 日韩欧美在线视频一区 | 欧美日在线 | 亚洲国产精品激情在线观看 | 成人在线视频网站 | 4h影视 | 性生生活大片免费看视频 | 极品电影院 | 97视频久久 | 欧美日韩在线免费观看 | 一区二区三区欧美在线 | 欧美在线一区二区三区四区 | 国产精品美女久久久久久久网站 | 成人精品视频在线观看 | 日韩在线视频一区二区三区 | 国产精品久久久久久久久久久久久 | 欧美亚洲一区二区三区 | 影音先锋男 |