这是一个用于实际产品的stc单片机按键处理程序头文件和原理图可从原帖下载: http://www.51hei.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; } }