單片機源程序如下:
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit P_LED=P1^1;
sbit P_KEY=P2^0;
///////////////////////////////
bit F_4MS=0;
bit f_key_press=0; //按下彈起標志位:0 彈起 1 按下
bit f_key_ctrl=0; //長按標志位
bit F_WORK_ON=0; //開關機標志位:1開機 0關機
/////////////////////////////////
unchar press_cnt=0;
unint ctrl_cnt=0;
unchar show_time=0;
void Timer0Init() //定時器0初始化
{
TMOD |= 0x01; //模式1
TMOD &= 0x0F;
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256; //定時1ms
EA=1;
ET0=1;
TR0=1; //T0中斷溢出請求標志位
///////這個作為主程序的定時,所有的定時都是在這上面進行計算
}
void main(void)
{
POWER_INIT(); //單片機初始化:配置IO口輸出輸出屬性,這個你沒有配置,輸入的情況是否要開上拉,這個你也沒有配置.
//IO口為輸出時,該IO口的初始化電平是高還是低,如果共陰的IO口初始化電平給低,如果共陽的就給高,
//你這原理圖上是共陽的,所以初始化IO口需要給高電平,防止沒有開機的情況下就亮了, 因為你沒有配置IO
//口的電平一般初始化模式是配置給底電平.
Timer0Init(); //T0初始化
while(1) //一直檢測按鍵是否按下 ?按下則進入中斷
{
if(F_1MS)
{
F_1MS=0;
//清看門狗 //你自己找下清理看門狗的代碼是什么
KEY_SCAN(); //按鍵掃描
LED_DISPLAY(); //燈顯示
}
}
}
/*按鍵掃描子函數模塊,記得給IO口設置為輸入,并且開內部上拉*/
void KEY_SCAN(void)
{
if(!f_key_press) //檢測按下
{
if(P_KEY){press_cnt=0;} //按鍵檢測到有高電平就清零計數
press_cnt++; //按鍵變量++
if(press_cnt>=40) //累加到40次,也就是消抖完成了
{
press_cnt=0; //清零計數變量
f_key_press=1; //把這個標志位置1,表示已經按下了
f_key_ctrl=1; //長按標志位置1,
}
}
else
{
if(!P_KEY){press_cnt=0;} //檢測彈起
press_cnt++;
if(press_cnt>=40)
{
press_cnt=0;
f_key_press=0;
if(F_WORK_ON&&f_key_ctrl) //開機短按后可以增加功能
{
//功能自己添加
}
f_key_ctrl=0; //這個標志位不能漏,因為短按的時候這個標志位容易漏掉
}
}
//////////////////////
if(f_key_ctrl) //檢測長按
{
ctrl_cnt++;
if(ctrl_cnt>=3000) //加到3000次 ,也就是3S
{
ctrl_cnt=0; //清零累加計數
f_key_ctrl=0; //清標志位
F_WORK_ON=!F_WORK_ON; //開機或者關機
}
}
else //這個標志位為0的時候清零累加計數
{
ctrl_cnt=0;
}
}
void LED_DISPLAY(void)
{
if(F_WORK_ON)
{
P_LED=0;
}
else
{
P_LED=1;
}
}
void Timer0() interrupt 1 //中斷函數
{
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256;
F_1MS=1; //這個標志位看主程序
}
前面那個POWER_INIT();這個函數你要自己配置,就是IO口的輸入輸出屬性,開不開上拉,初始電平的高低. 思路是這個思路. 這是一個模版.希望你可以看看,并且希望對你有幫助.因為我是在網頁上編輯的,所以沒有在KEIL里面驗證,如果有報錯, 你自己解決一下,但是整體的一個按鍵思路是這樣的. |