|
仿真截圖1_設(shè)置定時(shí)時(shí)間:
仿真截圖1_設(shè)置定時(shí)時(shí)間.jpg (132.36 KB, 下載次數(shù): 51)
下載附件
2023-10-5 00:44 上傳
仿真截圖2_正在計(jì)時(shí):
仿真截圖2_計(jì)時(shí).jpg (128.84 KB, 下載次數(shù): 48)
下載附件
2023-10-5 00:44 上傳
//源程序名:a_clock.c
#include<reg52.h>
#include<stdlib.h>
#include<intrins.h> //包含_nop_()函數(shù)定義的頭文件
unsigned char code digit[ ]={"0123456789"}; //LCD1602初始化字符
unsigned char code str_1[ ]={"Set delay time:"};
unsigned char code str_2[ ]={" Count time: "};
unsigned char count; //Timer0計(jì)數(shù)溢出中斷次數(shù)
unsigned char s,m,h; //即時(shí)的(秒,分,時(shí))變量
unsigned char ss,mm,hh;//預(yù)設(shè)定時(shí)(秒,分,時(shí))變量
unsigned char i; //循環(huán)變量
sbit RS=P2^0; //LCD寄存器選擇位,將RS位定義為P2.0引腳
sbit RW=P2^1; //LCD讀寫(xiě)選擇位,將RW位定義為P2.1引腳
sbit E=P2^2; //LCD使能信號(hào)位,將E位定義為P2.2引腳
sbit BF=P0^7; //LCD忙碌標(biāo)志位,
sbit run=P1^0; //啟動(dòng)計(jì)時(shí)按鈕檢測(cè)
unsigned char runing=0; //0非計(jì)時(shí)運(yùn)行,1計(jì)時(shí)運(yùn)行
sbit h_up=P1^1; //h+ 按鈕檢測(cè)
sbit h_dn=P1^2; //h- 按鈕檢測(cè)
sbit set=P1^3; //pause鈕檢測(cè)
sbit m_up=P1^4; //分鐘+按鈕檢測(cè)
sbit m_dn=P1^5; //分鐘減按鈕檢測(cè)
sbit alarm=P2^7; ////引腳用于觸發(fā)音樂(lè)IC模塊播放音樂(lè)
// 延時(shí)ms函數(shù)////////////////////////
void delayms(unsigned char ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
/////////////////////////////////////
//函數(shù):判斷LCD狀態(tài),result=1忙碌;result=0就緒
unsigned char BusyTest(void)
{
bit result;
RS=0; //RS低電平,RW高電平,可讀狀態(tài)
RW=1;
E=1; //允許讀寫(xiě)
_nop_();
_nop_();
_nop_();
_nop_();
result=BF; //rultes ← LCD狀態(tài)標(biāo)志
E=0; //恢復(fù)低電平
return result;
} /////////////////////////////////////////
//函數(shù):將模式設(shè)置指令或顯示地址寫(xiě)入LCD ////
void WriteInstruction (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //RS和R/W同時(shí)為低電平時(shí),可以寫(xiě)入指令
RW=0;
E=0; //準(zhǔn)備E從0到1發(fā)生正跳變,作為寫(xiě)指令
_nop_();
_nop_(); //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
P0=dictate; //將數(shù)據(jù)送入P0口,即寫(xiě)入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();
E=1; //E置高電平
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //當(dāng)E由高電平跳變成低電平時(shí),LCD開(kāi)始執(zhí)行命令
} //////////////////////////////////////////
//函數(shù):指定字符顯示的實(shí)際地址///////////////
void WriteAddress(unsigned char x)
{
WriteInstruction(x|0x80); //顯示位置地址碼
} //////////////////////////////////////////
//函數(shù):將數(shù)據(jù)字符的ASCII碼寫(xiě)入LCD///////////
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS為高電平,RW為低電平時(shí),可以寫(xiě)入數(shù)據(jù)
RW=0;
E=0; //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖,
//就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
P0=y; //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫(xiě)入液晶模塊
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
E=1; //E置高電平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
E=0; //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開(kāi)始執(zhí)行命令
} /////////////////////////////////////////
//函數(shù):LCD顯示模式初始化設(shè)置 //////////////
void LcdInitiate(void)
{
delayms(15);
WriteInstruction(0x38); //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
delayms(5);
WriteInstruction(0x38);
delayms(5);
WriteInstruction(0x38); //連續(xù)三次,確保初始化成功
delayms(5);
WriteInstruction(0x0c); //顯示模式設(shè)置:顯示開(kāi),無(wú)光標(biāo),光標(biāo)不閃爍
delayms(5);
WriteInstruction(0x06); //顯示模式設(shè)置:光標(biāo)右移,字符不移
delayms(5);
WriteInstruction(0x01); //清屏幕指令,將以前的顯示內(nèi)容清除
delayms(5);
} /////////////////////////////////////////
//函數(shù):顯示小時(shí) //////////////////////////
void DisplayHour(h)
{
unsigned char i,j;
i=h/10; //取整運(yùn)算,求得十位數(shù)字
j=h%10; //取余運(yùn)算,求得各位數(shù)字
WriteAddress(0x44); //寫(xiě)顯示地址,將十位數(shù)字顯示在第2行第5列
WriteData(digit[ i]); //將十位數(shù)字的字符常量寫(xiě)入LCD
WriteData(digit[j]); //將個(gè)位數(shù)字的字符常量寫(xiě)入LCD
} //////////////////////////////////////////////
//函數(shù):顯示分鐘 ///////////////////////////////
void DisplayMinute(m)
{
unsigned char i,j;
i=m/10; //取整運(yùn)算,求得十位數(shù)字
j=m%10; //取余運(yùn)算,求得各位數(shù)字
WriteAddress(0x47); //寫(xiě)地址,將十位數(shù)字顯示在第2行第8列
WriteData(digit[ i]); //將十位數(shù)字的字符常量寫(xiě)入LCD
WriteData(digit[j]); //將個(gè)位數(shù)字的字符常量寫(xiě)入LCD
} //////////////////////////////////////////////
//函數(shù):顯示秒 /////////////////////////////////
void DisplaySecond(s)
{
unsigned char i,j;
i=s/10; //取整運(yùn)算,求得十位數(shù)字
j=s%10; //取余運(yùn)算,求得各位數(shù)字
WriteAddress(0x4a); //寫(xiě)地址,將十位數(shù)字顯示在第2行第11列
WriteData(digit[ i]); //將十位數(shù)字的字符常量寫(xiě)入LCD
WriteData(digit[j]); //將個(gè)位數(shù)字的字符常量寫(xiě)入LCD
} //////////////////////////////////////////////
[ i][ i][ i] //函數(shù):顯示str_1 ///////////////////////[ i][ i][ i]void Display_str_1()
{
WriteAddress(0x01); //寫(xiě)地址,從第1行第2列開(kāi)始顯示
i=0; //從字符數(shù)組的第1個(gè)元素開(kāi)始顯示
while(str_1[ i]!='\0') //若未到字串結(jié)束標(biāo)志'\0',則顯示
{
WriteData(str_1[ i]); //將第i個(gè)字符數(shù)組元素寫(xiě)入LCD
i++; //數(shù)組元素指針+1
}
}//////////////////////////////////////////////
[ i][ i][ i][ i][ i]函數(shù):顯示str_2 //////////////////////////////
[ i][ i][ i][ i][ i]void Display_str_2()//
{
WriteAddress(0x01); //寫(xiě)地址,從第1行第2列開(kāi)始顯示
i=0; //從字符數(shù)組的第1個(gè)元素開(kāi)始顯示
while(str_2[ i]!='\0') //若未到字串結(jié)束標(biāo)志'\0',則顯示
{
WriteData(str_2[ i]); //將第i個(gè)字符數(shù)組元素寫(xiě)入LCD
i++; //數(shù)組元素指針+1
}
}//////////////////////////////////////////////
void Display_symbol() //函數(shù):顯示分隔符號(hào)////////
{
WriteAddress(0x46); //寫(xiě)地址,第1分號(hào)顯示在第2行第7列
WriteData(':');
WriteAddress(0x49); //寫(xiě)地址,第2個(gè)分號(hào)顯示在第2行第10列
WriteData(':');
} ////////////////////////////////////////////
//主函數(shù)///////////////////////////////////////////////
void main(void)
{
LcdInitiate(); //調(diào)用LCD初始化函數(shù)
Display_symbol();
Display_str_1();
hh =0;
mm =0;
ss =0;
s=0; //秒
m=0; //分鐘
h=0; //小時(shí)
TMOD=0x01; //使用定時(shí)器T0的模式1
TH0=(65536-46083)/256; //定時(shí)器T0的高8位設(shè)置初值
TL0=(65536-46083)%256; //定時(shí)器T0的低8位設(shè)置初值
EA=1; //開(kāi)總中斷
ET0=1; //定時(shí)器T0中斷允許
while(1)
{ //while_A
if (run ==0) //按下run按鈕
{ //if_run
delayms(20); //消除按鍵抖動(dòng)
if (run ==0 )
{ // if_run-1
runing =1; // 處于計(jì)時(shí)運(yùn)行狀態(tài)
Display_str_2();
TR0=1; //啟動(dòng)定時(shí)器T0
count=0; //Time0計(jì)數(shù)溢出中斷次數(shù)
while(set !=0)
{ // while_B
DisplayHour(h); //顯示小時(shí)即時(shí)值
delayms(5);
DisplayMinute(m); //顯示分鐘時(shí)值
delayms(5);
DisplaySecond(s); //顯示秒時(shí)值
delayms(5);
if (h >=hh & m>= mm ) //當(dāng)計(jì)時(shí)達(dá)設(shè)定值
{ //if_finish
TR0=0; //停止Time0計(jì)時(shí)
//ET0=0; //關(guān)Time0中斷
DisplayHour(hh); //顯示小時(shí)
delayms(5);
DisplayMinute(mm); //顯示分鐘
delayms(5);
DisplaySecond(ss); //顯示秒
delayms(5);
alarm = ~alarm; //P2.7腳由高電平亦低電平,觸發(fā)音樂(lè)IC模塊
} // end if_finish
} // end while_B
runing =0 ; //非計(jì)時(shí)運(yùn)行標(biāo)志
Display_str_1();
DisplayHour(hh); //顯示小時(shí)設(shè)定值
delayms(5);
DisplayMinute(mm); //顯示分鐘設(shè)定值
delayms(5);
DisplaySecond(ss); //顯示秒設(shè)定值
delayms(5);
} // end if_run-1
} // end if_run
if (h_up==0 )
{
delayms(20); //消除按鍵抖動(dòng)
if (h_up==0 &hh<24)
{
hh++;
DisplayHour(hh);
delayms(500);
}
} //end if_2
if (h_dn==0 )
{
delayms(20);
if (h_dn==0 && hh>0)
{
hh--;
DisplayHour(hh);
delayms(500);
}
}
if (m_up==0 )
{
delayms(20);
if (m_up==0 && mm<60 )
{
mm++;
DisplayMinute(mm);
delayms(500);
}
}
if (m_dn==0 )
{
delayms(20);
if (m_dn==0 && mm>0)
{
mm--;
DisplayMinute(mm);
delayms(500);
}
}
}// end while_A
} // end main() /////////////////////////
//函數(shù):定時(shí)器T0的中斷服務(wù) ////////////////
void Time0(void ) interrupt 1 using 1
{
if (runing ==1)
{
count++; //計(jì)數(shù)溢出中斷次數(shù)累計(jì)
}
if(count==20) //計(jì)滿20次即1秒
{
count=0; //中斷累計(jì)次數(shù)清0
s++; //秒加1
}
if(s==60) //計(jì)滿60秒
{
s=0; //秒清0
m++; //分鐘加1
}
if(m==60) //計(jì)滿60分鐘
{
m=0; //分鐘清0
h++; //小時(shí)加1
}
if(h==24) //計(jì)滿24小時(shí)
{
h=0; //小時(shí)清0
}
TH0=(65536-46083)/256;
TL0=(65536-46083)%256;
} ///////////////////////////////////////
編程工具:keil Uv4
仿真工具:Proteus8.7
alarm_clock.zip
(103.19 KB, 下載次數(shù): 56)
2023-10-5 00:52 上傳
點(diǎn)擊文件名下載附件
完整的工程文件夾 下載積分: 黑幣 -5
完整的工程文件夾在此壓縮包中 |
評(píng)分
-
查看全部評(píng)分
|