最近在做單片機獨立按鍵長按連加,短按加1的功能,網上找了很多例子,都不是很滿意,試了很多都不成功。最后找了一個很多人在用的代碼,不知道什么原因,在我這邊總是無法實現功能,搞了好幾天都不能解決,修修改改無數次,實在是沒思路了。以下是這部分代碼,希望大神賜教!
現在的主要問題是:
1,只能實現短按一次的功能,即數碼管顯示0時,短按一下可以增加到1,再按就沒反應了。
2,應該是KEY_SCAN() 和KEY_PROCESS()這兩個函數的問題,但是找了好久,改了很多也沒解決問題,現在沒有思路了。按鍵掃描函數KEY_SCAN()是在網上找的朱兆琪學習板的程序,我用的單片機是AVR的,在我上面怎么都用不了,不知道啥問題,不知道是程序問題還是硬件問題,感覺硬件沒啥問題,換另一種寫法就沒問題,但是如下寫法總是不行。
單片機源程序如下:
unsigned char key_number=0; //觸發的按鍵編號
unsigned short key_time_delay_cnt_SW1 =0; // SW1 按鍵去抖動計數器
unsigned char key_lock_SW1=0; // SW1 自鎖變量
unsigned short key_cont_trigg_cnt_SW1 =0; //SW1連加計數器
unsigned short key_start_cnt1 =0; //中斷啟動計數器標志位
unsigned short key_start_cnt2 =0;
unsigned short key_start_trigg_cnt1 =0;
unsigned short key_start_trigg_cnt2 =0;
uint8_t KEY_SCAN(void); // 按鍵掃描函數
void KEY_PROCESS(uint8_t); //按鍵處理函數
int main(void)
{
KEY_PROCESS(P_min_set_temp_ON); //P_min_set_temp_ON在數碼管上顯示分和秒
}
uint8_t KEY_SCAN(void)
{
// 掃描SW1
if (1==KEY_SW1) //按鍵沒有被按下(高電平),清零標志位
{
key_lock_SW1 =0; //自鎖標志位清零
key_time_delay_cnt_SW1=0; //去抖延時清零
key_start_cnt1=0; //在中斷中啟動計數
key_cont_trigg_cnt_SW1 =0;
key_start_trigg_cnt1=0; //在中斷中啟動計數
}
else if (0==key_lock_SW1) //如果有按鍵按下,且是第一次按下
{
key_start_cnt1=1; //中斷中啟動計數器,key_time_delay_cnt_SW1開始自加
if (key_time_delay_cnt_SW1 > KEY_TIME_DELAY_SW1) //自加到10mms去抖動,KEY_TIME_DELAY_SW1為進入中斷10次,約10ms
{
key_time_delay_cnt_SW1 =0;
key_start_cnt1=0;
key_lock_SW1=1;
key_number=1; //觸發 一次SW1單次觸發,如果松手,立即返回到if (KEY_SW1)
}
}
else if (key_time_delay_cnt_SW1 < KEY_TIME_ALWAYS_PRESS) //如果按住不放, 在1s內自加,KEY_TIME_ALWAYS_PRESS為1s
{
key_start_cnt1=1;
}
else //持續按住大于1s時,進入連加狀態
{
key_start_trigg_cnt1=1; //啟動key_cont_trigg_cnt_SW1自加
if (key_cont_trigg_cnt_SW1 > KEY_TIME_SEQ_INTER) //自加到250ms后,清零,KEY_TIME_SEQ_INTER為250ms
{
key_cont_trigg_cnt_SW1 =0;
key_start_trigg_cnt2=0;
key_number =2; //觸發SW1連續觸發,實現長按SW1超過1s, 產生每250ms觸發一次按鍵的效果
}
}
return key_number; //返回按鍵編號值
}
void KEY_PROCESS (uint8_t min_sec_set_temp)
{
KEY= KEY_SCAN(); //根據返回的按鍵編號值處理
switch (KEY)
{
case 1: // SW1 單次觸發
min_sec_set_temp ++;
if (min_sec_set_temp >99)
{
min_sec_set_temp=0;
}
//key_number=0;
break;
case 2: //SW1開始連加觸發
min_sec_set_temp --;
if (min_sec_set_temp >99)
{
min_sec_set_temp=99;
}
break;
default: ; break;
}
min_decade=min_sec_set_temp /10; //數碼管顯示
min_the_uint=min_sec_set_temp %10;
sec_decade=min_sec_set_temp /10;
sec_the_uint=min_sec_set_temp %10;
DISPLAY_TIME_SET_MIN_SEC(1); //數碼管顯示函數,通過按鍵加減數字可以顯示出來
}
ISR(TIMER1_OVF_vect) //中斷服務程序, 8M/256分頻,1ms進一次中斷
{
TIFR1 =0x01; //中斷標志置位
TIMSK1 =0x00; //關中斷
if (key_start_cnt1==1)
{
key_time_delay_cnt_SW1 ++;
}
else
{
key_time_delay_cnt_SW1=0;
}
if (key_start_cnt2==1)
{
key_time_delay_cnt_SW2++;
}
else
{
key_time_delay_cnt_SW2=0;
}
if (key_start_trigg_cnt1==1)
{
key_cont_trigg_cnt_SW1 ++;
}
else
{
key_cont_trigg_cnt_SW1=0;
}
if (key_start_trigg_cnt2==1)
{
key_cont_trigg_cnt_SW2 ++;
}
else
{
key_cont_trigg_cnt_SW2=0;
}
TCNT1H =0xFF; //計數器重裝初值高八位
TCNT1L =0xE0; //計數器重裝初值低八位
TIMSK1=0x01; //開中斷
}
|