欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2915|回復(fù): 10
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)按鍵反應(yīng)太慢,感覺是延時(shí)函數(shù)太多,如何改中斷法

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1099999 發(fā)表于 2023-12-6 15:24 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
/***************************************************************************************/

#include "reg52.h"                         //此文件中定義了單片機(jī)的一些特殊功能寄存器
#include "ds1302.h"
#include "temp.h"
#include "lcd.h"
#include "eeprom.h"

sbit k1 = P3^0;                          //按鍵
sbit k2 = P3^1;                        
sbit k3 = P3^2;
sbit k4 = P3^3;

sbit lcdled = P2^4;                          //lcd背光
sbit beep = P1^4;                        //蜂鳴器

unsigned int ti=0,alarm=0;       //修改第幾個(gè)時(shí)間參數(shù) 、修改第幾個(gè)鬧鐘參數(shù)
unsigned char alarm_hour=0x12,alarm_min=0x00;         //鬧鐘時(shí)、分參數(shù)

enum Mode                                //定義枚舉、三種模式
{
        DISPLAYDATA,MODIFYDATA,SETALARMCLOCK,NONE,ALARMCLOCK
}mode;

enum Alarmswitch         //定義鬧鐘開關(guān)
{
        OFF,ON
}alarmswitch;

/*********延時(shí)函數(shù)***********/                  
void delay(unsigned int t)         //短延時(shí)
{
         while(t--);
}
void delay_ms(unsigned int t)        //毫秒延時(shí)
{
        unsigned int a,b;
        for(a=0;a<t;a++)
        for(b=0;b<120;b++);
}

/********顯示日期、時(shí)間、星期***********/
void display_data(void)
{
        LcdWriteCom(0x80);
        LcdWritestr("20");        
        LcdWriteData(TIME[6]/16+0x30);          //年
        LcdWriteData(TIME[6]%16+0x30);
        LcdWriteData('-');
        LcdWriteData(TIME[4]/16+0x30);          //月
        LcdWriteData(TIME[4]%16+0x30);
        LcdWriteData('-');
        LcdWriteData(TIME[3]/16+0x30);          //日
        LcdWriteData(TIME[3]%16+0x30);

        LcdWritestr("  ");
        switch(TIME[5])                                           //顯示星期
        {               
                case 0:LcdWritestr("Mon"); break;
                case 1:LcdWritestr("Tue"); break;
                case 2:LcdWritestr("Wed"); break;
                case 3:LcdWritestr("Thu"); break;
                case 4:LcdWritestr("Fri"); break;
                case 5:LcdWritestr("Sat"); break;
                case 6:LcdWritestr("Sun"); break;
        }
        if(alarmswitch==ON)LcdWriteData('.');
        else LcdWriteData(' ');

        LcdWriteCom(0xC0);
        LcdWriteData(' ');
        LcdWriteData(TIME[2]/16+0x30);          //時(shí)
        LcdWriteData(TIME[2]%16+0x30);
        LcdWriteData(':');
        LcdWriteData(TIME[1]/16+0x30);          //分
        LcdWriteData(TIME[1]%16+0x30);
        LcdWriteData(':');
        LcdWriteData(TIME[0]/16+0x30);          //秒
        LcdWriteData(TIME[0]%16+0x30);
        LcdWritestr(" ");
}

/*********顯示溫度***********/
void displaytemp(int temp)          //顯示溫度
{
           float tp;  
        if(temp< 0)                        
          {
                LcdWriteCom(0xca);
                LcdWriteData('-');
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;        

          }
         else
          {                        
                LcdWriteCom(0xca);
                LcdWriteData('+');
                tp=temp;
                temp=tp*0.0625*100+0.5;        
        }
        LcdWriteData(temp % 10000 / 1000 + 0x30);
        LcdWriteData(temp % 1000 / 100  + 0x30);
        LcdWriteData('.');
        LcdWriteData(temp % 100 / 10 + 0x30);
        LcdWriteData(temp % 10 + 0x30);
}


/*******************************************************************************
* 函 數(shù) 名         : keypros
* 函數(shù)功能                   : 按鍵處理函數(shù),判斷按鍵K1是否按下
*******************************************************************************/
void keypros()                   //初始頁面按鍵檢測(cè)
{
        if(k1 == 0)                           //切換模式
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k1==0)         //再次判斷按鍵是否按下
                {
                        mode+= 1;if(mode == 3)mode = DISPLAYDATA;
                }
                while(k1 == 0);
        }
        if(k2 == 0)                          //蜂鳴器測(cè)試
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k2==0)         //再次判斷按鍵是否按下
                {
                        beep = !beep;  
                }
                while(k2 == 0);
        }
        if(k3 == 0)                   //背光燈測(cè)試
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k3==0)         //再次判斷按鍵是否按下
                {
                        lcdled = !lcdled;  
                }
                while(k3 == 0);
        }
        if(k4 == 0)                        //背光燈測(cè)試
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k4==0)         //再次判斷按鍵是否按下
                {
                        alarmswitch=!alarmswitch;  
                }
                while(k4 == 0);
        }               
}

/*************修改時(shí)間************/
void modify(void)
{
        display_data();
        if(k1 == 0)                        //切換模式
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k1==0)         //再次判斷按鍵是否按下
                {
                        mode+= 1;if(mode == 3)mode = DISPLAYDATA;
                }

                while(k1 == 0);
        }
        if(k2 == 0)                   //選擇修改參數(shù)
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k2==0)         //再次判斷按鍵是否按下
                {
                        ti++;
                        if(ti == 8)ti=0;
                }
                while(k2 == 0);
        }
        
        switch(ti)                                   //選擇進(jìn)入修改參數(shù)
        {
                case 0:
                                                delay_ms(20);
                                                if(k4==0 | k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4==0 | k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[0]=0;
                                                        }
                                                        while(k4 == 0 | k3==0);
                                                }
                                                LcdWriteCom(0xc7);
                                                LcdWritestr("  ");
                                                break;    //?
                case 1:
                                                delay_ms(20);
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[1]++;
                                                           if(TIME[1]%16 == 0x0a)
                                                           {
                                                                           TIME[1] += 16;
                                                                        TIME[1] &= 0xf0;
                                                           }if(TIME[1]==0x60)TIME[1]=0;
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[1]--;
                                                           if(TIME[1]%16==0x0f && TIME[1]!=0xff)
                                                           {
                                                                        TIME[1] &= 0xf9;
                                                           }
                                                           if(TIME[1]==0xff)TIME[1]=0x59;
                                                        }
                                                        while(k4==0);
                                                }
                                                LcdWriteCom(0xc4);
                                                LcdWritestr("  ");
                                                break;    //?
                case 2:
                                                delay_ms(20);
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[2]++;
                                                           if(TIME[2]%16 == 0x0a)
                                                           {
                                                                           TIME[2] += 16;
                                                                        TIME[2] &= 0xf0;
                                                           }if(TIME[2]==0x24)TIME[2]=0;
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[2]--;
                                                           if(TIME[2]%16==0x0f && TIME[2]!=0xff)
                                                           {
                                                                        TIME[2] &= 0xf9;
                                                           }
                                                           if(TIME[2]==0xff)TIME[2]=0x23;
                                                        }
                                                        while(k4==0);
                                                }
                                                LcdWriteCom(0xc1);
                                                LcdWritestr("  ");
                                                break;    //?
                case 3:
                                                delay_ms(10);
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[3]++;
                                                           if(TIME[3]%16 == 0x0a)
                                                           {
                                                                           TIME[3] += 16;
                                                                        TIME[3] &= 0xf0;
                                                           }if(TIME[3]==0x32)TIME[3]=0;
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[3]--;
                                                           if(TIME[3]%16==0x0f && TIME[3]!=0xff)
                                                           {
                                                                        TIME[3] &= 0xf9;
                                                           }
                                                           if(TIME[3]==0xff)TIME[3]=0x31;
                                                        }
                                                        while(k4==0);
                                                }
                                                LcdWriteCom(0x88);
                                                LcdWritestr("  ");
                                                break;         //日
                case 4:
                                       
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[4]++;
                                                           if(TIME[4]%16 == 0x0a)
                                                           {
                                                                           TIME[4] += 16;
                                                                        TIME[4] &= 0xf0;
                                                           }if(TIME[4]==0x13)TIME[4]=0;
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[4]--;
                                                           if(TIME[4]%16==0x0f && TIME[4]!=0xff)
                                                           {
                                                                        TIME[4] &= 0xf9;
                                                           }
                                                           if(TIME[4]==0xff)TIME[4]=0x12;
                                                        }
                                                        while(k4==0);
                                                }
                                                LcdWriteCom(0x85);
                                                LcdWritestr("  ");
                                                break;         //月
                case 5:
                                                
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[5]++;if(TIME[5]==7)TIME[5]=0;
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[5]--;if(TIME[5]==0xff)TIME[5]=6;
                                                        }
                                                        while(k4==0);
                                                }
                                                LcdWriteCom(0x8c);
                                                LcdWritestr("   ");
                                                break;         //周
                case 6:
                                                
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[6]++;
                                                           if(TIME[6]%16 == 0x0a)
                                                           {
                                                                           TIME[6] += 16;
                                                                        TIME[6] &= 0xf0;
                                                           }if(TIME[6]==0xa0)TIME[6]=0;
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           TIME[6]--;
                                                           if(TIME[6]%16==0x0f && TIME[6]!=0xff)
                                                           {
                                                                        TIME[6] &= 0xf9;
                                                           }
                                                           if(TIME[6]==0xff)TIME[6]=0x99;
                                                        }
                                                        while(k4==0);
                                                }
                                                LcdWriteCom(0x80);
                                                LcdWritestr("    ");
                                                break;         //年
                case 7:
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           mode=DISPLAYDATA;
                                                           ti=0;
                                                        }
                                                        while(k3==0);
                                                }
                                                LcdWriteCom(0xca);
                                                LcdWritestr("      ");
                                                delay(100);
                                                LcdWriteCom(0xca);
                                                LcdWritestr("<- OK");
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                                   Ds1302Init();                  //時(shí)鐘初始化
                                                                mode = DISPLAYDATA;    //返回日期
                                                                ti = 0;                                //還原初始修改
                                                        }
                                                        while(k4==0);
                                                }
                                                break;         //年
        }        
}
void setalarmclock(void)        //設(shè)置鬧鐘模式
{
        alarm_hour=byte_read(0x2601);
        alarm_min=byte_read(0x2201);
        alarmswitch=byte_read(0x2401);
        LcdWriteCom(0x80);                         //顯示
        LcdWritestr("alarm clock:    ");
        LcdWriteCom(0xc0);
        if(alarmswitch == OFF)LcdWritestr("  OFF    ");
        else LcdWritestr("  ON     ");
        LcdWriteCom(0xc9);
        LcdWriteData(alarm_hour/16+0x30);
        LcdWriteData(alarm_hour%16+0x30);
        LcdWriteData(':');
        LcdWriteData(alarm_min/16+0x30);
        LcdWriteData(alarm_min%16+0x30);
        LcdWritestr("    ");
        
        if(k1 == 0)                         //切換模式
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k1==0)         //再次判斷按鍵是否按下
                {
                        mode+= 1;if(mode == 3)mode = DISPLAYDATA;
                }

                while(k1 == 0);
        }
        if(k2 == 0)                         //選擇鬧鐘修改參數(shù)
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k2==0)         //再次判斷按鍵是否按下
                {
                        alarm++;
                        if(alarm == 3)alarm=0;
                }
                while(k2 == 0);
        }
        switch(alarm)                        //選擇進(jìn)入修改參數(shù)
        {
                case 0:
                                LcdWriteCom(0xc0);
                                LcdWritestr("      ");
                                if(k3 == 0)                          //控制鬧鐘開
                                {
                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                        if(k3==0)         //再次判斷按鍵是否按下
                                        {
                                                alarmswitch = ON;
                                                SectorErase(0x2401);
                                                byte_write(0x2401,alarmswitch);
                                        }
                                        while(k3 == 0);
                                }
                                if(k4 == 0)                         //控制鬧鐘關(guān)閉
                                {
                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                        if(k4==0)         //再次判斷按鍵是否按下
                                        {
                                                alarmswitch = OFF;
                                                SectorErase(0x2401);
                                                byte_write(0x2401,alarmswitch);
                                        }
                                        while(k4 == 0);
                                }
                                break;
                case 1:        
                                delay_ms(10);
                                                                                                
                                                if(k3==0)                  //控制鬧鐘時(shí)針加
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           alarm_hour++;
                                                           if(alarm_hour%16 == 0x0a)
                                                           {
                                                                           alarm_hour += 16;
                                                                        alarm_hour &= 0xf0;
                                                           }if(alarm_hour==0x24)alarm_hour=0;
                                                            SectorErase(0x2601);
                                                                byte_write(0x2601,alarm_hour);
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)                          //控制鬧鐘時(shí)針減
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           alarm_hour--;
                                                           if(alarm_hour%16==0x0f && alarm_hour!=0xff)
                                                           {
                                                                        alarm_hour &= 0xf9;
                                                           }
                                                           if(alarm_hour==0xff)alarm_hour=0x23;
                                                           SectorErase(0x2601);
                                                           byte_write(0x2601,alarm_hour);
                                                        }
                                                        while(k4==0);
                                                }
                                                LcdWriteCom(0xc9);
                                                LcdWritestr("  ");
                                break;
                case 2:
                                delay_ms(10);
                                
                                                if(k3==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k3 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           alarm_min++;
                                                           if(alarm_min%16 == 0x0a)
                                                           {
                                                                           alarm_min += 16;
                                                                        alarm_min &= 0xf0;
                                                           }if(alarm_min==0x60)alarm_min=0;
                                                           SectorErase(0x2201);
                                                           byte_write(0x2201,alarm_min);
                                                        }
                                                        while(k3==0);
                                                }
                                                if(k4==0)
                                                {
                                                        delay(1000);   //消除抖動(dòng) 一般大約10ms
                                                        if(k4 ==0)         //再次判斷按鍵是否按下
                                                        {
                                                           alarm_min--;
                                                           if(alarm_min%16==0x0f && alarm_min!=0xff)
                                                           {
                                                                        alarm_min &= 0xf9;
                                                           }
                                                           if(alarm_min==0xff)alarm_min=0x59;
                                                           SectorErase(0x2201);
                                                           byte_write(0x2201,alarm_min);
                                                        }
                                                        while(k4==0);
                                                }
                                LcdWriteCom(0xcc);
                                LcdWritestr("  ");
                                break;
        }

}

/************鬧鐘模式*****************/
void alarmclock(void)
{
    if(alarmswitch==ON && alarm_hour==TIME[2] && alarm_min==TIME[1])  //鬧鐘
        {                        
                beep=0;
                delay_ms(100);
                beep=1;
                delay_ms(100);  
                beep=0;
                delay_ms(100);
                beep=1;
                LcdWriteCom(0x80);
                LcdWritestr("   time out!    ");
                LcdWriteCom(0xc0);
                LcdWritestr("now time: ");
                LcdWriteData(alarm_hour/16+0x30);
                LcdWriteData(alarm_hour%16+0x30);
                LcdWriteData(':');
                LcdWriteData(alarm_min/16+0x30);
                LcdWriteData(alarm_min%16+0x30);
                LcdWritestr("    ");
                delay_ms(500);
                LcdClean();        
        }
        else mode=DISPLAYDATA;
        if(k4==0)
        {
                delay(1000);   //消除抖動(dòng) 一般大約10ms
                if(k4 ==0)         //再次判斷按鍵是否按下
                {
                         alarmswitch=OFF;
                }
                while(k4==0);
        }      
}
/*******************************************************************************
* 函 數(shù) 名         : main
* 函數(shù)功能                   : 主函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void main(void)
{
        int ucount=0;
        LcdInit();                         //lcd初始化
        //Ds1302Init();                  //時(shí)鐘初始化
        Ds18b20Init();                  //溫度傳感器初始化
        SectorErase(0x2001);
//        byte_write(0x2001,0x08);           //執(zhí)行一遍初始化
//        byte_write(0x2201,0x00);
//        byte_write(0x2401,0x00);
        alarm_hour=byte_read(0x2601);
        alarm_min=byte_read(0x2201);
        alarmswitch=byte_read(0x2401);

        while(1)               
        {
                switch(mode)        //模式選擇
                {
                        case DISPLAYDATA:                //時(shí)間顯示模式
                                Ds1302ReadTime(); //更新時(shí)間
                                display_data();                  //顯示時(shí)間          秒分時(shí)日月周年
                                displaytemp(Ds18b20ReadTemp());//顯示溫度
                                   keypros();                                 //按鍵檢測(cè)
                                if(alarmswitch==ON && alarm_hour==TIME[2] && alarm_min==TIME[1])  //鬧鐘
                                {
                                        mode = ALARMCLOCK;
                                }
                                break;
                        case MODIFYDATA:                          //時(shí)間修改模式
                                modify();
                                break;
                        case SETALARMCLOCK:                           //設(shè)置鬧鐘模式
                                setalarmclock();
                                break;
                        case ALARMCLOCK:                           //鬧鐘模式
                                alarmclock();
                                break;
                }
               
        }                                
}




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:161164 發(fā)表于 2023-12-7 09:33 | 只看該作者
就算是用中斷,該慢的還是會(huì)慢
按你貼的代碼來看,主要耗時(shí)在LCD1602的顯示
1602的顯示不用一直刷新,可以在數(shù)據(jù)有變時(shí)再刷或定時(shí)(100ms)去刷
而且正常全刷一次都只需2ms
懷疑你的1602驅(qū)動(dòng)代碼延時(shí)太長
回復(fù)

使用道具 舉報(bào)

板凳
ID:491577 發(fā)表于 2023-12-7 13:02 | 只看該作者
開發(fā)板上的程序只是用來學(xué)習(xí)原理的,實(shí)際編程是不用的,實(shí)用的按鍵掃描程序最好是放在定時(shí)器中斷里,中斷的時(shí)間是有要求的,必須大于等于10ms,只要大于10ms就不用考慮消抖問題(原理自己百度),延時(shí)語句,while(k4==0);都不需要。參考一下我寫的按鍵掃描程序:
http://www.raoushi.com/bbs/dpj-208253-1.html
回復(fù)

使用道具 舉報(bào)

地板
ID:712097 發(fā)表于 2023-12-7 14:26 | 只看該作者
還是中斷法按鍵處理最快,方法很簡單,設(shè)置外部中斷觸發(fā)方式(上升沿/下降沿等),開總中斷,然后在外部中斷函數(shù)做按鍵處理。
回復(fù)

使用道具 舉報(bào)

5#
ID:332444 發(fā)表于 2023-12-8 07:34 | 只看該作者
如果看了我的帖子和回復(fù),采用我的詢問式方法就不會(huì)有這樣問題和提問,也不會(huì)想用中斷.
回復(fù)

使用道具 舉報(bào)

6#
ID:628113 發(fā)表于 2023-12-8 10:39 | 只看該作者
按鍵有三種處理方式:
查詢, 中斷, 偽中斷 。
理論上 中斷 最好, 因?yàn)轫憫?yīng)最及時(shí), 但也是出問題最多的方式。

中斷為何出問題多,這里簡單說個(gè)例子:
低速的MCU , 例如 STM8L , 程序不斷讀取 DS18B20 的溫度并顯示。
讀取18B20時(shí)不關(guān)中斷, 不停按鍵鐵定讀出錯(cuò)誤;關(guān)中斷,又影響按鍵的實(shí)時(shí)性。

查詢法幾乎不會(huì)出問題,對(duì)其他應(yīng)用沒有啥影響。就是反應(yīng)遲鈍。

我現(xiàn)在用的最多的是偽中斷。 就是在1ms 的定時(shí)器中斷中處理 按鍵, 同時(shí)也能完美解決抖動(dòng)延時(shí)。
發(fā)現(xiàn)按鍵后, 置位標(biāo)志, 然后按需處理。緊急的話立即處理, 不急就在主循環(huán)有空處理。很靈活。

實(shí)際定時(shí)中斷里面的代碼是這樣的:
      if(IT_GetTimer(_KEY_UP)>=KEY_PRESS_DELAY &&  KEY_UP_IN==0) {IT_ClrTimer(_KEY_UP);        IT_SetKey(_KEY_UP, 1);}  // 1=up 2=ok 3=dn
      if(IT_GetTimer(_KEY_OK)>=KEY_PRESS_DELAY &&  KEY_OK_IN==0) {IT_ClrTimer(_KEY_OK);        IT_SetKey(_KEY_OK, 1);}  // 1=up 2=ok 3=dn
      if(IT_GetTimer(_KEY_DN)>=KEY_PRESS_DELAY &&  KEY_DN_IN==0) {IT_ClrTimer(_KEY_DN);        IT_SetKey(_KEY_DN, 1);} // 1=up 2=ok 3=dn       

一家之言, 供大家參考。
回復(fù)

使用道具 舉報(bào)

7#
ID:1034262 發(fā)表于 2023-12-8 11:26 | 只看該作者
一個(gè)軟件延時(shí)都不要用(除非是剛開始的初始化)。
回復(fù)

使用道具 舉報(bào)

8#
ID:72088 發(fā)表于 2023-12-8 15:51 | 只看該作者
我開始也是用普通延時(shí)方式判斷按鍵,的確慢,現(xiàn)實(shí)用定時(shí)掃描判斷按鍵,靈敏準(zhǔn)確迅速,無延時(shí)程序
回復(fù)

使用道具 舉報(bào)

9#
ID:517951 發(fā)表于 2023-12-9 16:55 | 只看該作者
在定時(shí)器中斷服務(wù)程序中, 加入按鍵掃碼代碼, 定時(shí)器設(shè)置為1ms中斷. 10或者15次讀到按鍵為低,即為有效, 設(shè)置標(biāo)志位. 然后在主循環(huán)中根據(jù)標(biāo)識(shí)位執(zhí)行按鍵后的動(dòng)作. 這樣按鍵就非常靈敏,且不會(huì)死循環(huán)20ms. 20ms單片機(jī)可以做很多事情的.
回復(fù)

使用道具 舉報(bào)

10#
ID:190577 發(fā)表于 2023-12-9 17:20 | 只看該作者
可以用狀態(tài)機(jī)
回復(fù)

使用道具 舉報(bào)

11#
ID:1103540 發(fā)表于 2023-12-10 15:55 | 只看該作者
按鍵消抖方式太落后,加了延遲,建議抄別人比較成熟的按鍵掃描方式,定時(shí)器掃描之類比較好用
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表