(玩電子) 電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

一個很好的單片機按鍵處理子程序

作者:佚名   來源:本站原創   點擊數:x  更新時間:2013年06月23日   【字體:

這是一個用于實際產品的stc單片機按鍵處理程序頭文件和原理圖可從原帖下載: http://www.ljflms.live/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;
		}		
}
發表評論】【告訴好友】【收藏此文】【關閉窗口

文章評論

相關文章

全天计划时时彩