?? main.c
字號:
#include "reg52.h"
#include "intrins.h"
#include "1602lib.h"
#include "PCF8563lib.h"
#define PAI_BASE 15
#define SCAN_CYCLE 10000
#define SECONDL 12 /*定義顯示字符位置*/
#define SECONDH 11
#define MINUTEL 9
#define MINUTEH 8
#define HOURL 6
#define HOURH 5
#define DAYL 10
#define DAYH 9
#define WEEKDAY 15
#define MONTHS 5
#define YEARL 15
#define YEARH 14
#define AMPM 14
typedef enum{ /*定義枚舉以標識當前設定位置*/
CUR_SECOND,
CUR_MINUTE,
CUR_HOUR,
CUR_DAY,
CUR_WEEKDAY,
CUR_MONTH,
CUR_YEAR
} Current;
typedef enum{ /*定義枚舉以標識顯示內容*/
SHOW_TIME,
SHOW_ALARM
} ShowItem;
uchar str1[] = "TIME:15:23:14 W7"; /*初始顯示時間*/
uchar str2[] = "DATE:JUN.30,2007";
bit alarmflg = 0;
bit timerflg = 0;
bit flg_100ms = 0;
struct c_s cs;
struct time tm;
struct alarm alm;
uchar set_min = 0,set_hour = 0,set_day = 0,set_weekday = 0,set_month = 0,set_year = 0,set_second = 0;
uchar setalarm_min = 0,setalarm_hour = 0;
Current current = CUR_MINUTE;
ShowItem showitem = SHOW_TIME;
uint keyFlag;
bit Int0Flag = 0;
uchar s_tableCounter,musicplayflg = 0;
uchar TH0Temp,TL0Temp;
const char code c_music[] = { 0x82,0x01,0x81,0x94,0x84, /*鬧鐘用生日快樂歌*/
0xb4,0xa4,0x04,
0x82,0x01,0x81,0x94,0x84,
0xc4,0xb4,0x04,
0x82,0x01,0x81,0xf4,0xd4,
0xb4,0xa4,0x94,
0xe2,0x01,0xe1,0xd4,0xb4,
0xc4,0xb4,0x04,
0x00};
const uint code c_musicFreq[] = {64260,64400,64524,64580, /*低音5,6,7,中音1*/
64684,64777,64820,64898, /*中音2,3,4,5*/
64968,65030,65058,65110, /*中音6,7,高音1,2*/
65157,65178,65217}; /*高音2,3,4,5*/
void TxData(uchar dat);
void Delay(uint n);
void ModShow(struct time tm); /*調整顯示內容函數*/
uchar Ascii(uchar dat); /*獲取數字ASCII碼函數*/
void Months(uchar dat); /*月份數字轉字符函數*/
void PCF8563_Init(void); /*初始化PCF8563,包括控制狀態寄存器,時間及鬧鐘*/
void ModAlarm(struct alarm* alm); /*調整鬧鐘時間模塊*/
void ModTime(struct time * tm); /*調整時間模塊*/
void ScanKeys(void); /*掃描鍵盤模塊*/
uchar KeyJudge(void); /*按鍵預處理*/
void KeyHandle(uchar KeyIndex); /*按鍵處理模塊*/
void main(void)
{
TMOD = 0x11; /*TIMER0工作在MODE1,16位定時器,TIMER1工作在MODE2,自動重新裝載模式*/
TH0 = 65536;
TL0 = 65536;
TH1 = (65536-SCAN_CYCLE)/256; /*設定TIMER1每隔SCAN_CYCLE 毫秒中斷一次*/
TL1 = (65536-SCAN_CYCLE)%256;
TR1 = 1; /*啟動TIMER1*/
T2CON =0X38; /*令定時器2作為串口波特率發生器*/
TL2 = 0Xd9; /*設定串口波特率為9600,晶振為12MHz*/
TH2 = 0Xff;
RCAP2L = 0Xd9; /*根據串口波特率9600設定自動重載寄存器*/
RCAP2H = 0xff;
TR2 = 1;
SCON = 0X50; /*設定UART工作在MODE3模式,可傳送和接收數據,REN=1*/
IE = 0X8a; /*使能中斷,TIMER0,1中斷,外部中斷1,2*/
P2 = 0Xff;
LCD_init(); /*LCD初始化*/
DisplayString(0,0,str1); /*顯示第一行字符*/
DisplayString(0,1,str2); /*顯示第二行字符*/
PCF8563_Init(); /*PCF8563初始化*/
while(1)
{
uchar keyPtr;
keyPtr = KeyJudge(); /*鍵盤掃描判斷*/
if(keyPtr!=0x55) /*如果按某鍵則進行相應處理*/
{
KeyHandle(keyPtr);
}
if(flg_100ms){ /*判斷100MS到否*/
flg_100ms = 0;
if(showitem == SHOW_TIME){ /*如果需要時間顯示*/
PCF8563_ReadTime(&tm); /*讀PCF8563時間*/
ModShow(tm); /*調整顯示內容*/
DisplayString(0,0,str1); /*顯示第一行字符*/
DisplayString(0,1,str2); /*顯示第二行字符*/
PCF8563_ReadCS(&cs); /*讀PCF8563控制/狀態字*/
if((cs.cs2&0x08)==0x08){ /*如果鬧鐘時間到*/
musicplayflg = 1; /*設置播放音樂標志*/
TR0 = 1; /*啟動TIMER0*/
cs.cs2 &= 0xf7; /*清鬧鐘標志位*/
PCF8563_SetCS(cs); /*寫PCF8563控制/狀態字*/
}
}else if(showitem == SHOW_ALARM);{ /*如果需要顯示鬧鐘時間*/
ModAlarm(&alm); /*調整鬧鐘時間*/
tm.minutes = alm.minute; /*將鬧鐘時間作為時間顯示*/
tm.hours = alm.hour;
tm.days = alm.day;
tm.weekdays = alm.weekday;
ModShow(tm); /*調整顯示內容*/
DisplayString(0,0,str1); /*顯示第一行字符*/
DisplayString(0,1,str2); /*顯示第二行字符*/
}
}
}
}
void PCF8563_Init(void)
{
cs.cs1 = 0x00;
cs.cs2 = 0x02; /*使能鬧鐘*/
PCF8563_SetCS(cs); /*設置控制/狀態字*/
tm.seconds = 50; /*設置初始時間*/
tm.minutes = 58;
tm.hours = 23;
tm.days = 31;
tm.weekdays = 2;
tm.mon_cen = 12;
tm.years = 6;
PCF8563_SetTime(tm);
alm.minute = 59; /*設定初始鬧鐘時間*/
alm.hour = 23;
alm.day = 00;
alm.weekday = 2;
PCF8563_SetAlarm(alm,1,1,0,0); /*設置鬧鐘*/
}
void ModShow(struct time tm)
{
uchar tmpL,tmpH;
tmpL = tm.seconds & 0x0f; /*調整秒顯示*/
tmpH = (tm.seconds & 0x7f)>>4; /*屏蔽VL位*/
str1[SECONDL] = Ascii(tmpL);
str1[SECONDH] = Ascii(tmpH);
tmpL = tm.minutes & 0x0f; /*調整分鐘顯示*/
tmpH = tm.minutes>>4;
str1[MINUTEL] = Ascii(tmpL);
str1[MINUTEH] = Ascii(tmpH);
tmpL = tm.hours & 0x0f; /*調整小時顯示*/
tmpH = tm.hours>>4;
str1[HOURL] = Ascii(tmpL);
str1[HOURH] = Ascii(tmpH);
tmpL = tm.days & 0x0f; /*調整天顯示*/
tmpH = tm.days>>4;
str2[DAYL] = Ascii(tmpL);
str2[DAYH] = Ascii(tmpH);
tmpL = tm.weekdays & 0x07; /*調整星期顯示*/
str1[WEEKDAY] = Ascii(tmpL);
tmpL = ((tm.mon_cen&0x7f)>>4)*10 + tm.mon_cen & 0x0f; /*體制哦啊橫月份顯示(BCD到HEX)*/
Months(tmpL); /*月份數字轉字符*/
tmpL = tm.years & 0x0f; /*調整年顯示*/
tmpH = tm.years>>4;
str2[YEARL] = Ascii(tmpL);
str2[YEARH] = Ascii(tmpH);
}
uchar Ascii(uchar dat)
{
return dat + 0x30; /*0~9得Ascii碼為其+0x30*/
}
void Months(uchar dat)
{
switch(dat){
case 1:str2[MONTHS]='J';str2[MONTHS+1]='A';str2[MONTHS+2]='N';break;
case 2:str2[MONTHS]='F';str2[MONTHS+1]='E';str2[MONTHS+2]='B';break;
case 3:str2[MONTHS]='M';str2[MONTHS+1]='A';str2[MONTHS+2]='R';break;
case 4:str2[MONTHS]='A';str2[MONTHS+1]='P';str2[MONTHS+2]='R';break;
case 5:str2[MONTHS]='M';str2[MONTHS+1]='A';str2[MONTHS+2]='Y';break;
case 6:str2[MONTHS]='J';str2[MONTHS+1]='U';str2[MONTHS+2]='N';break;
case 7:str2[MONTHS]='J';str2[MONTHS+1]='U';str2[MONTHS+2]='L';break;
case 8:str2[MONTHS]='A';str2[MONTHS+1]='U';str2[MONTHS+2]='G';break;
case 9:str2[MONTHS]='S';str2[MONTHS+1]='E';str2[MONTHS+2]='P';break;
case 10:str2[MONTHS]='O';str2[MONTHS+1]='C';str2[MONTHS+2]='T';break;
case 11:str2[MONTHS]='N';str2[MONTHS+1]='O';str2[MONTHS+2]='V';break;
case 12:str2[MONTHS]='D';str2[MONTHS+1]='E';str2[MONTHS+2]='C';break;
}
}
void Delay(uint n)
{
uint i;
for(i=0;i<n;i++);
}
void TxData(uchar dat)
{
SBUF = dat;
while(TI!=1);
TI = 0;
}
void Timer0Int() interrupt 1 using 2
{
if(Int0Flag==1) /*如果需要產生音樂頻率則按音頻改變TIMER0得中斷周期*/
{
P3^3 = ~P3^3; /*每個TIMER0中斷翻轉一下P3.3的電平以產生相應頻率的方波*/
TH0 = TH0Temp;
TL0 = TL0Temp;
}
}
void Timer1Int() interrupt 3 using 3 /*TIMER1中斷服務程序,中斷周期為10MS*/
{
uchar ucharTemp,ucharTemp1;
static uchar s_paiCounter,s_paiNum;
uint temp;
static uint counter = 0;
if(++counter>=10){ /*如果100ms到則這只100ms標志位*/
flg_100ms = 1;
counter = 0;
}
temp = 65536-SCAN_CYCLE; /*中斷周期為10ms*/
TH1 = temp>>8; /*temp/256相當于右移8位*/
TL1 = temp-((temp>>8)<<8); /*temp%256*/
if(musicplayflg==1){ /*如果需要播放音樂*/
if(++s_paiCounter>=s_paiNum) /**音樂一拍的時間*/
{
s_paiCounter = 0;
ucharTemp = c_music[s_tableCounter++];
if(ucharTemp==0x00) /*如果差到0x00則標識本首歌曲結束*/
{
Int0Flag = 0; /*產生音樂平率標志置零*/
s_paiNum = 4*PAI_BASE; /*歌曲結束后停止播放*/
P3^3 = 1; /*把喇叭關掉*/
s_tableCounter = 0;
musicplayflg = 0;
TR0 = 0;
}
else /*如果查到非0X00則標識是音樂標識碼*/
{
s_paiNum = (ucharTemp&0x0f)*PAI_BASE; /*音樂包是嗎的低四位為節拍碼*/
ucharTemp1 = (ucharTemp&0xf0)>>4;
if(ucharTemp1 == 0) /*如果音頻碼為零則標識不發音*/
{
Int0Flag = 0;
}
else /*如果音頻碼不為零則按此改變TIMER0得中斷周期*/
{
Int0Flag = 0;
temp = c_musicFreq[ucharTemp1-1];
TH0 = temp>>8; /*temp/256相當于右移8位*/
TL0 = temp-((temp>>8)<<8); /*temp%256*/
TH0Temp = TH0; /*保存新的代表音頻得TIMER0周期值*/
TL0Temp = TL0;
Int0Flag = 1;
}
}
}
}
}
void ScanKeys(void) /*掃描鍵盤模塊*/
{
uchar scanValue = 0xef,iScan,scanTempUchar;
for(iScan = 0;iScan<4;iScan++)
{
P1 = scanValue; /*發掃描值*/
scanTempUchar = P1; /*讀入掃描值*/
if((scanTempUchar&0X01) == 0X00) /*第一列被按*/
{
keyFlag|=(0x0001<<(iScan*4+0)); /*設置此鍵的標志位*/
}
else
{
keyFlag&=~(0x0001<<(iScan*4+0)); /*清此鍵的標志位*/
}
if((scanTempUchar&0x02) == 0x00) /*第二列被按*/
{
keyFlag|=(0x0001<<(iScan*4+1)); /*置此鍵的標志位*/
}
else
{
keyFlag&=~(0x0001<<(iScan*4+1)); /*清此鍵的標志位*/
}
if((scanTempUchar&0x04) == 0x00) /*第三列被按*/
{
keyFlag|=0x0001<<(iScan*4+2); /*置此鍵的標志位*/
}
else
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -