名稱:ds1302數(shù)碼管顯示RTC時間設計Verilog代碼Quartus AX301開發(fā)板
軟件:Quartus
語言:Verilog
代碼功能:
RTC(Real-Time Clock)實時時鐘為系統(tǒng)提供一個可靠的時間,并且在斷電的情況下,RTC 實時時鐘也可以通過電池供電,一直運行下去。RTC 通過類 SPI 總線向 FPGA 傳送 8 位數(shù)據(jù)(BCD 碼)。
數(shù)據(jù)包括秒,分,小時,日期,天,月和年。在本實驗中我們將讀取 RTC 的時,分,秒的數(shù)據(jù)并在數(shù)碼管中顯示時間
FPGA代碼Verilog/VHDL代碼資源下載:www.hdlcode.com
本代碼已在AX301開發(fā)板驗證,AX301開發(fā)板如下,其他開發(fā)板可以修改管腳適配:
設計文檔:
ds1302 數(shù)碼管顯示 RTC 時間實驗
1 實驗簡介
實驗通過閱讀 DS1302 芯片手冊,了解 DS1302 操作時序和相關寄存器,然后設計程序將DS1302 RTC 時間通過數(shù)碼管顯示出來,類似于一個電子鐘。
2 實驗原理
RTC(Real-Time Clock)實時時鐘為系統(tǒng)提供一個可靠的時間,并且在斷電的情況下,RTC 實時時鐘也可以通過電池供電,一直運行下去。RTC 通過類 SPI 總線向 FPGA 傳送 8 位數(shù)據(jù)(BCD 碼)。
數(shù)據(jù)包括秒,分,小時,日期,天,月和年。在本實驗中我們將讀取 RTC 的時,分,秒的數(shù)據(jù)并在數(shù)碼管中顯示時間。
2.1 硬件介紹
AX301/AX4010 開發(fā)板上 RTC 設計采用 DALLAS 公司的低功耗實時時鐘芯片 DS1302, DS1302 的VCC2 為主電源,VCC1 為后備電源。在主電源關閉的情況下,也能可以通過電池保持時鐘的連續(xù)運行。DS1302 外接 32.768kHz 晶振為 RTC 電路提供振蕩源。 RTC 部分的原理圖如下圖所示:
2.2 DS1302 時序和控制
2.2.1 寫數(shù)據(jù)時序
DS1302 芯片寫操作的時序圖。第一個字節(jié)是“訪問寄存器的地址”,第二字節(jié)是“寫數(shù)據(jù)”。 在寫操作的時候,都是“上升沿有效”,然而還有一個條件,就是 CE(/RST)信號必須拉高。
(數(shù)據(jù)都是從 LSB 開始發(fā)送,亦即是最低位開始至最高位結束)。
DS1302 寫時序
2.2.2 讀數(shù)據(jù)時序
基本上和寫操作的時序圖大同小異,區(qū)別的地方就是在第二個字節(jié)是“讀數(shù)據(jù)”的動作。第 二字節(jié)讀數(shù)據(jù)開始時,SCLK 信號都是下降沿送出數(shù)據(jù),這個時候可以使用上升沿讀取數(shù)據(jù)。CE (/RST)信號同樣是必須拉高。(第一節(jié)數(shù)據(jù)是從 LSB 開始輸出,第二節(jié)數(shù)據(jù)是從 LSB 開始讀 入)。
2.2.3 命令格式和寄存器
無論是讀操作還是寫操作,在時序圖中,第一個字節(jié)都是“訪問寄存器的地址”,然而這一字 節(jié)數(shù)據(jù)有自己的格式。
BIT 7 固定。 BIT 6 表示是訪問寄存器本身,還是訪問 RAM 空間。 BIT 5 到 BIT1 表示是寄存器 或 RAM 空間的地址。 BIT 0 表示是訪問寄存器本身是寫操作,還是讀操作。
下圖是 DS1302 的寄存器地址和數(shù)據(jù)格式
3 程序設計
通過分析 DS1302 讀寫時序,可以看出和 SPI 時序類似,只不過數(shù)據(jù)輸出和輸入分時復用了,本實驗利用 SPI Flash 讀寫實驗中已經(jīng)使用過的 SPI Master 模塊來做為 DS1302 的底層讀寫控制模塊,然后再編寫一個 RTC 讀寫模塊。
ds1302_io 模塊完成 DS1302 寄存器讀寫控制,狀態(tài)機如下圖所示。
狀態(tài)“S_IDLE”空閑狀態(tài),收到讀寫寄存器請求寫進入“S_CE_HIGH”狀態(tài),將 CE 拉高,然后根據(jù)請求類型,進入讀(S_READ)或寫狀態(tài)(S_WRITE)。
“S_WRITE”狀態(tài)下一個狀態(tài)進入寫地址狀態(tài)“S_WRITE_ADDR”,再進入寫數(shù)據(jù)狀態(tài)“S_WRITE_DATA”,完成一個寄存器的寫入,最后應答,拉低 CE。
“S_READ”狀態(tài)下一個狀態(tài)進入讀地址狀態(tài)“S_READ_ADDR”,再進入讀數(shù)據(jù)狀態(tài)“S_READ_DATA”,完成一個寄存器的讀取,最后應答,拉低 CE。
ds1302_io 狀態(tài)機
信號名稱 |
方向 |
說明 |
clk |
in |
時鐘輸入 |
rst |
in |
異步復位輸入,高復位 |
ds1302_ce |
out |
DS1302 CE,高有效 |
ds1302_sclk |
out |
DS1302 串行時鐘 |
ds1302_io |
inout |
DS1302 數(shù)據(jù) |
cmd_read |
in |
讀寄存器請求,發(fā)出請求時準備好地址 |
cmd_write |
in |
寫寄存器請求,發(fā)出請求時準備好地址和數(shù)據(jù) |
cmd_read_ack |
out |
讀寄存器應答,應答時讀取數(shù)據(jù)有效 |
cmd_write_ack |
out |
寫寄存器應答 |
read_addr |
in |
讀寄存器地址 |
write_addr |
in |
寫寄存器地址 |
read_data |
out |
讀出的數(shù)據(jù) |
write_data |
in |
寫寄存器數(shù)據(jù) |
ds1302_io 端口
ds1302 模塊主要完成時間寄存器的讀寫控制,狀態(tài)機狀態(tài)較為簡單。
ds1302 模塊狀態(tài)機
信號名稱 |
方向 |
說明 |
clk |
in |
時鐘輸入 |
rst |
in |
異步復位輸入,高復位 |
ds1302_ce |
out |
DS1302 CE,高有效 |
ds1302_sclk |
out |
DS1302 串行時鐘 |
ds1302_io |
inout |
DS1302 數(shù)據(jù) |
write_time_req |
in |
ds1302 寫時間請求,請求發(fā)出時,時間數(shù)據(jù) write_second、write_minute、write_hour、 write_date、write_month、write_week、write_year 要 有效 |
write_time_ack |
out |
寫時間請求應答 |
write_second |
in |
寫時間:秒,BCD 碼,00-59 |
write_minute |
in |
寫時間:分,BCD 碼,,00-59 |
write_hour |
in |
寫時間:時,BCD 碼,,00-23 |
write_date |
in |
寫時間:日,BCD 碼,,01-31 |
write_month |
in |
寫時間:月,BCD 碼,,01-12 |
write_week |
in |
寫時間:周,BCD 碼,,01-07 |
write_year |
in |
寫時間:年,BCD 碼,,00-99 |
read_time_req |
in |
讀時間請求 |
read_time_ack |
out |
讀時間請求應答 |
read_second |
out |
讀時間:秒,BCD 碼,00-59 |
read_minute |
out |
讀時間:分,BCD 碼,,00-59 |
read_hour |
out |
讀時間:時,BCD 碼,,00-23 |
read_date |
out |
讀時間:日,BCD 碼,,01-31 |
read_month |
out |
讀時間:月,BCD 碼,,01-12 |
read_week |
out |
讀時間:周,BCD 碼,,01-07 |
read_year |
out |
讀時間:年,BCD 碼,,00-99 |
ds1302 模塊端口
ds1302_test 模塊主要 CH 狀態(tài)檢測,CH 位于秒寄存器的 BIT7 位,上電后首先讀取時間,判斷秒寄存器的 CH 狀態(tài),如果為高,表示 DS1302 暫停,狀態(tài)機進入“S_WRITE_CH”,將 CH 寫 0, 并將一個初始時間寫入,然后循環(huán)不斷的讀取時間寄存器。
ds1302_test 狀態(tài)機
信號名稱 |
方向 |
說明 |
clk |
in |
時鐘輸入 |
rst |
in |
異步復位輸入,高復位 |
ds1302_ce |
out |
DS1302 CE,高有效 |
ds1302_sclk |
out |
DS1302 串行時鐘 |
ds1302_io |
inout |
DS1302 數(shù)據(jù) |
read_second |
out |
時間:秒,BCD 碼,00-59 |
read_minute |
out |
時間:分,BCD 碼,00-59 |
read_hour |
out |
時間:時,BCD 碼,00-23 |
read_date |
out |
時間:日,BCD 碼,01-31 |
read_month |
out |
時間:月,BCD 碼,01-12 |
read_week |
out |
時間:周,BCD 碼,01-07 |
read_year |
out |
時間:年,BCD 碼,00-99 |
ds1302_test 端口
4 實驗現(xiàn)象
將程序下載到開發(fā)板以后,可以看到數(shù)碼管一個初始時間,然后每秒時間改變一次,如果裝有紐扣電池,這個時間會持續(xù)走下去,不會因為斷電后停止;如果沒有紐扣電池,可以在不斷電的情況下重新下載程序,時間不會因為程序中斷而停止。也可以斷電后等待一分鐘左右,重新上電,RTC 保存的時間即會消失,可以重新下載程序。
紐扣電池型號為 CR1220,安裝時注意正極朝上,取下時用鑷子撥動黃色彈片,即可彈出電池。
部分代碼展示:
//************************************************************************* //Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd,All rights reserved // // File Name : seg_bcd.v // Project Name : // Author : meisq // Email : msq@qq.com // Company : ALINX(shanghai) Technology Co.,Ltd // WEB : http://www.alinx.cn/ //========================================================================== // Description: // // //========================================================================== // Revision History: // Date By Revision Change Description //-------------------------------------------------------------------------- // 2017/6/19 meisq 1.0 Original //*************************************************************************/ module seg_bcd( input clk, input rst_n, output[5:0] seg_sel, output[7:0] seg_data, input [23:0]seg_bcd ); /*Four bits represent a decimal number*/ wire[6:0] seg7_data_0; seg_decoder seg_decoder_m0( .bin_data(seg_bcd[23:20]), .seg_data(seg7_data_0) ); wire[6:0] seg7_data_1; seg_decoder seg_decoder_m1( .bin_data(seg_bcd[19:16]), .seg_data(seg7_data_1) ); wire[6:0] seg7_data_2; seg_decoder seg_decoder_m2( .bin_data(seg_bcd[15:12]), .seg_data(seg7_data_2) ); wire[6:0] seg7_data_3; seg_decoder seg_decoder_m3( .bin_data(seg_bcd[11:8]), .seg_data(seg7_data_3) );
點擊鏈接獲取代碼文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=1346