<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        基于單片機、DS1302、DS1602的電子時鐘,可以設置時間日期

        作者:佚名   來源:不詳   點擊數:  更新時間:2014年08月17日   【字體:

         

         
         
         這是DS1602+DS1302完整程序,其中P1口接獨立鍵盤。
         
        DS1602部分:
         
        # include "SYSTEM.H"             
         
        //#ifndef __LCD1602_8_H__
        //#define __LCD1602_8_H__
         
         
         
        //LCD接口定義     
        sfr   io = 0x80;    //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;
        sbit  rs = P2^6;    //LCD數據/命令選擇端(H/L)
        sbit  rw = P2^5;    //LCD讀/寫選擇端(H/L)
        sbit  ep = P2^7;    //LCD使能控制
        sbit     bz = io^7;    //LCD忙標志位
         
         
        //函數聲明  
        void lcd_busy(void);     //測試LCD忙碌狀態程序
        void lcd_wcmd(unsigned char cmd);  //寫入指令到LCD程序
        void lcd_wdat(unsigned char dat);  //寫入數據到LCD程序
        void lcd_pos (unsigned char x, bit y); //LCD數據指針位置程序
        void lcd_sef_chr();
        //void printc(unsigned char CHAR);  //顯示字符
         
        void lcd_init(void);     //LCD初始化設定程序
         
         
        //測試LCD忙碌狀態
        void lcd_busy(void)
         do{
          ep = 0;
          rs = 0;  //指令
          rw = 1;  //讀出
          io = 0xff;
          ep = 1;
          _nop_(); //高電平讀出 1us 
         }while(bz);  //bz=1表示忙,bz=0表示空閑
         ep = 0;  
        }
         
         
        //寫入指令到LCD
        void lcd_wcmd(unsigned char cmd)
        {       
         lcd_busy(); //檢測忙
         rs = 0;  //指令
         rw = 0;  //寫入
         ep = 1; 
         io = cmd; //指令
         ep = 0;  //下降沿有效 
        }
         
         
        //寫入數據函數
        void lcd_wdat(unsigned char Data)
        {
         lcd_busy();  //檢測忙
         rs = 1;   //數據
         rw = 0;   //寫入
         ep = 1;
         io = Data;  //數據
         ep = 0;   //下降沿有效
        }
         
         
        //LCD數據指針位置程序
        void lcd_pos(unsigned char x, bit y)
        {      
         if(y)lcd_wcmd(x|0xc0); //y=1,第二行顯示;y=0,第一行顯示  0<=x<16
         else lcd_wcmd(x|0x80); //數據指針=80+地址碼(00H~27H,40H~67H)
          
        }
         
         
        //顯示字符
        //
        void printc(unsigned char CHAR)
        {
         lcd_wdat(CHAR);
        }
        //
         
         
        //顯示字符串
        void prints(unsigned char //string)
        {
         //unsigned char i;
         //do{lcd_wdat(string[i]);i++;}while(string[i]!='\0');//生成代碼比for循環大
         for(i=0;string[i]!='\0';i++)lcd_wdat(string[i]);  //有時用for循環也好哈//
         
         while(//string) {lcd_wdat(//string);string++;}
         
        }
         
         
         
         
        //LCD初始化設定
        void lcd_init()
        {      
         lcd_wcmd(0x38);  //設置LCD為16X2顯示,5X7點陣,八位數據接口
         lcd_wcmd(0x06);  //LCD顯示光標移動設置(光標地址指針加1,整屏顯示不移動)
         lcd_wcmd(0x0c);  //LCD開顯示及光標設置(光標不閃爍,不顯示"_")
         lcd_wcmd(0x01);  //清除LCD的顯示內容
         
        }
         
         
        DS1302部分:
         
        # include "SYSTEM.H"
         
         
        //#ifndef __DS1302_A_H__
        //#define __DS1302_A_H__
         
         
         
        //引腳及位的定義
        sbit DS1302_CLK = P3^6;   //時鐘引腳
        sbit DS1302_IO  = P3^4;   //數據引腳
        sbit DS1302_RST = P3^5;   //復位引腳
        sbit ACC0 = ACC^0;
        sbit ACC7 = ACC^7;
         
         
        //函數聲明
        void DS1302_InputByte(unchar Data);           //寫入一個字節(內部函數)
        unchar DS1302_OutputByte(void);               //讀取一個字節(內部函數)
        void Write1302(unchar Address, unchar Data);  //在指定地址寫入指定的數據
        unchar Read1302(unchar Address);              //讀取DS1302指定地址中的數據
        void DS1302_SetProtect(bit Flag);             //DS1302是否寫入保護
        void DS1302_SetTime(unchar Address, unchar Value);//設置時間函數
        void DS1302_GetTime(SYSTEMTIME *Time);        //讀出時間
        void DateToStr(SYSTEMTIME *Time);             //日期轉化成字符
        void TimeToStr(SYSTEMTIME *Time);             //時間轉化成字符
        void DS1302_Initial (void);                   //DS1302初始化
         
        //寫入一個字節(內部函數)
        void DS1302_InputByte(unchar Data) 
        {
         unchar i;
         ACC = Data;
         for(i=8; i>0; i--)
         { 
          DS1302_CLK = 0;  
          DS1302_IO = ACC0; //由低位到高位  
          DS1302_CLK = 1;  //上升沿寫入數據
          ACC >>= 1;
         }
        }
         
         
         
        //讀取一個字節(內部函數)
        unchar DS1302_OutputByte(void)
        {
         unchar i;
         for(i=8; i>0; i--)
         {   
          DS1302_CLK = 0;      //下降沿讀出DS1302的數據
          ACC >>= 1;    //讀出由低到高位,只能移7次有效位!!!
          ACC7 = DS1302_IO;  //第一個數據           
          DS1302_CLK = 1;         
         }      
         return (ACC);
        }
         
         
        //在指定地址寫入指定的數據
        void Write1302(unchar Address, unchar Data)
        {
         DS1302_RST = 0;
         DS1302_CLK = 0;
         DS1302_RST = 1;
         DS1302_InputByte(Address);
         DS1302_InputByte(Data);
         DS1302_CLK = 1;
         DS1302_RST = 0;
        }
         
         
        //讀取1302指定地址中的數據
        unchar Read1302(unchar Address)
        {
         unchar Data;
         DS1302_RST = 0;
         DS1302_CLK = 0;
         DS1302_RST = 1;       //RST拉高,啟動數據傳送
         DS1302_InputByte(Address|0x01);//讀取指定地址數據指令
         Data = DS1302_OutputByte();
         DS1302_CLK = 1;
         DS1302_RST = 0;
         return (Data);
        }
         
        //是否寫入保護
        void DS1302_SetProtect(bit Flag)
        {
         if(Flag)
          Write1302(0x8E,0x80);  //0x8e控制字節地址,bit7=WP WP=1 禁止數據寫入DS1302
         else
          Write1302(0x8E,0x00);  //WP=0 允許數據寫入DS1302
        }
         
         
        //設置時間函數
        void DS1302_SetTime(unchar Address, unchar Value)
        {
         DS1302_SetProtect(0);
         Write1302(Address,((Value/10)<<4|(Value)));
         DS1302_SetProtect(1);
         
        }
         
         
        //讀出時間
        void DS1302_GetTime(SYSTEMTIME *Time)
        {
         unchar ReadValue;
         ReadValue = Read1302(DS1302_SECOND);
         Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
         ReadValue = Read1302(DS1302_MINUTE);
         Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
         ReadValue = Read1302(DS1302_HOUR);
         Time->Hour   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
         ReadValue = Read1302(DS1302_DAY);
         Time->Day    = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
         ReadValue = Read1302(DS1302_WEEK);
         Time->Week   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
         ReadValue = Read1302(DS1302_MONTH);
         Time->Month  = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
         ReadValue = Read1302(DS1302_YEAR);
         Time->Year   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
        }
         
         
        //日期轉化成字符
        void DateToStr(SYSTEMTIME *Time)
        {
         Time->DateString[0] = Time->Year/10 + '0';
         Time->DateString[1] = Time->Year + '0';
         Time->DateString[2] = '-';
         Time->DateString[3] = Time->Month/10 + '0';
         Time->DateString[4] = Time->Month + '0';
         Time->DateString[5] = '-';
         Time->DateString[6] = Time->Day/10 + '0';
         Time->DateString[7] = Time->Day + '0';
         Time->DateString[8] = '\0';
        }
         
         
        //時間轉化成字符
        void TimeToStr(SYSTEMTIME *Time)
        {
         Time->TimeString[0] = Time->Hour/10 + '0';
         Time->TimeString[1] = Time->Hour + '0';
         Time->TimeString[2] = ':';
         Time->TimeString[3] = Time->Minute/10 + '0';
         Time->TimeString[4] = Time->Minute + '0';
         Time->TimeString[5] = ':';
         Time->TimeString[6] = Time->Second/10 + '0';
         Time->TimeString[7] = Time->Second + '0';
         Time->TimeString[8] = '\0';
        }
         
         
        //初始化DS1302
        void DS1302_Initial (void)
        {
         unchar Second=Read1302(DS1302_SECOND);
         if(Second&0x80)//bit7=CH CH=0 振蕩器允許工作,CH=1振蕩器停止工作
         DS1302_SetTime(DS1302_SECOND,0);
         
        }
         
        函數聲明SYSTEM.H:
         
         
        //包含頭文件
        #include<REG52.H>
        #include <intrins.h>
        //#include"LCD1602_8.H"
        //#include"DS1302_A.H"
         
        //P0 Bit Registers
         
        sbit P0_0 = 0x80;
        sbit P0_1 = 0x81;
        sbit P0_2 = 0x82;
        sbit P0_3 = 0x83;
        sbit P0_4 = 0x84;
        sbit P0_5 = 0x85;
        sbit P0_6 = 0x86;
        sbit P0_7 = 0x87;
         
         
        //P1 Bit Registers
         
        sbit P1_0 = 0x90;
        sbit P1_1 = 0x91;
        sbit P1_2 = 0x92;
        sbit P1_3 = 0x93;
        sbit P1_4 = 0x94;
        sbit P1_5 = 0x95;
        sbit P1_6 = 0x96;
        sbit P1_7 = 0x97;
         
        //P2 Bit Registers
        sbit P2_0 = 0xA0;
        sbit P2_1 = 0xA1;
        sbit P2_2 = 0xA2;
        sbit P2_3 = 0xA3;
        sbit P2_4 = 0xA4;
        sbit P2_5 = 0xA5;
        sbit P2_6 = 0xA6;
        sbit P2_7 = 0xA7;
         
         
        //P3 Bit Registers (Mnemonics & Ports)
        sbit P3_0 = 0xB0;
        sbit P3_1 = 0xB1;
        sbit P3_2 = 0xB2;
        sbit P3_3 = 0xB3;
        sbit P3_4 = 0xB4;
        sbit P3_5 = 0xB5;
        sbit P3_6 = 0xB6;
        sbit P3_7 = 0xB7;
         
         
        //宏定義便于理解
        #define unchar unsigned char
        #define unint  unsigned int
        #define DS1302_SECOND      0x80
        #define DS1302_MINUTE      0x82
        #define DS1302_HOUR        0x84
        #define DS1302_WEEK        0x8A
        #define DS1302_DAY         0x86
        #define DS1302_MONTH       0x88
        #define DS1302_YEAR        0x8C
        #define DS1302_RAM(X)      (0xC0+(X)*2) 
        //用于計算RAM地址的宏運算
         
        //定義時間類型
        typedef struct _SYSTEMTIME_
        {
         unchar Second;
         unchar Minute;
         unchar Hour;
         unchar Week;
         unchar Day;
         unchar Month;
         unchar Year;
         unchar DateString[9];
         unchar TimeString[9];
        }SYSTEMTIME;   
         
         
         
        //LCD1602外部引用函數
        extern void lcd_init(void);  //LCD初始化設定程序
        extern void prints(unsigned char *string); //顯示字符串
        extern void lcd_pos (unsigned char x, bit y); //LCD數據指針位置程序
        extern void lcd_sef_chr() ;
        extern void lcd_wcmd(unsigned char cmd);//寫入指令到LCD程序
         
         
        //*DS1302外部引用函數
        extern void DS1302_SetTime(unchar Address, unchar Value);  //設置時間函數
        extern void DS1302_Initial (void);                         //DS1302初始化
        extern void DS1302_GetTime(SYSTEMTIME *Time);              //讀出時間
        extern void DateToStr(SYSTEMTIME *Time);                   //日期轉化成字符
        extern void TimeToStr(SYSTEMTIME *Time);                   //時間轉化成字符
         
         
         
         
        MAIN函數部分:
         
        #include "SYSTEM.H"
        SYSTEMTIME CurrentTime;
         
        unsigned char k = 0; //鍵值
        unsigned char K1,K2,K3,M1,M2,M3,K1J,K2J,K3J,K4J; //鍵值
        unsigned char Set; //調整值
        char Set_Mode = 0;
         
        void Keysan(void);
        void delay200ms(void);
        //主函數
        void main(void)
         lcd_init();
         //lcd_sef_chr(); //寫入自定義字符號
         DS1302_Initial();
         
          lcd_pos(0,0);
          prints("Date:");
          lcd_pos(0,1);
             prints("Time:");
         k = 6;  //不改變時間 
            while(1)
         {
           Keysan();
             DS1302_GetTime(&CurrentTime);
          DateToStr(&CurrentTime);
          TimeToStr(&CurrentTime);  
          lcd_pos(6,0);
          prints(CurrentTime.DateString);
          lcd_pos(6,1);
          prints(CurrentTime.TimeString);
         
          //lcd_pos(7,0);
             //lcd_wcmd(0x0E);
         
          delay200ms();
          
         }
        }
         
        //鍵盤掃描
        void Keysan(void)
        {
         
            if(~P1_2&K1J)   { k++;  }
           K1J=~(~P1_2);
         
            if(~P1_3&K2J)    { Set++; }
            K2J=~(~P1_3);
         
         if(~P1_4&K3J)    { Set--; }
           K3J=~(~P1_4);
         
            if(k == 7) {k = 0; }
         
         switch(k)
         {
           case 0: DS1302_SetTime(DS1302_SECOND, Set&0x3f); break;
           case 1: DS1302_SetTime(DS1302_MINUTE, Set&0x3f); break;
           case 2: DS1302_SetTime(DS1302_HOUR  , Set&0x1f); break;
           case 3: DS1302_SetTime(DS1302_DAY   , Set&0x0f); break;
           case 4: DS1302_SetTime(DS1302_MONTH , Set&0x0f); break;
           case 5: DS1302_SetTime(DS1302_YEAR  , Set&0x7f); break;
           default: break;
         }
        }
        //延時200000+0us 函數定義
        void delay200ms(void)
        {
           unsigned char i,j,k;
           for(i=201;i>0;i--)
           for(j=32;j>0;j--)
           for(k=14;k>0;k--);
        }
         
         
         
         
        關閉窗口
        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮