名称:ds1302数码管显示RTC时间设计Verilog代码Quartus AX301开发板
软件:Quartus
语言:Verilog
代码功能:
RTC(Real-Time Clock)实时时钟为系统提供一个可靠的时间,并且在断电的情况下,RTC 实时时钟也可以通过电池供电,一直运行下去。RTC 通过类 SPI 总线向 FPGA 传送 8 位数据(BCD 码)。
数据包括秒,分,小时,日期,天,月和年。在本实验中我们将读取 RTC 的时,分,秒的数据并在数码管中显示时间
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
本代码已在AX301开发板验证,AX301开发板如下,其他开发板可以修改管脚适配:
设计文档:
ds1302 数码管显示 RTC 时间实验
1 实验简介
实验通过阅读 DS1302 芯片手册,了解 DS1302 操作时序和相关寄存器,然后设计程序将DS1302 RTC 时间通过数码管显示出来,类似于一个电子钟。
2 实验原理
RTC(Real-Time Clock)实时时钟为系统提供一个可靠的时间,并且在断电的情况下,RTC 实时时钟也可以通过电池供电,一直运行下去。RTC 通过类 SPI 总线向 FPGA 传送 8 位数据(BCD 码)。
数据包括秒,分,小时,日期,天,月和年。在本实验中我们将读取 RTC 的时,分,秒的数据并在数码管中显示时间。
2.1 硬件介绍
AX301/AX4010 开发板上 RTC 设计采用 DALLAS 公司的低功耗实时时钟芯片 DS1302, DS1302 的VCC2 为主电源,VCC1 为后备电源。在主电源关闭的情况下,也能可以通过电池保持时钟的连续运行。DS1302 外接 32.768kHz 晶振为 RTC 电路提供振荡源。 RTC 部分的原理图如下图所示:
2.2 DS1302 时序和控制
2.2.1 写数据时序
DS1302 芯片写操作的时序图。第一个字节是“访问寄存器的地址”,第二字节是“写数据”。 在写操作的时候,都是“上升沿有效”,然而还有一个条件,就是 CE(/RST)信号必须拉高。
(数据都是从 LSB 开始发送,亦即是最低位开始至最高位结束)。
DS1302 写时序
2.2.2 读数据时序
基本上和写操作的时序图大同小异,区别的地方就是在第二个字节是“读数据”的动作。第 二字节读数据开始时,SCLK 信号都是下降沿送出数据,这个时候可以使用上升沿读取数据。CE (/RST)信号同样是必须拉高。(第一节数据是从 LSB 开始输出,第二节数据是从 LSB 开始读 入)。
2.2.3 命令格式和寄存器
无论是读操作还是写操作,在时序图中,第一个字节都是“访问寄存器的地址”,然而这一字 节数据有自己的格式。
BIT 7 固定。 BIT 6 表示是访问寄存器本身,还是访问 RAM 空间。 BIT 5 到 BIT1 表示是寄存器 或 RAM 空间的地址。 BIT 0 表示是访问寄存器本身是写操作,还是读操作。
下图是 DS1302 的寄存器地址和数据格式
3 程序设计
通过分析 DS1302 读写时序,可以看出和 SPI 时序类似,只不过数据输出和输入分时复用了,本实验利用 SPI Flash 读写实验中已经使用过的 SPI Master 模块来做为 DS1302 的底层读写控制模块,然后再编写一个 RTC 读写模块。
ds1302_io 模块完成 DS1302 寄存器读写控制,状态机如下图所示。
状态“S_IDLE”空闲状态,收到读写寄存器请求写进入“S_CE_HIGH”状态,将 CE 拉高,然后根据请求类型,进入读(S_READ)或写状态(S_WRITE)。
“S_WRITE”状态下一个状态进入写地址状态“S_WRITE_ADDR”,再进入写数据状态“S_WRITE_DATA”,完成一个寄存器的写入,最后应答,拉低 CE。
“S_READ”状态下一个状态进入读地址状态“S_READ_ADDR”,再进入读数据状态“S_READ_DATA”,完成一个寄存器的读取,最后应答,拉低 CE。
ds1302_io 状态机
信号名称 |
方向 |
说明 |
clk |
in |
时钟输入 |
rst |
in |
异步复位输入,高复位 |
ds1302_ce |
out |
DS1302 CE,高有效 |
ds1302_sclk |
out |
DS1302 串行时钟 |
ds1302_io |
inout |
DS1302 数据 |
cmd_read |
in |
读寄存器请求,发出请求时准备好地址 |
cmd_write |
in |
写寄存器请求,发出请求时准备好地址和数据 |
cmd_read_ack |
out |
读寄存器应答,应答时读取数据有效 |
cmd_write_ack |
out |
写寄存器应答 |
read_addr |
in |
读寄存器地址 |
write_addr |
in |
写寄存器地址 |
read_data |
out |
读出的数据 |
write_data |
in |
写寄存器数据 |
ds1302_io 端口
ds1302 模块主要完成时间寄存器的读写控制,状态机状态较为简单。
ds1302 模块状态机
信号名称 |
方向 |
说明 |
clk |
in |
时钟输入 |
rst |
in |
异步复位输入,高复位 |
ds1302_ce |
out |
DS1302 CE,高有效 |
ds1302_sclk |
out |
DS1302 串行时钟 |
ds1302_io |
inout |
DS1302 数据 |
write_time_req |
in |
ds1302 写时间请求,请求发出时,时间数据 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 状态检测,CH 位于秒寄存器的 BIT7 位,上电后首先读取时间,判断秒寄存器的 CH 状态,如果为高,表示 DS1302 暂停,状态机进入“S_WRITE_CH”,将 CH 写 0, 并将一个初始时间写入,然后循环不断的读取时间寄存器。
ds1302_test 状态机
信号名称 |
方向 |
说明 |
clk |
in |
时钟输入 |
rst |
in |
异步复位输入,高复位 |
ds1302_ce |
out |
DS1302 CE,高有效 |
ds1302_sclk |
out |
DS1302 串行时钟 |
ds1302_io |
inout |
DS1302 数据 |
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 实验现象
将程序下载到开发板以后,可以看到数码管一个初始时间,然后每秒时间改变一次,如果装有纽扣电池,这个时间会持续走下去,不会因为断电后停止;如果没有纽扣电池,可以在不断电的情况下重新下载程序,时间不会因为程序中断而停止。也可以断电后等待一分钟左右,重新上电,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