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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于DS1302的萬年歷(含proteus仿真與代碼)

[復制鏈接]
跳轉到指定樓層
樓主
ID:524667 發表于 2020-6-29 20:07 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <reg51.h>
#include <stdio.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit lcden=P2^5;//液晶使能
sbit lcdrw=P2^4;//液晶讀寫
sbit lcdrs=P2^3;//液晶命令/數據
sbit ds1302rst=P2^0;//1302復位端
sbit ds1302clk=P2^1;//1302時鐘輸入
sbit ds1302io=P2^2;//1302IO口
sbit key1=P1^2;//功能選擇鍵
sbit key2=P1^3;//數值增加鍵
sbit key3=P1^4;//數值減少鍵
sbit key4=P1^5;//啟動確認鍵
sbit key5=P1^6;//12/24小時切換鍵
sbit key6=P1^7;
sbit key7=P1^1;//鬧鐘設置
sbit beep=P1^0;
char year=10,mon=9,day=8;hou=14,min=33,sec=12;
char naohou=20,naomin=25;
u8 key1pushflag,key2pushflag,key3pushflag,key4pushflag,key5pushflag=0,key6pushflag=0;//定義按鍵1,2,3,4,5標志位
u8 countkey1,runmode=1,naomode=0,countkey2=0;//按鍵1標志,運行標志位
u8 init_display1[]="2010-09-08";
u8 init_display2[]="14:33:12";


void delay(u16 ms){
u8 i,j;
   for(i=ms;i>0;i--)
      for(j=110;j>0;j--);
   }


//液晶顯示模塊
  void write_com(u8 com){//寫命令
     lcdrs=0;
     lcden=0;
     lcdrw=0;
     P0=com;
     delay(5);
     lcden=1;
     delay(5);
     lcden=0;
     }

      void write_date(u8 date){//寫數據
       lcdrs=1;
         lcden=0;
         lcdrw=0;
     P0=date;
     delay(5);
     lcden=1;
     delay(5);
     lcden=0;
      }

      void init_lcd(){//初始化顯示函數
        u8  num;
         lcden=0;
        write_com(0x38); //設置16*2行顯示,5*7點陣,8位數據口
         write_com(0x0c); //開顯示,不顯示光標
         write_com(0x06); //寫一個字符后地址自動加一
         write_com(0x01); //顯示清零,數據指針清零
         write_com(0x80+0x03); //第一行起始地址
         for(num=0;num<10;num++){
         write_date(init_display1[num]);
            delay(5);
            }
            write_com(0x80+0x42); //第二行起始地址
         for(num=0;num<9;num++){
         write_date(init_display2[num]);
            delay(5);
            }
            }

void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{     
if (y == 0)
{     
write_com(0x80 + x);     
        }   
else
{     
write_com(0xC0 + x);     
}        
write_date( Data);  
}

   void write_dat_to_lcd(u8 add,u8 dat){
      u8 ge,shi;
      ge=dat%10;
      shi=dat/10;
      write_com(0x0c);
      write_com(0x80+add);
      write_date(0x30+shi);   
      write_date(0x30+ge);   
   }


   void ds1302_write_byte(u8 dat){//1302寫一字節函數
   u8 temp,num1;
      temp=dat;
      ds1302rst=1;
      for(num1=0;num1<8;num1++){
      ds1302io=temp&0x01;
         ds1302clk=0;
         ds1302clk=1;
         temp=temp>>1;
         }
      }

     u8 ds1302_read_byte(){//1302讀一字節函數
     u8 num,temp;
        ds1302rst=1;
        for(num=0;num<8;num++){
        if(ds1302io)
           temp=temp|0x80;
        else
           temp=temp&0x7f;
         ds1302clk=1;
         ds1302clk=0;
        temp=temp>>1;
           }
           return temp;
        }

        void ds1302_write_add_dat(u8 address,u8 dat){//向ds1302特定地址寫入一字節數據
        ds1302rst=0;
           ds1302clk=0;
           ds1302rst=1;
          ds1302_write_byte(address);
          ds1302_write_byte(dat);
          ds1302clk=1;
           ds1302rst=0;
           }
          
         u8 ds1302_read_add_dat(u8 address,u8 dat){//向ds1302特定地址讀入一字節數據
            u8 temp;
        ds1302rst=0;
           ds1302clk=0;
           ds1302rst=1;
          ds1302_write_byte(address);//先寫地址再讀數據
          temp=ds1302_read_byte();
          ds1302clk=1;
           ds1302rst=0;
            return temp;
           }
          
           u8 BCD_Decimal(u8 bcd){//BCD碼轉十進制
           u8 Decimal;
              Decimal=bcd>>4;
              return (Decimal=Decimal*10+(bcd&=0x0f));
              }
             
           void init_ds1302(){
           ds1302rst=0;
           ds1302clk=0;
              ds1302_write_add_dat(0x8e,0x00);
              }
   //按鍵模塊
   void keyscan(){
   if(key1==0){//加速鍵
   delay(5);
      if(key1==0){//功能按鍵
      while(!key1);
        runmode=0;
      key1pushflag=1;//功能按鍵按下,萬年歷設置狀態
      countkey1++;//年月日時分秒設置
      if(countkey1>6)
         countkey1=1;
         }
      }
      if(key7==0){//鬧鐘模式
      delay(5);
         if(key7==0){
         while(!key7);
            naomode=1;
         key6pushflag=1;
      countkey2++;
     if(countkey2>1)
     countkey2=0;
       }  
            }
    if(key1pushflag==1||key6pushflag==1){
       if(key2==0){//加鍵
   delay(5);
      if(key2==0){
      while(!key2);
        key2pushflag=1;
         }
      }
      if(key3==0){//減鍵
   delay(5);
      if(key3==0){
      while(!key3);
        key3pushflag=1;
         }
      }
      if(key4==0){
   delay(5);
      if(key4==0){
      while(!key4);
      key4pushflag=1;
      key1pushflag=0;
      key6pushflag=0;
         }
      }
      }
      if(key5==0){//12/24小時切換鍵
      delay(5);
         if(key5==0){
         while(!key5);
         key5pushflag=1;         
            }
         }
      if(key6==0){//12/24小時切換鍵
      delay(5);
         if(key6==0){
         while(!key6);
         key5pushflag=0;         
            }
         }
       
            
         }


//按鍵處理
void keyhandle(){
u8 temp;
    switch(countkey1){
    case 1:  //功能按鍵按一次,年數據處理
    write_com(0x80+0x05);//光標處于年的位置
    write_com(0x0f);//光標閃爍
    if(key2pushflag==1){//增加按鍵按下
    year++;
       if(year>99)
          year=0;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x05,year);//顯示增加數字
    write_com(0x80+0x05);   //光標回到年起始位置
       }
       else if(key3pushflag==1){
    year--;
       if(year<0)
          year=99;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x05,year);//顯示減少數字
    write_com(0x80+0x05);   //光標回到年起始位置
       }
       break;
       case 2:
          write_com(0x80+0x08);//光標處于月的位置
    write_com(0x0f);//光標閃爍
    if(key2pushflag==1){//增加按鍵按下
    mon++;
       if(mon>12)
          mon=1;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x08,mon);//顯示增加數字
    write_com(0x80+0x08);   //光標回到月起始位置
       }
       else if(key3pushflag==1){
    mon--;
       if(mon<0)
          mon=12;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x08,mon);//顯示減少數字
    write_com(0x80+0x08);   //光標回到月起始位置
       }
       break;  
       case 3:
            write_com(0x80+0x0b);//光標處于日的位置
    write_com(0x0f);//光標閃爍
    if(key2pushflag==1){//增加按鍵按下
    day++;
       if(day>30)
          day=0;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x0b,day);//顯示增加數字
    write_com(0x80+0x0b);   //光標回到日起始位置
       }
       else if(key3pushflag==1){
    day--;
       if(day<1)
          day=30;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x0b,day);//顯示減少數字
    write_com(0x80+0x0b);   //光標回到日起始位置
       }
       break;

       case 4:
        write_com(0x80+0x42);//光標處于時的位置
    write_com(0x0f);//光標閃爍
    if(key2pushflag==1){//增加按鍵按下
    hou++;
       if(hou>23)
          hou=0;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x42,hou);//顯示增加數字
    write_com(0x80+0x42);   //光標回到時起始位置
       }
    else if(key3pushflag==1){
    hou--;
       if(hou<0)
          hou=23;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x42,hou);//顯示減少數字
    write_com(0x80+0x42);   //光標回到時起始位置
       }
       break;
       case 5:
           write_com(0x80+0x45);//光標處于分的位置
    write_com(0x0f);//光標閃爍
    if(key2pushflag==1){//增加按鍵按下
    min++;
       if(min>59)
          min=0;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x45,hou);//顯示增加數字
    write_com(0x80+0x45);   //光標回到分起始位置
       }
       else if(key3pushflag==1){
    min--;
       if(min<0)
          min=59;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x45,min);//顯示減少數字
    write_com(0x80+0x45);   //光標回到分起始位置
       }
       break;  

       case 6:
         write_com(0x80+0x48);//光標處于秒的位置
    write_com(0x0f);//光標閃爍
    if(key2pushflag==1){//增加按鍵按下
    sec++;
       if(sec>59)
          sec=0;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x48,sec);//顯示增加數字
    write_com(0x80+0x48);   //光標回到秒起始位置
       }
       else if(key3pushflag==1){
    sec--;
       if(sec<0)
          sec=59;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x48,sec);//顯示減少數字
    write_com(0x80+0x48);   //光標回到秒起始位置
       }
       break;
     }  
       if(key4pushflag==1){
         temp=sec/10*16+sec%10;//秒鐘數據變成BCD碼
        ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護
        ds1302_write_add_dat(0x80,temp);  //將秒鐘數據寫入1302秒鐘寄存器
          
          temp=min/10*16+min%10;//分鐘數據變成BCD碼
        ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護
        ds1302_write_add_dat(0x82,temp);  //將秒鐘數據寫入1302秒鐘寄存器
          
          temp=hou/10*16+hou%10;//時鐘數據變成BCD碼
        ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護
        ds1302_write_add_dat(0x84,temp);  //將秒鐘數據寫入1302秒鐘寄存器
          
          temp=day/10*16+day%10;//日數據變成BCD碼
        ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護
        ds1302_write_add_dat(0x86,temp);  //將秒鐘數據寫入1302秒鐘寄存器
          
          temp=mon/10*16+mon%10;//月數據變成BCD碼
        ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護
        ds1302_write_add_dat(0x88,temp);  //將秒鐘數據寫入1302秒鐘寄存器
          
          temp=year/10*16+year%10;//年數據變成BCD碼
        ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護
        ds1302_write_add_dat(0x8c,temp);  //將秒鐘數據寫入1302秒鐘寄存器
       
        write_com(0x0c);
        key4pushflag=0;
        runmode=1;

       }
    }  

  void naozhongmozhi(void){
     u8 temp;
        switch(countkey2){
        case 0:
        write_com(0x80+0x42);//光標處于時的位置
        write_com(0x0f);//光標閃爍
        if(key2pushflag==1){//增加按鍵按下
        naohou++;
       if(naohou>23)
          naohou=0;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x42,naohou);//顯示增加數字
    write_com(0x80+0x42);   //光標回到時起始位置
       }
    else if(key3pushflag==1){
    naohou--;
       if(naohou<0)
          naohou=23;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x42,naohou);//顯示減少數字
    write_com(0x80+0x42);   //光標回到時起始位置
       }
       break;
       case 1:
    write_com(0x80+0x45);//光標處于分的位置
    write_com(0x0f);//光標閃爍
    if(key2pushflag==1){//增加按鍵按下
    naomin++;
       if(naomin>59)
          naomin=0;
      key2pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直增加
    write_dat_to_lcd(0x45,naomin);//顯示增加數字
    write_com(0x80+0x45);   //光標回到分起始位置
       }
       else if(key3pushflag==1){
    naomin--;
       if(naomin<0)
          naomin=59;
      key3pushflag=0;//清除按鍵標志,放置按1次該鍵,數值一直減少
    write_dat_to_lcd(0x45,naomin);//顯示減少數字
    write_com(0x80+0x45);   //光標回到分起始位置
       }
       break;  
           }
           if(key4pushflag==1){
           write_com(0x0c);
        key4pushflag=0;
        naomode=0;
              }
        }
       
  void shijianmoshiqiehuan(void){
  if(key5pushflag==1){
        if(hou>12){
          hou=hou-12;
          LCD_Write_Char(10,1,'P');
          LCD_Write_Char(11,1,'M');
           }
           else{
           hou=hou;
          LCD_Write_Char(10,1,'A');
          LCD_Write_Char(11,1,'M');  
              }
        write_dat_to_lcd(0x48,sec);//把秒送入液晶
        write_dat_to_lcd(0x45,min);
        write_dat_to_lcd(0x42,hou);
        write_dat_to_lcd(0x0b,day);
        write_dat_to_lcd(0x08,mon);
        write_dat_to_lcd(0x05,year);
           }
           else{
        write_dat_to_lcd(0x48,sec);//把秒送入液晶
        write_dat_to_lcd(0x45,min);
        write_dat_to_lcd(0x42,hou);
        write_dat_to_lcd(0x0b,day);
        write_dat_to_lcd(0x08,mon);
        write_dat_to_lcd(0x05,year);
          LCD_Write_Char(10,1,' ');
          LCD_Write_Char(11,1,' ');  
              }
     }


void main(void)
{

   init_lcd();
    init_ds1302();

   while (1){
      keyscan();
      if(runmode==1){
         sec=BCD_Decimal(ds1302_read_add_dat(0x81));//讀1302秒鐘寄存器數據,并轉化為十進制
          min=BCD_Decimal(ds1302_read_add_dat(0x83));
          hou=BCD_Decimal(ds1302_read_add_dat(0x85));
          day=BCD_Decimal(ds1302_read_add_dat(0x87));
          mon=BCD_Decimal(ds1302_read_add_dat(0x89));
          year=BCD_Decimal(ds1302_read_add_dat(0x8d));
         write_com(0x0c);
         if(naomode==0){
         shijianmoshiqiehuan();
         }
         if(naomode==1){
        write_dat_to_lcd(0x45,naomin);
        write_dat_to_lcd(0x42,naohou);
           naozhongmozhi();
            }
            
            if(hou==naohou&&min==naomin){
           beep=0;
               }
               else{
               beep=1;
                  }
         }
         else{//萬年歷參數設置模式
         keyhandle();
            }
      }

}


基于ds1302的萬年歷設計.rar

136.04 KB, 下載次數: 44, 下載積分: 黑幣 -5

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九热免费在线观看 | 国产午夜高清 | 国产资源网| 亚洲毛片 | 日本电影韩国电影免费观看 | 一级网站 | 欧美日韩大片 | 四虎影院免费在线 | 一区二区伦理电影 | 亚洲成人一区 | 久久国产精品免费一区二区三区 | 狠狠骚 | 福利片在线观看 | 一区二区免费在线 | 91国内精品久久 | 成人午夜视频在线观看 | 国产欧美一区二区久久性色99 | 国产精品爱久久久久久久 | 日本超碰| 久久综合九色综合欧美狠狠 | 精品久久久久久久久久久久 | 视频在线一区 | 欧美一区中文字幕 | 成人欧美一区二区三区1314 | 国产在线精品一区二区 | av一区二区三区 | 国产片侵犯亲女视频播放 | 国产成人av在线播放 | 日本小电影在线 | 日一区二区三区 | 色婷婷激情综合 | 嫩草视频在线免费观看 | 91亚洲精品国偷拍自产在线观看 | 自拍偷拍欧美 | 亚洲444kkkk在线观看最新 | 亚洲国产精品日韩av不卡在线 | 91国语清晰打电话对白 | 亚洲精品乱码久久久久久按摩观 | 国产精品成人一区二区三区夜夜夜 | 国产精品国产自产拍高清 | 国产成人短视频在线观看 |