本帖最后由 正点原子运营 于 2021-1-19 16:33 编辑
1)实验平台:正点原子超越者FPGA开发板
2)平台购买地址:https://item.taobao.com/item.htm?&id=631660290421
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz-chaoyuezhe.html
4)正点原子FPGA交流群:905624739点击加入:
5)关注正点原子公众号,获取最新资料更新
第二十八章RTC实时时钟LCD显示实验
PCF8563是一款多功能时钟/日历芯片。因其功耗低、控制简单、封装小而广泛应用于电表、水表、传真机、便携式仪器等产品中。本章我们将使用超越者开发板上的PCF8563器件实现实时时钟的显示。
本章包括以下几个部分:
2828.1 简介
28.2 实验任务
28.3 硬件设计
28.4 程序设计
28.5 下载验证
28.1简介
PCF8563是PHILIPS公司推出的一款工业级多功能时钟/日历芯片,具有报警功能、定时器功能、时钟输出功能以及中断输出功能,能完成各种复杂的定时服务。其内部功能模块的框图如下图所示:
图 28.1.1 PCF8563功能框图
PCF8563有16个可寻址的8位寄存器,但不是所有位都有用到。前两个寄存器(内存地址00H、01H)用作控制寄存器和状态寄存器(CONTROL_STATUS);内存地址02H~08H用作TIME计时器(秒~年计时器);地址09H~0CH用于报警(ALARM)寄存器(定义报警条件);地址0DH控制CLKOUT管脚的输出频率;地址0EH和0FH分别用于定时器控制寄存器和定时器寄存器。
秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器中的数据编码格式为BCD,只有星期和星期报警寄存器中的数据不以BCD格式编码。BCD码(Binary-Coded Decimal‎)是一种二进制的数字编码形式,用四个二进制位来表示一位十进制数(0~9),能够使二进制和十进制之间的转换得以快捷的进行。
PCF8563通过I2C接口与FPGA芯片进行通信。使用该器件时,FPGA芯片先通过I2C接口向该器件相应的寄存器写入初始的时间数据(秒~年),然后通过I2C接口读取相应的寄存器的时间数据。有关I2C总线协议详细的介绍请大家参考“EEPROM读写实验”。
下面对本次实验用到的寄存器做简要的描述和说明,其他寄存器的描述和说明,请大家参考PCF8563的数据手册。
秒寄存器的地址为02h,说明如下表所示:
表 28.1.1 秒寄存器描述(地址02h)
当电源电压低于PCF8563器件的最低供电电压时,VL为“1”,表明内部完整的时钟周期信号不能被保证,可能导致时钟/日历数据不准确。
BCD编码的秒数值如下图所示:
图 28.1.2 秒数值的BCD编码
分寄存器的地址为03h,说明如下表所示:
表 28.1.2 分钟寄存器描述(地址03h)
小时寄存器的地址为04h,说明如下表所示:
表 28.1.3 小时寄存器描述(地址04h)
天寄存器的地址为05h,说明如下表所示:
表 28.1.4 天寄存器描述(地址05h)
当年计数器的值是闰年时,PCF8563自动给二月增加一个值,使其成为29天。
月/世纪寄存器的地址为07h,说明如下表所示:
表 28.1.5 月/世纪寄存器(地址07h)
表 28.1.6 月份表
表 28.1.7 寄存器(地址08h)
28.2实验任务
本节的实验任务是通过超越者开发板上的PCF8563实时时钟芯片,在RGB-LCD液晶屏上来显示时间。
28.3硬件设计
超越者开发板上PCF8563接口部分的原理图如下图所示。
图 28.3.1 PCF8563接口原理图
PCF8563作为I2C接口的从器件与EEPROM等模块统一挂接在超越者开发板上的IIC总线上。 OSCI、OSCO与外部32.768KHz的晶振相连,为芯片提供驱动时钟;SCL和SDA分别是I2C总线的串行时钟接口和串行数据接口。
由于本实验中的管脚较多,这里仅仅给出部分管脚的分配信息,具体是时钟,复位,SCL和SDA,如下表所示。其他的管脚分配请大家参考“RGB-LCD彩条显示实验”。
表 28.3.1 RTC实时时钟部分管脚分配
对应的约束语句:
NET "sys_clk" LOC = N8 | IOSTANDARD = "LVCMOS33";
NET "sys_rst_n" LOC = G16 | IOSTANDARD = "LVCMOS33";
NET iic_scl LOC = T4 | IOSTANDARD = "LVCMOS33";
NET iic_sda LOC = R5 | IOSTANDARD = "LVCMOS33";
28.4程序设计
根据实验任务,我们可以大致规划出系统的控制流程:首先通过I2C总线向PCF8563写入初始时间值,然后不断地读取时间数据,并将读到的时间数据显示到LCD上。由此画出系统的功能框图如下所示:
图 28.4.1 PCF8563T实时时钟LCD显示系统框图
由系统框图可知,顶层模块(rtc_lcd)例化了以下三个模块,分别是IIC驱动模块(iic_dri)、PCF8563控制模块(pcf8563_ctrl)和LCD字符显示模块(lcd_disp_char)。其中LCD字符显示模块例化了读取ID模块(rd_id)、时钟分频模块(clk_div)、LCD显示模块(lcd_display)以及LCD驱动模块(lcd_driver)。
PCF8563实时时钟控制模块(pcf8563_ctrl)通过与IIC驱动模块(iic_dri)进行通信来实现对PCF8563实时时钟数据的读取;PCF8563实时时钟控制模块(pcf8563_ctrl)再将从IIC读取的时间数据送给LCD字符显示模块(lcd_disp_char),以进行显示。
顶层模块的代码如下:
代码中第18至23行定义了一些参数,其中TIME_INIT表示RTC实时时钟的初始日期和时间,可以通过修改此参数值使PCF8563从不同的时间开始计时,例如从2020年1月1号09:30:00开始计时,需要将该参数值设置为48’h200101093000。
顶层模块中主要完成对其余模块的例化。其中I2C驱动模块(iic_dri)的代码与“EEPROM读写实验”章节中的IIC驱动模块完全相同,只是在例化时对字地址位控制(BIT_CTRL)和IIC器件地址(SLAVE_ADDR)两个参数作了修改,有关IIC驱动模块的详细介绍请大家参考“EEPROM读写实验”。
PCF8563实时时钟控制模块的代码如下所示:
程序中定义了一个状态流控制计数器(flow_cnt),先将初始日期和时间(TIME_INIT)写入PCF8563中,然后会循环从PCF8563中读出秒、分、时、日、月和年。在写操作是i2c_rh_wl(I2C读写控制信号)为低电平,读操作时拉高i2c_rh_wl信号。
LCD字符显示模块(lcd_disp_char)的代码由“RGB-LCD字符和图片显示”实验的代码修改而来,除lcd_disp_char顶层模块外,唯一不同的地方在LCD显示模块。
LCD显示模块的代码如下所示:
我们的显示内容首先分成两行,第一行显示年月日,第二行显示时分秒。程序中第19至28行代码定义了一些参数,前4个参数定义每一行字符显示的参考点,结合具体参数值我们知道:第一行是(1,1),第二行是(17,17),接着后面两个参数分别定义了每一行各自显示的宽度(长度),分别是80和64,最后两个参数定义了字符的颜色和背景色,字符颜色为黑色,背景色为白色。
代码第38到49行定义了0到9每个阿拉伯数字所对应的数组,具体的每个数组的字模数据都是一个长度为128的数组,实际上我们把二维数组的所有数据都放在了第一行上,使用时把它看成一个二维数组,大小为16*8bit,16行,每一行有8位数据。
代码第57到67行是一个具体的字符显示的逻辑。首先判断当前像素坐标的位置,如代码第58到61行,如果处在字符显示的区域则开始根据字符数组值来显示像素。显示时,数组参数pixel_xpos,pixel_ypos分别从小到大取不同的值时,代入数组,此时我们实际上就是在从左到右,从上到下扫描一个字符像素平面,pixel_xpos变化对于行扫描,pixel_ypos则对于列扫描。
对于62行的代码 “ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8”,我们不难理解“*8”的由来,因为在查找数组元素的时候,pixel_ypos的每次变化代表换到下一行扫描,一行跨过8个数据,所有乘以8. 这里就可总结一下:字符数组一行的128个数据从高位到低位,每8位代表另一行,分别对应点阵中该行从左向右的每一个像素点。
62行到63行是对数组的每个元素分别赋值,具体是数组元素为1的点赋值为黑色,否则为白色。
往下,每一个字符显示逻辑的分析和上面类似,请大家自行分析。
程序中第37至49行代码初始化字符数组的值,即数字“0”~“9”的字模数据,由取模软件生成,先将软件设置成字符模式,取模软件的设置如下:
图 28.4.2 字符软件设置
这里将点阵设置为16,即一个数字的字符用一行来表示。
生成字模的界面如下:
图 28.4.3 生成字模的软件设置
程序中第51行至260行代码根据输入的日期、时间和字符区域的坐标显示在LCD上,字符颜色为黑色,背景色为白色。
|