找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機按鍵異常的不靈敏,求各位大佬指教程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:950769 發(fā)表于 2022-8-30 22:49 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
單片機主程序:
#include "reg52.h"   
#include <intrins.h>   
#include<OLED.h>
#include "key.h"
#include"delay.h"
#include"show_num.h"
#include"light.h"

#define uchar unsigned char
#define uint unsigned int

uint key_scan();
void light_time();
void Math_Distance(uint distance);

sbit echo = P2^7;           
sbit trig = P2^3;                                                                              
sbit beep = P2^4;


bit flag = 0;                   //測量成功標(biāo)志位全局參定義
uint time_H,time_L;           //暫存值,只用來存儲定時器的高低八位返回數(shù)值
uint time;                           //時間
uint max=2,min=1;                //單位為米

uint cm_table1[2]={0,0};
uint cm_table2[2]={0,0};          //儲存距離參數(shù)的數(shù)組
uint maxnum[2]={0,0};
uint minnum[2]={0,0};

void main()
{
        uint distance = 0;        //參數(shù):距離
        uint save = 0;                //參數(shù):(上一次的)距離保存。用于修正錯誤值
        uint i = 5;

        beep=0;                                //蜂鳴器上電后不響
        delay(1000);  
        OLED_Init();             // OLED初始化
        OLED_Fill(0x00);   
        trig = 0;                   //先關(guān)觸發(fā)信號               //指示燈

        while(1)
        {
     TMOD = 0x10;           //開定時器1-> 0001_0000  16位工作方式
         TH1 = 0;                   //定時器高八位初填裝值清空
         TL1 = 0;                    //定時器低八位初填裝值清空
         
         TF1=0;                           //T1溢出中斷標(biāo)志位。可自動由硬件至高/清零
         ET1 = 0;                   //T1中斷使能
         EA = 1;                   //開總中斷

         flag = 0;                   //標(biāo)志位清0
         trig = 1;                   //給觸發(fā)信號
         delay_20us();           //等那么一小段時間
         trig = 0;                   //關(guān)觸發(fā)信號  ————這樣就給了一小段高電平觸發(fā)信號,以至于不會一直觸發(fā)

         while(!echo);           //等待接收端出現(xiàn)高電平(如果是低,那就一直等)
         TR1 = 1;                   //T1運行控制位,開始計時
         while(echo);           //等待高電平結(jié)束(如果是高,那就一直等)
         TR1 = 0;                   //關(guān)定時器T1
         
         time_H = TH1;           //把T1的高低八位定時數(shù)據(jù)取出
         time_L = TL1;           //        ↑
         
          if(flag == 0)                //如果測距成功
        {
          time=time_H*256+time_L;        //將定時器的高低八位返回值賦給時間參數(shù)time
          distance = time*0.173;        //來回1/2*時間time*聲速346(m/s)*0.001(單位換算:mm)
          save = distance;                        //暫存正確的距離值
          if(distance > max*1000)
          {                  
                beep = 1;
          }
          if(distance <= max*1000 && distance >= min*1000)
          {
                  beep = 0;
                light_time();
          }
          if(distance < min*1000)
          {
                beep = 1;
                delay(50000);
                beep=0;
          }                                
      Math_Distance(distance);        
        }

          else if(flag == 1)        
        {
          distance =  save;                                
        }
        switch(key_scan())
        {
                case 0:
                        break;
                case 1:
                        if(max == 10)
                        {
                                max = 10;
                        }
                        else
                        {
                                max++;
                        }
                        break;
                case 2:
                        if(max == 0)
                        {
                                max = 0;
                        }
                        else
                        {
                                max--;
                        }
                        break;        
                case 3:
                        if(min == 10)
                        {
                                min = 10;
                        }
                        else
                        {
                                min++;
                        }
                        break;
                case 4:
                        if(min == 0)
                        {
                                min = 0;
                        }
                        else
                        {
                                min--;
                        }
                        break;               
                default:
                        break;
        }
         
         OLED_P6x8Str(0,1,"maximums:");
         Show_Number(8,2,maxnum,2);
         OLED_P8x16Str(26,2,"m");
         OLED_P6x8Str(74,1,"minimums:");
         Show_Number(82,2,minnum,2);
         OLED_P8x16Str(100,2,"m");
     OLED_P8x16Str(28,4,"distance:");  
         OLED_P8x16Str(78,6,"dm");                  
         Show_Number(32,6,cm_table1,2);
         OLED_P6x8Str(50,7,".");
         Show_Number(58,6,cm_table2,2);   
         delay(5000);                          

        }
}

/*******************************************************************************
* 函 數(shù) 名       : Math_Distance
*******************************************************************************/
void Math_Distance(uint distance)           //距離值數(shù)學(xué)轉(zhuǎn)換
{
  cm_table1[0]=distance/1000;           
  cm_table1[1]=distance/100;                 
  cm_table2[0]=distance%100/10;           
  cm_table2[1]=distance%100%10;           
  maxnum[0]=max/10;
  maxnum[1]=max%10;
  minnum[0]=min/10;
  minnum[1]=min%10;        
}

按鍵檢測:
#include"key.h"

#define uchar unsigned char
#define uint unsigned int

sbit A4 = P2^0;
sbit A5 = P3^3;
sbit A6 = P2^1;
sbit A7 = P2^2;

/**********************************
* 函數(shù)名:  鍵值函數(shù)
**************************************/
uint key_scan()
{
        uint keynum = 0;
        if(A4 == 0)
        {
                keynum = 1;
        }
        if(A5 == 0)
        {
                keynum = 2;
        }
        if(A6 == 0)
        {
                keynum = 3;
        }
        if(A7 == 0)
        {
                keynum = 4;
        }

        return keynum;

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

使用道具 舉報

沙發(fā)
ID:123289 發(fā)表于 2022-8-31 08:28 | 只看該作者
靈敏:是指在短時間內(nèi)能響應(yīng)你的事件。
這里理解為,你按下了鍵,CPU在短時間就發(fā)現(xiàn)了,且響應(yīng)了一下。
為何不靈敏了呢?因為在這段時間時,CPU【干私活】不理采你的按鍵了。
查一查,有沒有CPU耗時長的程序部分。要想鍵靈敏,必須保CPU在短時間內(nèi)能掃鍵一下。
回復(fù)

使用道具 舉報

板凳
ID:161164 發(fā)表于 2022-8-31 09:00 | 只看該作者
不要用delay
OLED顯示常量只須在初始化時更新一次,如OLED_P6x8Str(0,1,"maximums:");
OLED顯示變量可以定時更新或變量有變化時更新
回復(fù)

使用道具 舉報

地板
ID:59202 發(fā)表于 2022-9-1 00:09 | 只看該作者
如果main函數(shù)里干的事情太多,就會影響到一些要求實時響應(yīng)的工作,最好就把按鍵檢測放到定時中斷函數(shù)里去,可以設(shè)定個10ms中斷檢測一次按鍵情況,就不會有按鍵不靈敏的感覺了
回復(fù)

使用道具 舉報

5#
ID:879348 發(fā)表于 2022-9-1 08:07 | 只看該作者
使用非阻塞編程,或者直接上系統(tǒng)多個while
回復(fù)

使用道具 舉報

6#
ID:1043674 發(fā)表于 2022-9-2 23:36 來自手機 | 只看該作者
掃描按鍵是否按下可以用定時器來掃描,這樣可以避免在執(zhí)行其他耗時操作時,無法掃描按鍵
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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