最近在學習使用DS1302模塊,遇到一個問題。就是我需要把DS1302的時間在LCD上顯示,但是我LCD顯示出的時間是程式里初始化的時間,而不是當前實時的時間,求大佬指導一下。
下面是我的程式:
#include<reg51.h>#include <intrins.h> //包含_nop_( )空函式指令的頭檔案#define uchar unsigned char#define uint unsigned intsbit IO=P1^2; //輸入輸出sbit SCLK=P1^1; //時鐘sbit RST=P1^0; //復位sbit RS=P2^5; //位變數sbit RW=P2^6; //位變數sbit E=P2^7; //位變數 //---DS1302寫入和讀取時分秒的地址命令---////---秒分時日月周年 最低位讀寫位;-------//uchar READ_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; uchar WRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//---DS1302時鐘初始化2013年1月1日星期二12點00分00秒。---////---存盤順序是秒分時日月周年,存盤格式是用BCD碼---//uchar TIME[6]={0,0,0x12,0x01,0x01,0x13};void Lcd_Display(); //LCD顯示函式void delay(uint j); //延時函式void check_busy(void); //忙標志檢測函式void write_command(uchar com); //寫命令函式void write_data(uchar dat); //寫資料函式void Lcd_Init(void); //LCD初始化函式void Ds1302_Write(uchar addr, uchar dat); //DS1302寫命令函式uchar Ds1302_Read(uchar addr); //DS1302讀一個地址的資料void Ds1302_Init(); //初始化DS1302void Ds1302_ReadTime(); //讀取時鐘資訊/*************************************主函式****************************************/void main(){ Lcd_Init(); Ds1302_Init(); while(1) Lcd_Display(); }/****************************1ms延時函式****************************************/void delay(uint j){ uchar i=250; for(;j>0;j--) { while(--i); i=249; while(--i); i=250; }}/****************************液晶顯示幕初始化函式****************************************/void Lcd_Init(void){ write_command(0x38); //寫入命令0x38:8位兩行 顯示,5×7點陣字符 write_command(0x0c); //寫入命令0x0C:開整體 顯示,游標關,無黑塊 write_command(0x06); //寫入命令0x06,0x05左 write_command(0x01); //寫入命令0x01:清屏 delay(1);}/****************************寫命令函式****************************************/void write_command(uchar com){ check_busy(); E=0; RS=0; RW=0; P0=com; E=1; _nop_( ); E=0; delay(1);}/****************************寫資料函式****************************************/void write_data(uchar dat){ check_busy(); E=0; RS=1; RW=0; P0=dat; E=1; _nop_(); E=0; delay(1); }/****************************檢查忙標志函式****************************************/void check_busy(void) { uchar dt; do { dt=0xff; E=0; RS=0; RW=1; E=1; dt=P0; }while(dt&0x80); E=0;}/*******************************初始化DS1302*************************************/void Ds1302_Init(){ uchar n; Ds1302_Write(0x8E,0X00); //禁止寫保護,就是關閉寫保護功能 for (n=0; n<7; n++)//寫入7個位元組的時鐘信號:分秒時日月周年 { Ds1302_Write(WRITE_RTC_ADDR[n],TIME[n]); } Ds1302_Write(0x8E,0x80); //打開寫保護功能}/***************************向DS1302寫命令(地址+資料)*********************************/void Ds1302_Write(uchar addr, uchar dat){ uchar n; RST = 0; _nop_(); SCLK = 0;//先將SCLK置低電平。 _nop_(); RST = 1; //然后將RST(CE)置高電平。 _nop_(); for (n=0; n<8; n++)//開始傳送八位地址命令 { IO = addr & 0x01;//資料從低位開始傳送 addr >>= 1; SCLK = 1;//資料在上升沿時,DS1302讀取資料 _nop_(); SCLK = 0; _nop_(); } for (n=0; n<8; n++)//寫入8位資料 { IO = dat & 0x01; dat >>= 1; SCLK = 1;//資料在上升沿時,DS1302讀取資料 _nop_(); SCLK = 0; _nop_(); } RST = 0;//傳送資料結束 _nop_();}/******************************讀取一個地址的資料*******************************/uchar Ds1302_Read(uchar addr){ uchar n,dat,dat1; RST = 0; _nop_(); SCLK = 0;//先將SCLK置低電平。 _nop_(); RST = 1;//然后將RST(CE)置高電平。 _nop_(); for(n=0; n<8; n++)//開始傳送八位地址命令 { IO = addr & 0x01;//資料從低位開始傳送 addr >>= 1; SCLK = 1;//資料在上升沿時,DS1302讀取資料 _nop_(); SCLK = 0;//DS1302下降沿時,放置資料 _nop_(); } _nop_(); for(n=0; n<8; n++)//讀取8位資料 { dat1 = IO;//從最低位開始接收 dat = (dat>>1) | (dat1<<7); SCLK = 1; _nop_(); SCLK = 0;//DS1302下降沿時,放置資料 _nop_(); } RST = 0; _nop_(); //以下為DS1302復位的穩定時間,必須的。 SCLK = 1; _nop_(); IO = 0; _nop_(); IO = 1; _nop_(); return dat; }/*********************************讀取時鐘資訊***************************************/void Ds1302_ReadTime(){ uchar n; for (n=0; n<6; n++)//讀取6個位元組的時鐘信號:秒分時日月周年 { TIME[n] = Ds1302_Read(READ_RTC_ADDR[n]); } }/********************************LCD顯示函式*************************************/void Lcd_Display(){ Ds1302_ReadTime(); write_command(0x80+0X40); write_data('0'+TIME[2]/16); //時 write_data('0'+(TIME[2]&0x0f)); write_data('-'); write_data('0'+TIME[1]/16); //分 write_data('0'+(TIME[1]&0x0f)); write_data('-'); write_data('0'+TIME[0]/16); //秒 write_data('0'+(TIME[0]&0x0f)); write_command(0x80); write_data('2'); write_data('0'); write_data('0'+TIME[5]/16); //年 write_data('0'+(TIME[5]&0x0f)); write_data('-'); write_data('0'+TIME[4]/16); //月 write_data('0'+(TIME[4]&0x0f)); write_data('-'); write_data('0'+TIME[3]/16); //日 write_data('0'+(TIME[3]&0x0f)); }
uj5u.com熱心網友回復:
詳細看DS1302的手冊, 里面有一個控制位用于啟動RTC時鐘uj5u.com熱心網友回復:
注釋掉DS1302初始化陳述句再編譯,就不會每次上電就是初始化時間。uj5u.com熱心網友回復:
DS1302首次初始化把時間寫進去,再將初始化時間的代碼注釋掉重新編譯再燒錄一次就OK轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/23824.html
標籤:單片機/工控
