1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-301505-1-1.html 4)对正点原子FPGA感兴趣的同学可以加群讨论:994244016 5)关注正点原子公众号,获取最新资料更新
PCF8563是一款多功能时钟/日历芯片。因其功耗低、控制简单、封装小而广泛应用于电表、水表、传真机、便携式仪器等产品中。本章我们将使用领航者Zynq开发板上的PCF8563器件实现实时时钟的显示。 本章包括以下几个部分: 1.1 PCF8563简介 1.2 实验任务 1.3 硬件设计 1.4 程序设计 1.5 下载验证 1.1 PCF8563简介 PCF8563是PHILIPS公司推出的一款工业级多功能时钟/日历芯片,具有报警功能、定时器功能、时钟输出功能以及中断输出功能,能完成各种复杂的定时服务。其内部功能模块的框图如下图所示:
图 7.5.13.1 PCF8563功能框图 PCF8563有16个可寻址的8位寄存器,但不是所有位都有用到。前两个寄存器(内存地址00H、01H)用作控制寄存器和状态寄存器(CONTROL_STATUS);内存地址02H08H用作TIME计时器(秒年计时器);地址09H~0CH用于报警(ALARM)寄存器(定义报警条件);地址0DH控制CLKOUT管脚的输出频率;地址0EH和0FH分别用于定时器控制寄存器和定时器寄存器。 秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器中的数据编码格式为BCD,只有星期和星期报警寄存器中的数据不以BCD格式编码。BCD码(Binary-Coded Decimal)是一种二进制的数字编码形式,用四个二进制位来表示一位十进制数(0~9),能够使二进制和十进制之间的转换得以快捷的进行。 PCF8563通过I2C接口与Zynq进行通信。使用该器件时,Zynq先通过I2C接口向该器件相应的寄存器写入初始的时间数据(秒~年),然后通过I2C接口读取相应的寄存器的时间数据。有关I2C总线协议详细的介绍请大家参考“EEPROM读写实验”。 下面我们对本次实验用到的寄存器做简要的描述和说明,其他寄存器的描述和说明,请大家参考PCF8563的数据手册。 秒寄存器的的地址为02h,说明如下表所示: 表 24.1.1 秒寄存器描述(地址02h) Bit 符号 描述 7 VL VL=0保证准确的时钟/日历数据 VL=1不保证准确的时钟/日历数据 6~0 秒 用BCD格式表示的秒数值 当电源电压低于PCF8563器件的最低供电电压时,VL为“1”,表明内部完整的时钟周期信号不能被保证,可能导致时钟/日历数据不准确。 BCD编码的秒数值如下表所示: 表 24.1.2 秒数值的BCD编码
寄存器的地址为03h,说明如下表所示: 表 24.1.3 分钟寄存器描述(地址03h) Bit 符号 描述 7 - 无效 6~0 分钟 用BCD格式表示的分钟值 小时寄存器的地址为04h,说明如下表所示: 表 24.1.4 小时寄存器描述(地址04h) Bit 符号 描述 7~6 - 无效 5~0 小时 用BCD格式表示的小时值 天寄存器的地址为05h,说明如下表所示: 表 24.1.5 天寄存器描述(地址05h) Bit 符号 描述 7~6 - 无效 5~0 天 用BCD格式表示的天数值 当年计数器的值是闰年时,PCF8563自动给二月增加一个值,使其成为29天。 月/世纪寄存器的地址为07h,说明如下表所示: 表 24.1.6 月/世纪寄存器(地址07h) Bit 符号 描述 7 C 当C为0时表明是当前世纪,为1时表明是下一世纪 6~5 - 未用 4~0 月 用BCD格式表示的月数值 表 24.1.7 月份表 月份 Bit4 Bit3 Bit2 Bit1 Bit0 一月 0 0 0 0 1 二月 0 0 0 1 0 三月 0 0 0 1 1 四月 0 0 1 0 0 五月 0 0 1 0 1 六月 0 0 1 1 0 七月 0 0 1 1 1 八月 0 1 0 0 0 九月 0 1 0 0 1 十月 1 0 0 0 0 十一月 1 0 0 0 1 十二月 1 0 0 1 0 年寄存器的地址为08h,说明如下表所示: 表 24.1.8 寄存器(地址08h) Bit 符号 描述 7~0 年 用BCD格式表示的当前年数值,值为00~99 1.2 实验任务 本节的实验任务是通过领航者Zynq开发板上的PCF8563实时时钟芯片,在RGB LCD液晶屏上来显示时间。 1.3 硬件设计 领航者开发板上PCF8563接口部分的原理图如下图所示。
图 7.5.13.1 PCF8563接口原理图 PCF8563作为I2C接口的从器件与EEPROM等模块统一挂接在领航者开发板上的IIC总线上。 OSCI、OSCO与外部32.768KHz的晶振相连,为芯片提供驱动时钟;SCL和SDA分别是I2C总线的串行时钟接口和串行数据接口。 由于本实验中的管脚较多,这里仅给出XDC约束语句,XDC约束语句如下
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
set_property -dict {PACKAGE_PIN E18 IOSTANDARD LVCMOS33} [get_ports iic_scl]
set_property -dict {PACKAGE_PIN F17 IOSTANDARD LVCMOS33} [get_ports iic_sda]
set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[0]}]
set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[1]}]
set_property -dict {PACKAGE_PIN R16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[2]}]
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[3]}]
set_property -dict {PACKAGE_PIN W20 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[4]}]
set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[5]}]
set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[6]}]
set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[7]}]
set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[8]}]
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[9]}]
set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[10]}]
set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[11]}]
set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[12]}]
set_property -dict {PACKAGE_PIN Y19 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[13]}]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[14]}]
set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[15]}]
set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[16]}]
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[17]}]
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[18]}]
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[19]}]
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[20]}]
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[21]}]
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[22]}]
set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVCMOS33} [get_ports {lcd_rgb[23]}]
set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports lcd_hs]
set_property -dict {PACKAGE_PIN T20 IOSTANDARD LVCMOS33} [get_ports lcd_vs]
set_property -dict {PACKAGE_PIN U20 IOSTANDARD LVCMOS33} [get_ports lcd_de]
set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS33} [get_ports lcd_bl]
set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS33} [get_ports lcd_clk]
set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports lcd_rst]
1.4 程序设计 根据实验任务,我们可以大致规划出系统的控制流程:ZYNQ首先通过I2C总线向PCF8563写入初始时间值,然后不断地读取时间数据,并将读到的时间数据显示到LCD上。由此画出系统的功能框图如下所示:
图 7.5.13.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)。 各模块端口及信号连接如图 7.5.13.2所示:
图 7.5.13.2 顶层模块原理图 PCF8563实时时钟控制模块(pcf8563_ctrl)通过与IIC驱动模块(iic_dri)进行通信来实现对PCF8563实时时钟数据的读取;PCF8563实时时钟控制模块(pcf8563_ctrl)再将从IIC读取的时间数据送给LCD字符显示模块(lcd_disp_char),以进行显示。 顶层模块的代码如下:
1 module rtc_lcd(
2 input sys_clk, //系统时钟
3 input sys_rst_n, //系统复位
4
5 //RGB LCD接口
6 output lcd_de, //LCD 数据使能信号
7 output lcd_hs, //LCD 行同步信号
8 output lcd_vs, //LCD 场同步信号
9 output lcd_bl, //LCD 背光控制信号
10 output lcd_clk, //LCD 像素时钟
11 inout [23:0] lcd_rgb, //LCD RGB888颜色数据
12
13 //RTC实时时钟
14 output iic_scl, //RTC的时钟线scl
15 inout iic_sda //RTC的数据线sda
16 );
17
18 //parameter define
19 parameter SLAVE_ADDR = 7'b101_0001 ; //器件地址(SLAVE_ADDR)
20 parameter BIT_CTRL = 1'b0 ; //字地址位控制参数(16b/8b)
21 parameter CLK_FREQ = 26'd50_000_000; //i2c_dri模块的驱动时钟频率(CLK_FREQ)
22 parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率
23 parameter TIME_INIT = 48'h19_01_01_09_30_00;//初始时间
24
25 //wire define
26 wire dri_clk ; //I2C操作时钟
27 wire i2c_exec ; //I2C触发控制
28 wire [15:0] i2c_addr ; //I2C操作地址
29 wire [ 7:0] i2c_data_w; //I2C写入的数据
30 wire i2c_done ; //I2C操作结束标志
31 wire i2c_ack ; //I2C应答标志 0:应答 1:未应答
32 wire i2c_rh_wl ; //I2C读写控制
33 wire [ 7:0] i2c_data_r; //I2C读出的数据
34
35 wire [7:0] sec ; //秒
36 wire [7:0] min ; //分
37 wire [7:0] hour ; //时
38 wire [7:0] day ; //日
39 wire [7:0] mon ; //月
40 wire [7:0] year ; //年
41
42 //*****************************************************
43 //** main code
44 //*****************************************************
45
46 //i2c驱动模块
47 i2c_dri #(
48 .SLAVE_ADDR (SLAVE_ADDR), //EEPROM从机地址
49 .CLK_FREQ (CLK_FREQ ), //模块输入的时钟频率
50 .I2C_FREQ (I2C_FREQ ) //IIC_SCL的时钟频率
51 ) u_i2c_dri(
52 .clk (sys_clk ),
53 .rst_n (sys_rst_n ),
54 //i2c interface
55 .i2c_exec (i2c_exec ),
56 .bit_ctrl (BIT_CTRL ),
57 .i2c_rh_wl (i2c_rh_wl ),
58 .i2c_addr (i2c_addr ),
59 .i2c_data_w (i2c_data_w),
60 .i2c_data_r (i2c_data_r),
61 .i2c_done (i2c_done ),
62 .i2c_ack (i2c_ack ),
63 .scl (iic_scl ),
64 .sda (iic_sda ),
65 //user interface
66 .dri_clk (dri_clk )
67 );
68
69 //PCF8563控制模块
70 pcf8563_ctrl #(
71 .TIME_INIT (TIME_INIT)
72 )u_pcf8563_ctrl(
73 .clk (dri_clk ),
74 .rst_n (sys_rst_n ),
75 //IIC
76 .i2c_rh_wl (i2c_rh_wl ),
77 .i2c_exec (i2c_exec ),
78 .i2c_addr (i2c_addr ),
79 .i2c_data_w (i2c_data_w),
80 .i2c_data_r (i2c_data_r),
81 .i2c_done (i2c_done ),
82 //时间和日期
83 .sec (sec ),
84 .min (min ),
85 .hour (hour ),
86 .day (day ),
87 .mon (mon ),
88 .year (year )
89 );
90
91 //LCD字符显示模块
92 lcd_disp_char u_lcd_disp_char(
93 .sys_clk (sys_clk ),
94 .sys_rst_n (sys_rst_n ),
95 //时间和日期
96 .sec (sec ),
97 .min (min ),
98 .hour (hour ),
99 .day (day ),
100 .mon (mon ),
101 .year (year ),
102 //RGB LCD接口
103 .lcd_de (lcd_de ),
104 .lcd_hs (lcd_hs ),
105 .lcd_vs (lcd_vs ),
106 .lcd_bl (lcd_bl ),
107 .lcd_clk (lcd_clk ),
108 .lcd_rgb (lcd_rgb )
109 );
110
111 endmodule
代码中第18至23行定义了一些参数,其中TIME_INIT表示RTC实时时钟的初始日期和时间,可以通过修改此参数值使PCF8563从不同的时间开始计时,例如从2019年1月1号09:30:00开始计时,需要将该参数值设置为48’h190101093000。 顶层模块中主要完成对其余模块的例化。其中I2C驱动模块(iic_dri)的代码与“EEPROM读写实验”章节中的IIC驱动模块完全相同,只是在例化时对字地址位控制(BIT_CTRL)和IIC器件地址(SLAVE_ADDR)两个参数作了修改,有关IIC驱动模块的详细介绍请大家参考“EEPROM读写实验”。 PCF8563实时时钟控制模块的代码如下所示:
1 module pcf8563_ctrl #(
2 // 初始时间设置,从高到低为年到秒,各占8bit
3 parameter TIME_INIT = 48'h19_10_26_09_30_00)(
4 input clk , //时钟信号
5 input rst_n , //复位信号
6
7 //i2c interface
8 output reg i2c_rh_wl , //I2C读写控制信号
9 output reg i2c_exec , //I2C触发执行信号
10 output reg [15:0] i2c_addr , //I2C器件内地址
11 output reg [7:0] i2c_data_w, //I2C要写的数据
12 input [7:0] i2c_data_r, //I2C读出的数据
13 input i2c_done , //I2C一次操作完成
14
15 //PCF8563T的秒、分、时、日、月、年数据
16 output reg [7:0] sec, //秒
17 output reg [7:0] min, //分
18 output reg [7:0] hour, //时
19 output reg [7:0] day, //日
20 output reg [7:0] mon, //月
21 output reg [7:0] year //年
22 );
23
24 //reg define
25 reg [3:0] flow_cnt ; // 状态流控制
26 reg [12:0] wait_cnt ; // 计数等待
27
28 //*****************************************************
29 //** main code
30 //*****************************************************
31
32 //先向PCF8563中写入初始化日期和时间,再从中读出日期和时间
33 always @(posedge clk or negedge rst_n) begin
34 if(!rst_n) begin
35 sec
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?