這是一個用于實際產品的stc單片機按鍵處理程序頭文件和原理圖可從原帖下載: http://www.zg4o1577.cn/bbs/dpj-19294-1.html
#include "STC12C5620AD.H" #include "Key_Scan.H" #include "Key_Handle.H" #include "DS1302.H" #include "Radio.H" #include "Channel_Handle.H" #include "Volume_Handle.H" /********************** 聲明外部變量**************************/ extern uchar Volume; //Volume_Handle.c extern uint PLL; //From Radio.c extern bit Flag_40ms; //From Main.c extern uchar Work_Mode; //From Main.c extern uchar data Sec; //From DS1302.c extern uchar data Min; //From DS1302.c extern uchar data Hour; //From DS1302.c extern uchar data Date; //From DS1302.c extern uchar data Month; //From DS1302.c extern uchar data Day; //From DS1302.c extern uchar data Year; //From DS1302.c extern uchar Display_Channel[]; //From Main.c /********************** 定義變量**************************/ uchar Radio_Index; //預置電臺切換計數,0-15,8用于記錄最后一次的電臺 uchar Key_Flag=0x00; //按鍵計時,有按鍵時清零,無按鍵10S左右使Woke_Mode=0; /********************** 按鍵處理**************************/ void Key_Handle() { uchar Time_Write_Temp; //調整用的緩存 uchar Key_Value; Radio_Index=EEPROM_Get_Index(); //獲取頻道序號 Display_Channel[3]=(Radio_Index/10)|0x30; Display_Channel[4]=(Radio_Index%10)|0x30; //顯示頻道序號 if(Flag_40ms) { Key_Value=Key_Scan(); //40ms進行一次掃描 Flag_40ms=0; Key_Flag++; if(Key_Flag>=250) { Key_Flag=250; LCD_BLK=0; Work_Mode=0; //無按鍵10s后,自動回到模式0 } else LCD_BLK=1; } switch (Key_Value) { case 0x0e: //按下MENU switch (Work_Mode) { case 0: Work_Mode=1; //進入電臺搜索 break; case 1: Work_Mode=2; //進入調節年份 break; case 2: Work_Mode=3; //進入調節月份 break; case 3: Work_Mode=4; //進入調節日 break; case 4: Work_Mode=5; //進入調節星期 break; case 5: Work_Mode=6; //進入調節時 break; case 6: Work_Mode=7; //進入調節分 break; case 7: DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x80,0x00); //秒置0 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 Work_Mode=0; //回到正常顯示 break; default: break; } Key_Flag=0; //清除按鍵計時 break; case 0x0d: //按下|<< switch (Work_Mode) { case 0: //正常狀態 Radio_Index--; //上一個預置電臺 if(Radio_Index<1) Radio_Index=15; EEPROM_Write_Index(Radio_Index); //更新新電臺序號 PLL=EEPROM_Get_PLL(Radio_Index); //更新新電臺PLL TEA5767_Update_PLL(); //寫入PLL break; case 1: TEA5767_User_Search(0); //向下手動搜索 break; case 2: //年減少 Time_Write_Temp=(Year>>4)*10+(Year&0x0f); //裝換成十進制數 if(Time_Write_Temp==0) {Time_Write_Temp=99;} else {Time_Write_Temp--;} Year=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x8c,Year); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 3: //月減少 Time_Write_Temp=(Month>>4)*10+(Month&0x0f); //裝換成十進制數 if(Time_Write_Temp==1) {Time_Write_Temp=12;} else {Time_Write_Temp--;} Month=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x88,Month); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 4: //日減少 Time_Write_Temp=(Date>>4)*10+(Date&0x0f); //裝換成十進制數 if(Time_Write_Temp==1) {Time_Write_Temp=31;} else {Time_Write_Temp--;} Date=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x86,Date); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 5: //星期減少 Time_Write_Temp=(Day>>4)*10+(Day&0x0f); //裝換成十進制數 if(Time_Write_Temp==1) {Time_Write_Temp=7;} else {Time_Write_Temp--;} Day=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x8a,Day); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 6: //時減少 Time_Write_Temp=(Hour>>4)*10+(Hour&0x0f); //裝換成十進制數 if(Time_Write_Temp==0) {Time_Write_Temp=23;} else {Time_Write_Temp--;} Hour=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x84,Hour); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 7: //分減少 Time_Write_Temp=(Min>>4)*10+(Min&0x0f); //裝換成十進制數 if(Time_Write_Temp==0) {Time_Write_Temp=59;} else {Time_Write_Temp--;} Min=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x82,Min); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 8: //音量調節 Volume+=5; //音量減小5dB if(Volume>=35) Volume=35; Volume_Write(Volume); //寫入聲音參數 break; default: break; } Key_Flag=0; //清除按鍵計時 break; case 0x0b: //按下>>| switch (Work_Mode) { case 0: //正常狀態 Radio_Index++; //下一個預置電臺 if(Radio_Index==16) Radio_Index=1; EEPROM_Write_Index(Radio_Index); //更新新電臺序號 PLL=EEPROM_Get_PLL(Radio_Index); //更新新電臺PLL TEA5767_Update_PLL(); //寫入PLL break; case 1: TEA5767_User_Search(1); //向上手動搜索 break; case 2: //年增加 Time_Write_Temp=(Year>>4)*10+(Year&0x0f); //裝換成十進制數 if(Time_Write_Temp==99) {Time_Write_Temp=0;} else {Time_Write_Temp++;} Year=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x8c,Year); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 3: //月增加 Time_Write_Temp=(Month>>4)*10+(Month&0x0f); //裝換成十進制數 if(Time_Write_Temp==12) {Time_Write_Temp=1;} else {Time_Write_Temp++;} Month=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x88,Month); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 4: //日增加 Time_Write_Temp=(Date>>4)*10+(Date&0x0f); //裝換成十進制數 if(Time_Write_Temp==31) {Time_Write_Temp=1;} else {Time_Write_Temp++;} Date=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x86,Date); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 5: //星期增加 Time_Write_Temp=(Day>>4)*10+(Day&0x0f); //裝換成十進制數 if(Time_Write_Temp==7) {Time_Write_Temp=1;} else {Time_Write_Temp++;} Day=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x8a,Day); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 6: //時增加 Time_Write_Temp=(Hour>>4)*10+(Hour&0x0f); //裝換成十進制數 if(Time_Write_Temp==23) {Time_Write_Temp=0;} else {Time_Write_Temp++;} Hour=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x84,Hour); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 7: //分增加 Time_Write_Temp=(Min>>4)*10+(Min&0x0f); //裝換成十進制數 if(Time_Write_Temp==59) {Time_Write_Temp=0;} else {Time_Write_Temp++;} Min=(Time_Write_Temp/10)<<4|(Time_Write_Temp%10); //裝換成BCD DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x82,Min); //寫入 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 break; case 8: //音量調節 if(Volume<=0) Volume=0; else Volume-=5; //音量增加5dB Volume_Write(Volume); //寫入聲音參數 break; default: break; } Key_Flag=0; //清除按鍵計時 break; case 0x07: //按下SET { switch (Work_Mode) { case 0: //正常狀態 Work_Mode=8; //轉到音量調節狀態 break; case 1: //電臺搜索 EEPROM_Save_PLL(Radio_Index,PLL); //存入新收到的電臺 Work_Mode=0; break; case 8: //音量調節狀態 Work_Mode=0; //轉到正常狀態 break; default: DS1302_Write_Data(0x8e,0x00); // 禁止寫保護 DS1302_Write_Data(0x80,0x00); //置秒為00,并啟動時鐘 DS1302_Write_Data(0x8e,0x80); // 開啟寫保護 Work_Mode=0; break; } } Key_Flag=0; //清除按鍵計時 break; default: break; } }