日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于51单片机+DS1302时钟模块+LCD1602显示

發布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于51单片机+DS1302时钟模块+LCD1602显示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

DS1302時鐘模塊LCD1602顯示

  • DS1302時鐘模塊相關介紹
    • 基本介紹
      • 概述
      • 特點
      • 各引腳功能
      • 相關寄存器
    • 時序圖
      • 單字節寫時序
      • 單字節讀時序
      • 時鐘/日歷多字節(Burst)方式
  • 代碼
    • main.c
    • lcd1602.c
    • ds1302.c
  • 項目展示

DS1302時鐘模塊相關介紹

基本介紹

概述

DS1302 可慢速充電實時時鐘芯片包含實時時鐘/日歷和 31 字節的非易失性靜態 RAM。它經過一個簡
單的串行接口與微處理器通信。實時時鐘/日歷可對秒,分,時,日,周,月,和年進行計數,對于小于
31 天的月,月末的日期自動進行調整,還具有閏年校正的功能。時鐘可以采用 24 小時格式或帶 AM(上
午)/PM(下午)的 12 小時格式。31 字節的== RAM== 可以用來臨時保存一些重要數據。使用同步串行通信,
簡化了 DS1302 與微處理器的通信。與時鐘/RAM 通信僅需3 根線:(1)RST(復位),(2)I/O(數據線)
和(3)SCLK(串行時鐘)。數據可以以每次一個字節的單字節形式或多達 31 字節的多字節形式傳輸。DS1302
能在非常低的功耗下工作,消耗小于 1μW 的功率便能保存數據和時鐘信息。

特點

各引腳功能


各引腳的功能:
Vcc1:主電源;Vcc2:備份電源。 當Vcc2>Vcc1+0.2V時,由Vcc2向DS1302供電,當Vcc2<Vcc1時,由Vcc1向DS1302供電。
SCLK: 串行時鐘,輸入,控制數據的輸入與輸出;
I/O: 三線接口時的雙向數據線;
CE: 輸入信號,在讀和寫的器件必須為高。該引腳有兩個功能:1.開始控制字訪問移位寄存器的控制邏輯;2.提供結束單字節或多字節數據傳輸的方法。

相關寄存器

有關日歷、時間的寄存器共有12個,其中有7個寄存器(讀時81H——8DH,寫時80H——8CH==)存放的數據格式是BCD碼形式。如圖所示

小時寄存器
位7用于定義DS1302是采用12小時模式還是24小時模式。高:12小時模式。在12小時模式時,位5 為1時,表示PM。在24小時模式時,為5是第二個10小時位。
秒寄存器
的就位7定義為時鐘暫停標志(CH)。1:時鐘振蕩器停止,DS1302進入低功耗狀態,當該位置為0時,時鐘開始運行。
控制寄存器
的位7是寫保護位(WP),其他7位均置0,對時鐘和RAM進行寫操作時,WP必須為0,也就是關閉寫保護,當WP為1時,就是只讀模式。
DS1302相關的RAM地址
DS1302中附加31字節靜態RAM的地址如下圖

DS1302的工作模式寄存器
所謂的突發模式(BURST模式)就是一次性傳送多個字節的時鐘信號和RAM數據。比如我可以一次性把時間和日期寫入,也可以一次性的讀出時間和日期。

通過對 31(十進制)位地址尋址(地址/命令位于 1 至 5=邏輯 1),可以把時鐘/日歷或 RAM 寄存器規定為多字節方式。如前所述,位 6 規定時鐘或 RAM 而位 0 規定讀或寫。在時鐘\日歷寄存器中的地址 9 至 31或 RAM 寄存器中的地址 31 不能存儲數據。在多字節方式中讀或寫從地址 0 的位 0 開始。當以多字節方式寫時鐘寄存器時,必須按數據傳送的次序寫最先 8 個寄存器。意思就是寫我們不是只有7個嗎?時分秒、年月日、周一共七個 但是吧它得字節數為8 所有要寫夠8次。
但是,當以多字節方式寫 RAM 時,為了傳送數據不必寫所有 31 個字節。不管是否寫了全部 31 個字節,所寫的每一個字節都將傳送至 RAM。

DS1302充電寄存器
這個我沒整過,全部復制手冊的。哈哈

這個寄存器控制 DS1302 的慢速充電特性。圖 4 的簡化電路表示慢速充電器的基本組成。慢速充電選擇(TCS)位(位 4-7)控制慢速充電器的選擇。為了防止偶然的因素使之工作,只有 1010 模式才能使慢
速充電器工作,所有其它的模式將禁止慢速充電器。DS1302 上電時,慢速充電器被禁止。二極管選擇(DS)位(位 2-3)選擇是一個二極管還是兩個二極管連接在 Vcc2 與 Vcc1 之間。如果 DS 為 01,那么選擇一個二極管;如果 DS 為 10,則選擇兩個二極管。如果 DS 為 00 或 11,那么充電器被禁止,與 TCS 無關。RS 位(位0-1)選擇連接在 Vcc2 與 Vcc1 之間的電阻。電阻選擇(RS)位選擇的電阻如下:

如果 RS 為 00,充電器被禁止,與 TCS 無關。
二極管和電阻的選擇用戶根據電池和超容量電容充電所需的最大電流決定。最大充電電流可以如下列
所說明的那樣進行計算。假定 5V 系統電源加到 Vcc2 而超容量電容接至 Vcc1。再假設慢速充電器工作時在Vcc2 和 Vcc1 之間接有一個二極管和電阻 R1。因而最大電流可計算如下:
Imax =(5.0V-二極管壓降)/R1
=(5.0V-0.7V)/2kΩ
= 2.2mA
顯而易見,當超容量電容充電時,Vcc2 和 Vcc1 之間的電壓減少,因而充電電流將會減小。

時序圖

我們首先得給DS1302時鐘模塊寫入時間和日期,然后呢這個時鐘會自己走,我們之后只需要讀取時間和日期即可。我們直接看時序圖 編寫代碼

單字節寫時序

數據輸入
跟隨在輸入寫命令字節的 8 個 SCLK 周期之后,在下 8 個 SCLK 周期的上升沿輸入數據。如果有額外的SCLK 周期,它們將被忽略。輸入從位 0 開始。

上面時序圖是前8位是地址,后8位是數據。
我們根據上面的時序圖 來編寫 單字節寫的一個函數
發現上面的

/*DS1302寫單字節函數*/ void ds1302_write_byte(unsigned char addrOrData) {unsigned char i = 0;for(i=0;i<8;i++) {DAT = addrOrData & 0x01; //開始傳輸低位 addrOrData = addrOrData >> 1;//右移一位CLK = 1; //拉高時鐘表示已經發送CLK = 0; //拉低時鐘準備繼續放新的數據位} }/*DS1302寫函數*/ void ds1302_write(unsigned char addr,unsigned char data) {RST = 0; //RST拉低SCLK = 0; //時鐘SCLK也拉低RST = 1; //準備開始寫 ds1302_writeByte(addr); //寫入要寫的地址ds1302_writeByte(dat); //寫入地址的數據RST = 0; //關閉 表示結束 }


看上面的圖,比如我想寫入時 為18點 時的寫寄存器是84H 數據就是18點 但是DS1302存儲格式為 BCD 碼那就是 0x18。
那寫入 時 為18點 的代碼則是:

ds1302_write(0x84,0x18); //寫入時 為 18點

單字節讀時序


/*DS1302讀單字節函數*/ unsigned char ds1302_read_byte(unsigned char data) {unsigned char i;for(i=0;i<8;i++){dat = dat >> 1; //右移一位 數據是先從低位開始if(IO == 1)dat = dat | 0x80; //1000 0000elsedat = dat & 0x7f; //0111 1111SCLK = 1; //時鐘拉高表示這位已經結束SCLK = 0; //時鐘拉低開始接收新的數據位}return data; }/*DS1302讀取數據函數*/ unsigned char ds1302_read_data(unsigned char addr) {unsigned char data; //用于存放接收的數據RST = 0; //RST拉低SCLK = 0; //時鐘SCLK也拉低RST = 1; //準備開始寫 ds1302_write_byte(addr); //寫入要讀取的地址data = ds1302_read_byte(data); //讀取地址的數據RST = 0;//關閉 表示結束return data; //返回讀取到的數據 }

我們想讀取時 里面時間 看看現在是幾點 時 讀寄存器是85H

time = ds1302_read_data(0x85);

寫保護寄存器
寫保護寄存器的位 7 是寫保護位。開始 7 位(位 0-6)置為零,在讀操作時總是讀出零。在對時鐘或
功能 字節數 脈沖數
CLOCK 8 72
RAM 31 256
DS1302
RAM 進行寫操作之前,位 7 必須為零。當它為高電平時,寫保護位禁止對任何其它寄存器進行寫操作。

時鐘/日歷多字節(Burst)方式

所謂的突發模式(BURST模式)就是一次性傳送多個字節的時鐘信號和RAM數據。比如我可以一次性把時間和日期寫入,也可以一次性的讀出時間和日期。

代碼

部分代碼呈現

main.c

#include <reg52.h> #include "lcd1602.h" #include "ds1302.h"void main() {lcd_init(); //初始化LCD1602 ds1302_init();//初始化DS1302while(1){ds1302_burst_read(DS1302_READ_TIME); //讀取日期和時間lcd_display_dateAndTime(); //1602顯示日期和時間 } }

lcd1602.c

/*初始化LCD1602函數*/ void lcd_init() {unsigned char array1[] = "date: - - ";unsigned char array2[] = "time: : : "; write_com(CURSOR_RIGHT); //寫入數據后光標自動右移 整屏不移動。 0x40(光標左移 整屏不移動)0x05(左移 整屏右移)0x07(右移 整屏右移)write_com(CLOSE_DIS_CUR); //開顯示功能 無光標 不閃爍write_com(DIS_5X7); //數據總線8位 16X2顯示 5*7點陣write_com(CLEAR_SCREEN); //清屏 0000 0001lcd_display_str(0,0,array1); //第一行顯示 date: - - lcd_display_str(0,1,array2); //第二行顯示 time: : : }/*LCD1602 顯示DS1302日期和時間 函數*/ void lcd_display_dateAndTime() { lcd_display_byte(5,0,(time[7]>>4)+48); //顯示年lcd_display_byte(6,0,(time[7]&0x0f)+48);lcd_display_byte(7,0,(time[6]>>4)+48); //顯示年lcd_display_byte(8,0,(time[6]&0x0f)+48);lcd_display_byte(10,0,(time[4]>>4)+48); //顯示月lcd_display_byte(11,0,(time[4]&0x0f)+48);lcd_display_byte(13,0,(time[3]>>4)+48); //顯示日lcd_display_byte(14,0,(time[3]&0x0f)+48);lcd_display_byte(5,1,(time[2]>>4)+48); //顯示時lcd_display_byte(6,1,(time[2]&0x0f)+48);lcd_display_byte(8,1,(time[1]>>4)+48); //顯示分lcd_display_byte(9,1,(time[1]&0x0f)+48);lcd_display_byte(11,1,(time[0]>>4)+48); //顯示秒lcd_display_byte(12,1,(time[0]&0x0f)+48);lcd_display_byte(14,1,(time[5]&0x0f)+48); //顯示周 }

ds1302.c

#include "ds1302.h"unsigned char time[8] = {0x00,0x45,0x19,0x18,0x10,0x01,0x21,0x20};//秒分時 日月周 年/*DS1302單字節讀數據函數*/ unsigned char ds1302_readByte(unsigned char dat) {unsigned char i = 0;for(i=0;i<8;i++) {dat = dat >> 1; //左移一次 低位開始 共有效左移7次if(DAT == 1) dat = dat | 0x80; //高位置1elsedat = dat & 0x7F; //高位置0 CLK = 1; //時鐘拉高表示這位已經結束CLK = 0; //時鐘拉低開始接收新的數據位} return dat;}/*DS1302單字節寫地址或者數據函數*/ void ds1302_writeByte(unsigned char addrOrData) {unsigned char i = 0;for(i=0;i<8;i++) {DAT = addrOrData & 0x01; //開始傳輸低位 addrOrData = addrOrData >> 1;//右移一位CLK = 1; //拉高時鐘表示已經發送CLK = 0; //拉低時鐘準備繼續放新的數據位}}/*DS1302時鐘模塊寫命令函數*/ void ds1302_writeCom(unsigned char addr,unsigned char dat) {RST = 0; //拉低RSTCLK = 0; //拉低時鐘RST = 1; //使能打開ds1302_writeByte(addr); //寫入要寫的地址ds1302_writeByte(dat); //寫入地址的數據RST = 0; //關閉 表示結束 }/*DS1302時鐘模塊讀數據函數*/ unsigned char ds1302_readData(unsigned char addr) {unsigned char dat = 0;RST = 0; //拉低RSTCLK = 0; //拉低時鐘RST = 1; //打開使能ds1302_writeByte(addr); //寫入要讀的地址dat = ds1302_readByte(dat); //讀取地址的數據RST = 0; //關閉 表示結束return dat; //返回讀取到的數據 }/*DS1302時鐘模塊讀取日期和時間函數*/ void ds1302_read_DateAndTime() {time[0] = ds1302_readData(DS1302_READ_YEAR); //讀取年time[1] = ds1302_readData(DS1302_READ_MONTH); //讀取月time[2] = ds1302_readData(DS1302_READ_DAY); //讀取日time[3] = ds1302_readData(DS1302_READ_HOUR); //讀取時time[4] = ds1302_readData(DS1302_READ_MINUTE);//讀取分time[5] = ds1302_readData(DS1302_READ_SECOND);//讀取秒time[6] = ds1302_readData(DS1302_READ_WEEK); //讀取周 }/*DS1302時鐘模塊初始化函數*/ void ds1302_init() {RST = 0; //關閉RSTCLK = 0; //拉低時鐘ds1302_writeCom(DS1302_WRITE_PROTECT,0x00); //關閉寫保護 這樣才能進行寫操作ds1302_burst_write(DS1302_WRITE_TIME); //初始化全部時間//ds1302_initTime(); //初始時間:2021年10月18日 19點45分00秒 周一 ds1302_writeCom(DS1302_WRITE_PROTECT,0x80); //開啟寫保護 只讀模式}

項目展示


如果覺得這篇文章對你有用。歡迎大家點贊、評論哈哈
需要整個工程代碼,歡迎大家打賞,評論區留上你的郵箱 or vx or qq。o( ̄︶ ̄)o

繼續加油!!!

總結

以上是生活随笔為你收集整理的基于51单片机+DS1302时钟模块+LCD1602显示的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。