這是一個用于實際產品的stc單片機按鍵處理程序頭文件和原理圖可從原帖下載: http://m.raoushi.com/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;
}
}
