久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2424|回復: 0
打印 上一主題 下一主題
收起左側

Proteus軟件c51單片機lcd\DS1302實現時鐘功能

[復制鏈接]
跳轉到指定樓層
樓主
時鐘可以顯示掉秒

#include"reg52.h"
#define uint unsigned int
#define uchar unsigned char
uchar a,miao,fen,shi,day,week,month,year,key1n,flag,temp;
#define yi 0x80
#define er 0x80+0x40
sbit rs=P2^0;//RS
sbit en=P2^2;//E
sbit rw=P2^1;//RW

sbit led=P2^6;
sbit IO=P2^5;//時鐘
sbit RST=P2^3;//時鐘
sbit SCLK=P2^4;//時鐘
sbit ACC0=ACC^0;//累加器
sbit ACC7=ACC^7;//累加器
sbit key1=P3^2;//設置
sbit key2=P3^3;//加
sbit key3=P3^4;//減
sbit buzzer=P3^5;//喇叭
uchar code tab1[]={"20  -  -  "};//年月日1
uchar code tab2[]={"  :  :  "};
void delay(uint xms)
  {
  uint x,y;
  for (x=xms;x>0;x--)
    for (y=110;y>0;y--);
   }
  void write_1602com(uchar com) //1603液晶寫入指令函數***
   {
   rs=0;//數據/指令選擇置為指令
   rw=0;//讀寫選擇置為寫
   en=0;
   P0=com;//送入指令
   delay(1);
   en=1;
   delay(1);
   en=0;
   }
  void write_1602dat(uchar dat)//***液晶寫入數據函數***
   {
    rs=1;//數據/指令選擇置為數據
    rw=0;//讀寫選擇置為寫
    en=0;
    P0=dat;//送入數據
    delay(1);
    en=1;
    delay(1);
    en=0;
    }
  void lcd_clr()//***液晶初始化函數***
    {
     write_1602com(0x38);//設置16*2顯示,5*7點陣,8位數據接口
  write_1602com(0x0c);//設置LCD顯示開,光標顯示關。
  write_1602com(0x06);//寫一個數據后地址加1
  write_1602com(0x01);//顯示清屏
  write_1602com(yi+1);//年月日在第一行
  for(a=0;a<14;a++)
    {
    write_1602dat(tab1[a]);
    delay(3);
    }
    write_1602com(er+2);
    for(a=0;a<8;a++)
     {
       write_1602dat(tab2[a]);
    delay(3);
    }
   }
  void write_byte(uchar dat)   //DS1302有關子函數  寫一個字節8byte
    {
    ACC=dat;RST=1;
     for(a=8;a>0;a--)
   {
     IO=ACC0;
     SCLK=0;
     SCLK=1;
     ACC=ACC>>1;
          }
  }
   uchar read_byte()    //讀一個字節
     {
    RST=1;
     for(a=8;a>0;a--)
      {
   ACC7=IO;
   SCLK=1;
   SCLK=0;
   ACC=ACC>>1;
   }
   return(ACC);
     }
  void write_1302(uchar add,uchar dat)//向1302芯片寫數據,指定寫入地址,數據
     {
     RST=0;
     SCLK=0;
     RST=1;
     write_byte(add);
            write_byte(dat);
     SCLK=1;
     RST=0;
     }
  uchar read_1302(uchar add)//從1302讀數據函數,指定讀取數據來源地址
    {
     uchar temp;
   RST=0;
   SCLK=0;
   RST=1;
   write_byte(add);
   temp=read_byte();
   SCLK=1;
   RST=0;
   return(temp);
    }
  uchar BCD_Decimal(uchar bcd)//BCD碼轉十進制函數,輸入BCD,返回十進制
     {
       uchar Decimal;
    Decimal=bcd>>4; //bcd碼右移四位高四位(十位)—轉到——低四位(個位)
    return(Decimal=Decimal*10+(bcd&=0x0F));//bcd=bcd&0x0f保留bcd低四位其他位清零
     }
  void ds1302_clr()//1302芯片初始化函數(2008-6-30,10:00,week1)
     {
        RST=0;SCLK=0;
              write_1302(0x8e,0x00);// 允許寫,禁止寫保護
     write_1302(0x80,0x00);// 秒寫入秒寄存器0x80,寫入初始秒數據00
     write_1302(0x82,0x00);// 分寫入分寄存器0x82,寫入初始分數據00
     write_1302(0x84,0x10);// 時寫入時寄存器0x84,寫入初始時數據10
     write_1302(0x8a,0x05);// 周寫入周寄存器0x8a,寫入初始時數據1
     write_1302(0x86,0x12);// 日寫入日寄存器0x86,寫入初始時數據30
     write_1302(0x88,0x0B);// 月寫入時寄存器0x88,寫入初始時數據06
     write_1302(0x8c,0x10);// 年寫入時寄存器0x8c,寫入初始時數據16
     write_1302(0x8e,0x80);// 打開寫保護
     }

  void write_sfm(uchar add,uchar dat)//時 分 秒 可能為兩位數
     {
       uchar gw,sw;
    gw=dat%10;//取得個位數字
    sw=dat/10;//區的十位數字
    write_1602com(er+add);//顯示行數
    write_1602dat(0x30+sw);
    write_1602dat(0x30+gw);  
     }
  void write_nyr(uchar add,uchar dat)//年 月 日
      {
             uchar gw,sw;
    gw=dat%10;
    sw=dat/10;
    write_1602com(yi+add); // 設定顯示位置為第一個位置+add
    write_1602dat(0x30+sw);//數字+30得到該數字的lcd1602顯示碼
    write_1602dat(0x30+gw);//同上
    }
     void write_week(uchar week)//寫星期函數
      {
    write_1602com(yi+12);//星期字符的顯示位置
   
     switch(week)
      {
        case 1:write_1602dat('M');//星期數為1時,顯示
           write_1602dat('O');
        write_1602dat('N');
        break;
     case 2:write_1602dat('T');
           write_1602dat('U');
        write_1602dat('E');
        break;
     case 3:write_1602dat('W');
           write_1602dat('E');
        write_1602dat('D');
        break;
     case 4:write_1602dat('T');
           write_1602dat('H');
        write_1602dat('U');
        break;
     case 5:write_1602dat('F');
        write_1602dat('R');
        write_1602dat('I');
        break;
     case 6:write_1602dat('S');
           write_1602dat('T');
        write_1602dat('A');
        break;
     case 7:write_1602dat('S');
           write_1602dat('U');
        write_1602dat('N');
        break;
    }
   }
   void timealarm()
    {
     if(shi>7)//大于7點才啟動報時
     {
       if(key1==1)//不按下設置按鍵時才有效
       {
      if(fen==0&&miao<30)
      {
      
      
        buzzer=0;//啟動蜂鳴器
      
      }
      else buzzer=1;
       }
     }
    }
          void keyscan()//鍵盤掃描有關函數
      {
     if(key1==0)//key1為功能鍵(設置鍵)
      {
        delay(9); //延時消抖動
       if(key1==0)//判斷按鍵是否按下,按下為0
         {
        buzzer=0;
        delay(20);
        buzzer=1;
         while(!key1);//按鍵釋放
      key1n++;
       if(key1n==9)
        key1n=1;
        switch(key1n)
         {
           case 1:TR0=0;//關閉定時器
              TR1=0;
           write_1602com(er+0x09);//設置按鍵按動一次,秒位置顯示光標
           write_1602com(0x0f); //全屏顯示 光標顯示 顯示光標閃爍
           /*temp=(miao)/10*16+(miao)%10;//
           write_1302(0x8e,0x00);
           write_1302(0x80,0x80|temp);//miao
           write_1302(0x8e,0x80);*/
           break;
        case 2:write_1602com(er+0x06);  //按兩次 分位置顯示光標(可按key2 或 key3進行上調或下調)
              write_1602com(0x0f);
           break;
       case 3:write_1602com(er+0x03);//按三次 時
             write_1602com(0x0f);
          break;
       case 4:write_1602com(yi+0x0e);//按四次week
             write_1602com(0x0f);
          break;
          case 5:write_1602com(yi+0x0a);//按五次日
             write_1602com(0x0f);
          break;
          case 6:write_1602com(yi+0x07);//按六次月
             write_1602com(0x0f);
          break;
          case 7:write_1602com(yi+0x04);//按七次年
             write_1602com(0x0f);
          break;
       case 8:write_1602com(0x0c);
             TR0=1;
          temp=(miao)/10*16+(miao)%10;
          write_1302(0x8e,0x00);
          write_1302(0x80,0x00|temp);//miao數據寫入1302
          write_1302(0x8e,0x80);
          break;
            
        }
        }
    }
     if(key1n!=0)
      {
       if(key2==0)
        {
       delay(10);
       if(key2==0);
       {
         buzzer=0;
      delay(20);
      buzzer=1;
      while(!key2);
      switch(key1n)
      {
       case 1:miao++;//設置鍵按動一次,調秒
         if(miao==60)
         miao=0;  //miao
         write_sfm(0x08,miao);
         temp=(miao)/10*16+(miao)%10;
         write_1302(0x8e,0x00);
         write_1302(0x80,temp);
         write_1302(0x8e,0x80);
         write_1602com(er+0x09);//lcd秒位置顯示光標
        
         break;
        case 2:fen++;
          if(fen==60)
          fen=0;
        write_sfm(0x05,fen);//fen
        temp=(fen)/10*16+(fen)%10;
        write_1302(0x8e,0x00);
        write_1302(0x82,temp);
        write_1302(0x8e,0x80);
        write_1602com(er+6);
        break;
      case 3:shi++;
          if(shi==24)
          shi=0;
        write_sfm(0x02,shi);
        temp=(shi)/10*16+(shi)%10;
        write_1302(0x8e,0x00);
        write_1302(0x84,temp);
        write_1302(0x8e,0x80);
        write_1602com(er+3);
        break;
     case 4:week++;
          if(week==8)
          week=1;
        write_1602com(yi+0x0c);
        write_week(week);
        temp=(week)/10*16+(week)%10;
        write_1302(0x8e,0x00);
        write_1302(0x8a,temp);
        write_1302(0x8e,0x80);
        write_1602com(yi+0x0e);
        break;
     case 5:day++;
            if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
               {if(day==32)
                 day=1;}
         else if(month==4||month==6||month==9||month==11)
              {
              if(day==31)
             day=1;
             }
         else if(month==2)
            {
          if(year%4==0||year%100==0&&year%400==0)
             {
            if(day==30)
               day=1;
            }
           else if(day==29)
               day=1;
           }
         write_nyr(0x09,day);
         temp=(day)/10*16+(day)%10;
         write_1302(0x8e,0x00);
         write_1302(0x86,temp);
         write_1302(0x8e,0x80);
         write_1602com(yi+10);
         break;
     case 6:month++;
             if(month==13)
       month=1;
       write_nyr(0x06,month);
       temp=(month)/10*16+(month)%10;
       write_1302(0x8e,0x00);
       write_1302(0x88,temp);
       write_1302(0x8e,0x80);
       write_1602com(yi+7);
       break;
        case 7:year++;  
          if(year==100)
       year=0;
       write_nyr(3,year);
       temp=(year)/10*16+(year)%10;
       write_1302(0x8e,0x00);
       write_1302(0x8c,temp);
       write_1302(0x8e,0x80);
       write_1602com(yi+4);
       break;
                         }
        }
        }
    if(key3==0)
      {
        delay(10);
       if(key3==0)
       {
         buzzer=0;
      delay(20);
      buzzer=1;
       while(!key3);
       switch(key1n)
      {
       case 1:miao--;//設置鍵按動一次,調秒
         if(miao==-1)
         miao=59;  //miao
         write_sfm(0x08,miao);
         temp=(miao)/10*16+(miao)%10;
         write_1302(0x8e,0x00);
         write_1302(0x80,temp);
         write_1302(0x8e,0x80);
         write_1602com(er+0x09);//lcd秒位置顯示光標
         break;
        case 2:fen--;
          if(fen==-1)
          fen=59;
        write_sfm(0x05,fen);//fen
        temp=(fen)/10*16+(fen)%10;
        write_1302(0x8e,0x00);
        write_1302(0x82,temp);
        write_1302(0x8e,0x80);
        write_1602com(er+6);
        break;
      case 3:shi--;
          if(shi==-1)
          shi=23;
        write_sfm(0x02,shi);
        temp=(shi)/10*16+(shi)%10;
        write_1302(0x8e,0x00);
        write_1302(0x84,temp);
        write_1302(0x8e,0x80);
        write_1602com(er+3);
        break;
     case 4:week--;
          if(week==0)
          week=7;
        write_1602com(yi+0x0c);
        write_week(week);
        temp=(week)/10*16+week%10;
        write_1302(0x8e,0x00);
        write_1302(0x8a,temp);
        write_1302(0x8e,0x80);
        write_1602com(yi+0x0e);
        break;
     case 5:day--;
            if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
               {if(day==-1)
                 day=31;}
         else if(month==4||month==6||month==9||month==11)
              {
              if(day==-1)
             day=30;
             }
         else if(month==2)
            {
          if(year%4==0||year%100==0&&year%400==0)
             {
            if(day==-1)
               day=29;
            }
          else if(day==-1)
             day=28;
           }
         write_nyr(0x09,day);
         temp=(day)/10*16+(day)%10;
         write_1302(0x8e,0x00);
         write_1302(0x86,temp);
         write_1302(0x8e,0x80);
         write_1602com(yi+10);
         break;
     case 6:month--;
             if(month==0)
       month=12;
       write_nyr(6,month);
       temp=(month)/10*16+(month)%10;
       write_1302(0x8e,0x00);
       write_1302(0x88,temp);
       write_1302(0x8e,0x80);
       write_1602com(yi+7);
       break;
        case 7:year--;  
          if(year==-1)
       year=99;
       write_nyr(3,year);
       temp=(year)/10*16+(year)%10;
       write_1302(0x8e,0x00);
       write_1302(0x8c,temp);
       write_1302(0x8e,0x80);
       write_1602com(yi+4);
       break;
                         }
      
      }
     }
     
     }
               }
      void init()
    {
      TMOD=0x11;//指定定時/計數的工作方式
    TH0=0;//定時器T0的高四位=0
    TL0=0;//定時器T0的低四位=0
    EA=1;// 系統允許有開放的中斷
    ET0=1;//允許T0中斷
    TR0=1;//開啟中斷,啟動定時器
              }
    //**************主程序*************//
    void main()
    {
      lcd_clr();
  
            ds1302_clr();
   init();
   led=0;
   buzzer=0;
   delay(80);
   buzzer=1;
   while(1)
   {
     keyscan();//調用鍵盤掃描子函數
     }
    }
    void timer0()interrupt 1
     {
      
    miao=BCD_Decimal(read_1302(0x81));
    fen=BCD_Decimal(read_1302(0x83));
    shi=BCD_Decimal(read_1302(0x85));
    day=BCD_Decimal(read_1302(0x87));
    month=BCD_Decimal(read_1302(0x89));
    year=BCD_Decimal(read_1302(0x8d));
    week=BCD_Decimal(read_1302(0x8b));
    write_sfm(8,miao);
    write_sfm(5,fen);
    write_sfm(2,shi);
    write_nyr(9,day);
    write_nyr(6,month);
    write_nyr(3,year);
    write_week(week);
    timealarm();
    }
字符手冊.pdf (1.29 MB, 下載次數: 5) 51hei1302.zip (119.95 KB, 下載次數: 17)





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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91精品在线播放 | 亚洲成人av在线 | 日本在线免费看最新的电影 | 在线播放中文 | 成人网在线观看 | 激情久久网 | 99国产精品一区二区三区 | 韩国av一区二区 | 美女黄18岁以下禁止观看 | 欧美黄色网络 | 亚洲精品免费视频 | 国产精品视频一二三区 | 国产精品3区 | 亚洲免费网 | av电影一区 | 亚洲成人精选 | 午夜激情在线视频 | 国产精品黄色 | 久久成人免费视频 | 99精品在线观看 | 精品免费视频一区二区 | 日本黄色片免费在线观看 | 草草草网站 | 国产极品车模吞精高潮呻吟 | 久久精品伊人 | 欧美一二三四成人免费视频 | 欧美成人精品在线 | 性xxxxx| 99热这里| 成人免费视频在线观看 | 国产日韩中文字幕 | 亚洲 欧美 日韩 在线 | www.99热这里只有精品 | 超碰伊人| 亚洲免费在线观看 | 日韩有码一区 | 91在线精品视频 | 久久久精 | av手机在线看 | 91精品国产高清一区二区三区 | 午夜影院操 |