?? 2051.c
字號:
//目標器件AT89C2051晶振12M
//單鍵操作實現校時和每天任意兩個時間點定鬧
//在有鬧鈴響時按鍵則停鬧
//在正常模式時按鍵則開啟或關閉鬧鈴功能
//查看鬧鈴時間:在正常模式時第1次按鍵顯示第1鬧鈴時間,第2次按鍵顯示第2鬧鈴時間,3秒后返回正常模式
//設置鬧鈴時間:在正常模式時在3秒內連按3次鍵進入鬧鐘設定模式,此時若不按鍵5秒后返回正常模式
//繼續按鍵則時數跳變,再按鍵分數跳變,再按鍵完成第1鬧鈴時間設置等待確認
//繼續按鍵則進入第2鬧鈴時間設置否則5秒后返回正常模式
//設置時鐘時間:在正常模式時長按鍵5秒則進入校時模式,設置過程與鬧鈴模式相似,設置完成后返回正常模式
//2008年10月12日 I2C
//頭文件包含
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define CYCLE0 50240 //每隔CYCLE0微秒T0產生中斷
#define CYCLE1 20000 //每隔CYCLE1微秒T1產生中斷
#define num 400 //顯示掃描延時量
#define Second 0 //時鐘秒單元
#define Minute 1 //時鐘分單元
#define Hour 2 //時鐘時單元
#define Minute_n1 3 //鬧鈴時單元
#define Hour_n1 4 //鬧鈴分單元
#define Minute_n2 5 //鬧鈴時單元
#define Hour_n2 6 //鬧鈴分單元
#define DispOut P3 //字符碼由P3輸出
//#define DisScan P1 //位掃描碼由P1輸出
//數據緩沖區
uchar TimeData[7]; //時間數據緩沖區
uchar DispData[4]; //顯示緩沖區
//共陽數碼管0~9字符表
uchar code Disp[10]={0xc0,0xf9,0x64,0x70,0x59,0x52,0x42,0xf8,0x40,0x50};
//全局變量定義
uchar KeyVal,f; //鍵值單元
//內部可尋址位定義
bit SecondFlag; //時鐘秒信號位
bit SecondFlashFlag; //時鐘秒閃信號位
bit AddFlag; //設定模式增量信號位
bit TimeSetFlag; //校時模式標志位
bit TimingSetFlag; //鬧鈴模式標志位
bit SetModeFlag; //設置模式標志位
bit TimingFunFlag; //鬧鈴功能的標志位
bit TimingSuitedFlag; //鬧鈴時間匹配標志位
bit BeeNopFlag; //鬧鈴輸出反相信號位
bit BeeMusicFlag; //鬧鈴聲次數信號位
bit BeeSpaceFlag; //鬧鈴聲間隔信號位
bit TimingDisSelectFlag; //鬧鈴時間顯示選取擇控制位
bit KeyTimeOutFlag; //連續擊鍵超時計數控制位
bit UnpressKeyTimeFlag; //無按鍵計時控制位
//輸出連接定義
sbit Hour_SWei= P1^5; //時十位驅動
sbit Hour_GWei= P1^4; //時個位驅動
sbit Min_SWei= P1^3; //分十位驅動
sbit Min_GWei= P1^2; //分個位驅動
//sbit Timing_LED= P3^4; //模式指示長亮時表示鬧鐘功能啟動
sbit Button_S1= P1^7; //按鍵S1
sbit Bee_Out= P1^6; //鬧鈴輸出
//函數聲明
void Delay(uint i); //延時函數
void System_init(void); //系統初始化函數
void TimerMake(void); //計時函數
void Display(void); //顯示函數
void KeyScan(void); //鍵值產生函數
void KeyFunction(void); //鍵功能處理函數
void TimeCompate(void); //時間比較函數
void ChangeData(uchar *x); //設置模式自動增量函數
void TimeDisData(void); //時鐘數據顯示處理函數
void TimingDisData(void); //鬧鈴數據顯示處理函數
void ClearFlag(void);
void StartBuzze(void);
void T0_intermit(void); //T0中斷函數
void T1_intermit(void); //T1中斷函數
//主函數
void main(void)
{
uchar DispScanTime;
uchar KeyTimeOut;
uchar UnpressKeyTime;
System_init();
while(1)
{
DispScanTime++;
//顯示掃描
if(DispScanTime%25==0)
Display();
//鍵盤掃描
if(DispScanTime>250)
{
DispScanTime=0;
Bee_Out=1; //關閉蜂鳴聲
KeyScan();
KeyFunction();
}
//計時
if(SecondFlag)
{
SecondFlag=0;
//時鐘計時
TimerMake();
//連續擊鍵超時計時
if(KeyTimeOutFlag)
{
if(++KeyTimeOut>=3)
ClearFlag(); //返回正常模式
}
else
KeyTimeOut=0;
//無按鍵計時
if(UnpressKeyTimeFlag)
{
if(++UnpressKeyTime>=5)
ClearFlag();
}
else
UnpressKeyTime=0;
}
//鬧鈴啟動
if(TimingFunFlag&&!SetModeFlag&&!TimingSuitedFlag)
{
TimeCompate(); //時間比較
// Timing_LED=0; //LED亮表示鬧鈴功能生效
} //聲光鬧鈴輸出
else if(TimingSuitedFlag&&BeeSpaceFlag)
{
BeeNopFlag=BeeMusicFlag;
Bee_Out=!BeeNopFlag; //取反再輸出
// Timing_LED=!BeeSpaceFlag; //鬧鈴輸出時LED閃爍
}
// else
// Timing_LED=1;
}
}
//初始化函數
void System_init(void)
{
//置顯示初值
TimeData[Hour]=12; //時間初值
TimeData[Minute]=58;
TimeData[Hour_n1]=6; //第一組鬧鈴初值
TimeData[Minute_n1]=36;
TimeData[Hour_n2]=7; //第二組鬧鈴初值
TimeData[Minute_n2]=15;
//初始化P3口
P1=0xff;
//設T0,T1為方式1
TMOD=0x11;
//裝T0初值
TH0=(-CYCLE0)/256;
TL0=(-CYCLE0)%256;
//裝T1初值
TH1=(-CYCLE1)/256;
TL1=(-CYCLE1)%256;
//開中斷及啟動T0
EA =1;
ET0=1;
TR0=1;
}
//延時函數
void Delay(uint i)
{
while(i--);
}
//函數功能:時鐘計時
void TimerMake(void)
{
if(++TimeData[Second]>=60) //秒
{
TimeData[Second]=0;
if(++TimeData[Minute]>=60) //分
{
TimeData[Minute]=0;
if(++TimeData[Hour]>=24) //時
TimeData[Hour]=0;
}
}
}
//時鐘顯示數據放入顯示緩沖區
void TimeDisData(void)
{
DispData[0]=Disp[TimeData[Hour]/10];
if(SecondFlashFlag)
{
//每半秒加小數點用于秒閃
// DispData[1]=Disp[TimeData[Hour]%10]|0x80;
// DispData[2]=Disp[TimeData[Minute]/10]|0x80;
// }
// else
// {
DispData[1]=Disp[TimeData[Hour]%10];
DispData[2]=Disp[TimeData[Minute]/10];
}
DispData[3]=Disp[TimeData[Minute]%10];
}
//鬧鈴顯示數據放入顯示緩沖區
void TimingDisData(void)
{
if(TimingDisSelectFlag)
{
//第2定時時間
DispData[0]=Disp[TimeData[Hour_n2]/10];
DispData[1]=Disp[TimeData[Hour_n2]%10];
DispData[2]=Disp[TimeData[Minute_n2]/10];
DispData[3]=Disp[TimeData[Minute_n2]%10];
}
else
{
//第1定時時間
DispData[0]=Disp[TimeData[Hour_n1]/10];
DispData[1]=Disp[TimeData[Hour_n1]%10];
DispData[2]=Disp[TimeData[Minute_n1]/10];
DispData[3]=Disp[TimeData[Minute_n1]%10];
}
}
//函數功能:顯示
//兩種顯示程序都可行,生成的代碼量相當
void Display(void)
{
/* uchar i;
uchar databat;
uchar ScanStart=0x0e; //掃描初值,由低位開始掃描
//選擇顯示數據
if(TimingSetFlag)
TimingDisData();
else
TimeDisData();
//動態掃描顯示
for(i=0;i<4;i++)
{
databat=DisScan&0xf0; //保存P3口當前狀態
DisScan=databat|0x2f; //清屏
DispOut=DispData[i]; //輸出字符碼
DisScan=databat|(ScanStart&0x2f); //輸出位掃描碼
Delay(DISTIME); //延時
ScanStart=(ScanStart<<1)+1; //產生下一位掃描碼
}*/
//選擇顯示數據
if(TimingSetFlag)
TimingDisData();
else
TimeDisData();
//顯示時十位
Hour_SWei=0;
DispOut=DispData[0];
Delay(num);
Hour_SWei=1;
//顯示時個位
Hour_GWei=0;
DispOut=DispData[1];
Delay(num);
Hour_GWei=1;
//顯示分十位
Min_SWei=0;
DispOut=DispData[2];
Delay(num);
Min_SWei=1;
//顯示分個位
Min_GWei=0;
DispOut=DispData[3];
Delay(num);
Min_GWei=1;
}
//函數功能:定鬧時間比較
void TimeCompate(void)
{
//時分相等且秒為0時啟動鬧鈴輸出
if(TimeData[Second]==0)
{
if((TimeData[Hour_n1]==TimeData[Hour])&&(TimeData[Minute_n1]==TimeData[Minute]))
StartBuzze();
else if((TimeData[Hour_n2]==TimeData[Hour])&&(TimeData[Minute_n2]==TimeData[Minute]))
StartBuzze();
}
}
//函數功能:啟動鬧鈴輸出
void StartBuzze(void)
{
TimingSuitedFlag=1;
ET1=1;
TR1=1; //用TR1控制鬧鈴聲響
}
//按鍵掃描函數:產生鍵值
void KeyScan(void)
{
uint KeyLongTime;
if(!Button_S1)
{
Bee_Out=0; //啟動按鍵聲
if(TimingSuitedFlag) //有鬧鈴輸出時
{
TimingSuitedFlag=0;
Bee_Out=1; //鬧鈴停鬧
TR1=0; //關閉TR1
ET1=0;
}
else
{
while(!Button_S1) //等待按鍵松開
{
KeyLongTime++; //長按鍵計時開始
if(KeyLongTime>300)
{
Bee_Out=1; //關閉按鍵聲
Display(); //保持顯示
}
if(KeyLongTime>600) //長按鍵超過5秒
{
TimeSetFlag=1; //進入校時模式
SecondFlashFlag=1; //使秒閃長亮
KeyVal=12; //鍵值置12指向校時模式起始鍵值
} //校時設定模式的后續鍵值由KeyVal++產生
}
//按鍵松開
KeyVal++; //產生鍵值
KeyLongTime=0; //清長按鍵計時
TimingFunFlag=!TimingFunFlag; //鬧鈴功能開或關
}
}
}//鍵功能函數:執行鍵值功能
void KeyFunction(void)
{
uchar *j; //定義指針
switch(KeyVal)
{
//第1次按鍵
case 1:
KeyTimeOutFlag=1; //啟動按鍵超時計數
TimingSetFlag=1;
break;
//第2次按鍵
case 2:
TimingDisSelectFlag=1; //顯示第2定時時間
TimingFunFlag=1;
break;
//第3次按鍵進入鬧鈴模式
case 3:
KeyTimeOutFlag=0; //關閉按鍵超時計數
TimingSetFlag=1; //進入鬧鈴設置模式
TimingDisSelectFlag=0;
UnpressKeyTimeFlag=1; //啟動無按鍵計時
SetModeFlag=1;
break;
//第4次按鍵時數跳變(鬧鈴模式)
case 4:
UnpressKeyTimeFlag=0;
j=&TimeData[Hour_n1]; //指針指向時間單元
ChangeData(j); //調用增量函數改變時間值
break;
//第5次按鍵分數跳變(鬧鈴模式)
case 5:
j=&TimeData[Minute_n1];
ChangeData(j);
break;
//第6次按鍵等待確認
case 6:
UnpressKeyTimeFlag=1; //啟動無按鍵計時
break;
//第7次按進入第2定時時間設置
case 7:
TimingDisSelectFlag=1;
break;
//
case 8:
UnpressKeyTimeFlag=0;
j=&TimeData[Hour_n2]; //指針指向時間單元
ChangeData(j); //調用增量函數改變時間值
break;
//第9次按鍵分數跳變(鬧鈴模式)
case 9:
j=&TimeData[Minute_n2];
ChangeData(j);
break;
//
case 10:
UnpressKeyTimeFlag=1; //啟動無按鍵計時
break;
//第11次按鍵完成并返回正常模式
case 11:
ClearFlag();
break;
//
case 12:
break;
//長按鍵后鍵值=13進入校時模式
case 13:
SetModeFlag=1;
break;
//校時模式第1次按鍵時數跳變
case 14:
j=&TimeData[Hour];
ChangeData(j);
break;
//校時模式第2次按鍵分數跳變
case 15:
j=&TimeData[Minute];
ChangeData(j);
break;
//校時模式第3次按鍵等待對時
case 16:
TimeData[Second]=0;
break;
//校時模式第4次按鍵完成并返回正常模式
case 17:
TimeSetFlag=0;
SetModeFlag=0;
KeyVal=0;
break;
default:
break;
}
}
//函數功能:設置模式時自動增量改變所設項目
void ChangeData(uchar *x)
{
uchar i;
i=*x; //取出數據
if(AddFlag) //檢測半秒增量標志位
{
AddFlag=0;
if((KeyVal==4)||(KeyVal==8)||(KeyVal==14))
{
if(++i>=24) //時數增加
i=0;
}
else if(++i>=60) //分數增加
i=0;
}
*x=i; //保存數據}
//函數功能:清各個相關控制位返回正常模式
void ClearFlag(void)
{
UnpressKeyTimeFlag=0;
KeyTimeOutFlag=0;
SetModeFlag=0;
TimingSetFlag=0;
TimingDisSelectFlag=0;
KeyVal=0; //返回正常模式
}
//函數功能:T0中斷服務子程序(產生秒脈沖等)
void T0_intermit(void) interrupt 1
{
uint TimeT0;
TH0=(-CYCLE0)/256;
TL0=(-CYCLE0)%256;
TimeT0++;
if(TimeT0%10==0)
{
AddFlag=1; //設置模式的增量標志位置1
if(!TimeSetFlag)
SecondFlashFlag=!SecondFlashFlag; //秒閃脈沖
}
if(TimeT0>=20) //累計20次為1秒
{
TimeT0=0;
if(!TimeSetFlag)
SecondFlag=1; //秒位置1
}
}
//函數功能:T1中斷服務子程序(產生鬧鈴聲響)
//產生寬度為100ms和600ms的方波
void T1_intermit(void) interrupt 3
{
uchar TimeT1;
TH1=(-CYCLE1)/256;
TL1=(-CYCLE1)%256;
TimeT1++;
if(TimeT1%5==0)
BeeMusicFlag=!BeeMusicFlag; //100ms
if(TimeT1>=30)
{
TimeT1=0;
BeeSpaceFlag=!BeeSpaceFlag; //600ms
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -