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