找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2870|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

LCD1602 AT89s52單片機定時鬧鐘_我編程及制作(代碼完整,C51編譯通過)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:858964 發(fā)表于 2023-10-5 00:53 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
仿真截圖1_設(shè)置定時時間:
            

仿真截圖2_正在計時:

//源程序名: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)    完整的工程文件夾在此壓縮包中

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:858964 發(fā)表于 2023-10-5 17:17 | 只看該作者

以下是實物外觀,  6個橙黃色按鈕用于設(shè)置定時時間,外殼拆取自別的報廢儀器。


回復(fù)

使用道具 舉報

板凳
ID:1097263 發(fā)表于 2023-11-27 15:59 | 只看該作者
好東西,謝謝壇主分享。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表