制作出來的實物圖如下:
DS1302液晶顯示.jpg (1.81 MB, 下載次數: 17)
下載附件
2019-5-4 09:11 上傳
- /*********************************************************************
- 模塊名稱:DS1302
- 模塊功能: RTC
- 硬件接線:無。
- 注意事項:(1) DS1302的SPI接口用到了P3.4、P3.5、P3.6,若程序運行有問題查
- 硬件問題時可以從這三個引腳復用部分查起
- (2) DS1302的初始化時間是隨便給的,之所以給23.59.50,是為了在10
- 秒后即可看到24.59.59到00.00.00的跳變。
- (3) DS1302寄存器讀寫的函數編寫時要注意時序和LSB這2個要點。
- **********************************************************************/
- /*
- **********************************************************************
- * 頭文件包含
- **********************************************************************
- */
- #include "ds1302.h"
- /*
- **********************************************************************
- * 本地全局變量
- **********************************************************************
- */
- // 以下為DS1302相關定義
- sbit DSIO = P1^0; // DS1302的SPI接口IO線,輸入輸出都走這里
- sbit CE = P1^1; // chip enable,讀寫ds1302前要使能,讀寫完要禁止
- sbit SCLK = P1^2; // serial clock,串行時鐘線
- extern u8 gTime[7]; // 定義在mian.c中,用來存儲DS1302中7個時間的BCD碼值
- extern u8 gDigValue[8]; // 定義在main.c中,用LCD2864上顯示的8個數值
- extern u8 YTD[];
- extern u8 week[];
- // DS1302內部時間寄存器地址常量定義,這些地址值可查DS1302數據手冊獲取
- u8 code DS1302_READ_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; //讀地址
- u8 code DS1302_WRITE_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //寫地址
- /*
- **********************************************************************
- * 內部函數原型聲明
- **********************************************************************
- */
- static void Ds1302WriteReg(u8 addr, u8 dat);
- static u8 Ds1302ReadReg(u8 addr);
- static void Ds1302WriteTime(void);
- /*********************************************************************
- * 函 數 名 : Ds1302WriteReg
- * 函數功能 : 向DS1302中地址為addr的寄存器寫入數值dat
- * 參數列表 : addr - 待寫入數值的寄存器地址
- dat - 待寫入addr寄存器的數值
- * 函數輸出 : 無
- *********************************************************************/
- static void Ds1302WriteReg(u8 addr, u8 dat)
- {
- u8 i = 0;
- CE = 0;
- _nop_(); // 空指令,延時
- SCLK = 0; // 先將SCLK置低電平
- _nop_();
- CE = 1; // CE拉高以使能對DS1302的讀寫權限
- _nop_();
- for (i=0; i<8; i++) // 循環逐位發送addr的8個bit,注意低位在前
- {
- DSIO = addr & 0x01; // 數據從LSB低位開始傳送
- addr >>= 1; // 發完后addr右移一位原來的次低位變成新的低位
- SCLK = 1; // 拉高SCLK制造一個上升沿,通知DS1302讀取數據
- _nop_(); // 延時等待DS1302讀取DSIO線上的1位數據
- SCLK = 0; // 讀完后,拉低SCLK為下一個位的傳輸做準備
- _nop_();
- }
- // 循環結束后1字節的寄存器地址傳給DS1302
- for (i=0; i<8; i++) // 循環寫入8位數據,注意低位在前
- {
- DSIO = dat & 0x01;
- dat >>= 1;
- SCLK = 1; //制造上升沿通知DS1302讀取數據
- _nop_();
- SCLK = 0;
- _nop_();
- } // 循環結束后1字節值成功傳給DS1302
-
- CE = 0; // 寫入完畢拉低CE以禁止對DS1302的讀寫,防止意外改寫事故
- _nop_();
- }
- /*********************************************************************
- * 函 數 名 : Ds1302ReadReg
- * 函數功能 : 向DS1302中地址為addr的寄存器寫入數值dat
- * 參數列表 : addr - 待讀出的寄存器的地址
- * 函數輸出 : 讀出的寄存器addr的數值
- *********************************************************************/
- static u8 Ds1302ReadReg(u8 addr)
- {
- u8 i = 0, dat = 0, dat1 = 0;
- CE = 0; // CE設置為初始狀態
- _nop_();
- SCLK = 0; // SCLK設置為初始狀態
- _nop_();
- CE = 1; // 拉高CE使能對DS1302的寄存器讀寫權限
- _nop_();
- for (i=0; i<8; i++) // 循環發送8bit寄存器地址值
- {
- DSIO = addr & 0x01; // DS1302的SPI接口從LSB開始發送
- addr >>= 1;
- SCLK = 1; // 制造上升沿,DS1302在上升沿完成讀取動作
- _nop_();
- SCLK = 0; // 拉低SCLK為下個bit發送做準備
- _nop_();
- }
-
- for (i=0; i<8; i++) // 循環讀取8bit寄存器值數據
- {
- dat1 = DSIO;//從最低位開始接收
- dat = (dat>>1) | (dat1<<7);
- SCLK = 1;
- _nop_();
- SCLK = 0;//DS1302下降沿時,放置數據
- _nop_();
- }
- CE = 0;
- _nop_(); //以下為DS1302復位的穩定時間,必須的。
- SCLK = 1;
- _nop_();
- DSIO = 0;
- _nop_();
- DSIO = 1;
- _nop_();
- return dat;
- }
- /*********************************************************************
- * 函 數 名 : Ds1302WriteTime
- * 函數功能 : 將全局變量gTime中的時間寫入DS1302中以重置DS1302時間
- * 參數列表 : 無
- * 函數輸出 : 無
- *********************************************************************/
- static void Ds1302WriteTime(void)
- {
- u8 i = 0;
- Ds1302WriteReg(0x8E,0x00); // 禁用WP以獲取寫時間寄存器的權限
- for (i=0; i<7; i++) // 依次寫入7個時間,順序依次:秒分時日月周年
- {
- Ds1302WriteReg(DS1302_WRITE_ADDR[i],gTime[i]);
- }
- Ds1302WriteReg(0x8E,0x80); // 使能WP以禁止對時間寄存器的讀寫,防止意外改寫事故
- }
- /*********************************************************************
- * 函 數 名 : Ds1302InitTime
- * 函數功能 : 以給定的初始時間來重置DS1302時間值
- * 參數列表 : 無
- * 函數輸出 : 無
- *********************************************************************/
- void Ds1302InitTime(void)
- {
- // 先給個初始化時間
- gTime[0] = 0x50; // 初始化時間,秒,注意是BCD碼不是10進制也不是16進制
- gTime[1] = 0x59; // 初始化時間,分,注意是BCD碼不是10進制也不是16進制
- gTime[2] = 0x23; // 初始化時間,時,注意是BCD碼不是10進制也不是16進制
- gTime[3] = 0x31; // 初始化時間,日,注意是BCD碼不是10進制也不是16進制
- gTime[4] = 0x12; // 初始化時間,月,注意是BCD碼不是10進制也不是16進制
- gTime[5] = 0x07; // 初始化時間,周,注意是BCD碼不是10進制也不是16進制
- gTime[6] = 0x18; // 初始化時間,年,注意是BCD碼不是10進制也不是16進制,以2000為基數
- // 將給定時間寫入DS1302內部時間寄存器以完成初始化
- Ds1302WriteTime();
- }
- /*********************************************************************
- * 函 數 名 : Ds1302ReadTime
- * 函數功能 : 讀出DS1302內部時間放入全局變量gTime中
- * 參數列表 : 無
- * 函數輸出 : 無
- *********************************************************************/
- void Ds1302ReadTime(void)
- {
- u8 i = 0;
- for (i=0; i<7; i++)//讀取7個字節的時鐘信號:秒分時日月周年
- {
- gTime[i] = Ds1302ReadReg(DS1302_READ_ADDR[i]);
- }
- }
- /*********************************************************************
- * 函 數 名 : UpdateDigValue
- * 函數功能 : 顯示時間
- * 參數列表 : 無
- * 函數輸出 : 無
- *********************************************************************/
- void UpdateDigValue(void)
- {
- Ds1302ReadTime(); // 從DS1302讀取時間存入gTime中
- gDigValue[0] = ((gTime[2] >> 4) & 0x0f)+48; // Hour的高4位
- gDigValue[1] = ((gTime[2] >> 0) & 0x0f)+48; // Hour的低4位
- gDigValue[2] = ':'; // 分隔符
-
- gDigValue[3] = ((gTime[1] >> 4) & 0x0f)+48; // Minute的高4位
- gDigValue[4] = ((gTime[1] >> 0) & 0x0f)+48; // Minute的低4位
- gDigValue[5] = ':'; // 分隔符
- gDigValue[6] = ((gTime[0] >> 4) & 0x0f)+48; // Second的高4位
- gDigValue[7] = ((gTime[0] >> 0) & 0x0f)+48; // Second的低4位
-
- }
- /*********************************************************************
- * 函 數 名 : DisplayDay
- * 函數功能 : 顯示年月日
- * 參數列表 : 無
- * 函數輸出 : 無
- *********************************************************************/
- void DisplayDay(void)
- {
- Ds1302ReadTime(); // 從DS1302讀取時間存入gTime中
- YTD[2] = ((gTime[6] >> 4) & 0x0f)+48; // Hour的高4位
- YTD[3] = ((gTime[6] >> 0) & 0x0f)+48; // Hour的低4位
- YTD[6] = ((gTime[4] >> 4) & 0x0f)+48; // Minute的高4位
- YTD[7] = ((gTime[4] >> 0) & 0x0f)+48; // Minute的低4位
- YTD[10] = ((gTime[3] >> 4) & 0x0f)+48; // Second的高4位
- YTD[11] = ((gTime[3] >> 0) & 0x0f)+48; // Second的低4位
- }
復制代碼 全部資料51hei下載地址:
代碼.zip
(53.48 KB, 下載次數: 5)
2019-5-4 09:14 上傳
點擊文件名下載附件
DS1302液晶顯示 下載積分: 黑幣 -5
|