OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6684|回复: 0

[XILINX] 【正点原子FPGA连载】第二十八章RTC实时时钟LCD显示实验--摘自【正点原子】超越者之FPGA开发指南

[复制链接]

1107

主题

1118

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4615
金钱
4615
注册时间
2019-5-8
在线时间
1218 小时
发表于 2021-1-19 16:26:33 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 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点击加入: QQ群头像.png
5)关注正点原子公众号,获取最新资料更新

100846rel79a9p4uelap24.jpg
100846f1ce1fg14zbg0va4.png
第二十八章RTC实时时钟LCD显示实验


PCF8563是一款多功能时钟/日历芯片。因其功耗低、控制简单、封装小而广泛应用于电表、水表、传真机、便携式仪器等产品中。本章我们将使用超越者开发板上的PCF8563器件实现实时时钟的显示。
本章包括以下几个部分:
2828.1  简介
28.2  实验任务
28.3  硬件设计
28.4  程序设计
28.5  下载验证


28.1简介
PCF8563是PHILIPS公司推出的一款工业级多功能时钟/日历芯片,具有报警功能、定时器功能、时钟输出功能以及中断输出功能,能完成各种复杂的定时服务。其内部功能模块的框图如下图所示:
28256.png

图 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)
2811.png

当电源电压低于PCF8563器件的最低供电电压时,VL为“1”,表明内部完整的时钟周期信号不能被保证,可能导致时钟/日历数据不准确。
BCD编码的秒数值如下图所示:
281095.png

图 28.1.2 秒数值的BCD编码

分寄存器的地址为03h,说明如下表所示:
表 28.1.2 分钟寄存器描述(地址03h)
28121.png

小时寄存器的地址为04h,说明如下表所示:
表 28.1.3 小时寄存器描述(地址04h)
2813.png

天寄存器的地址为05h,说明如下表所示:
表 28.1.4 天寄存器描述(地址05h)
2814.png

当年计数器的值是闰年时,PCF8563自动给二月增加一个值,使其成为29天。
月/世纪寄存器的地址为07h,说明如下表所示:
表 28.1.5 月/世纪寄存器(地址07h)
2815.png

表 28.1.6 月份表
2816.png

表 28.1.7 寄存器(地址08h)
2817.png

28.2实验任务
本节的实验任务是通过超越者开发板上的PCF8563实时时钟芯片,在RGB-LCD液晶屏上来显示时间。
28.3硬件设计
超越者开发板上PCF8563接口部分的原理图如下图所示。
282216.png

图 28.3.1 PCF8563接口原理图

PCF8563作为I2C接口的从器件与EEPROM等模块统一挂接在超越者开发板上的IIC总线上。 OSCI、OSCO与外部32.768KHz的晶振相连,为芯片提供驱动时钟;SCL和SDA分别是I2C总线的串行时钟接口和串行数据接口。
由于本实验中的管脚较多,这里仅仅给出部分管脚的分配信息,具体是时钟,复位,SCL和SDA,如下表所示。其他的管脚分配请大家参考“RGB-LCD彩条显示实验”。
表 28.3.1 RTC实时时钟部分管脚分配
2831.png

对应的约束语句:
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上。由此画出系统的功能框图如下所示:
283095.png

图 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),以进行显示。
顶层模块的代码如下:
  1. <font size="4">1   module rtc_lcd(</font>
  2. <font size="4">2       input                sys_clk,     //系统时钟</font>
  3. <font size="4">3       input                sys_rst_n,   //系统复位</font>
  4. <font size="4">4   </font>
  5. <font size="4">5       //RGB LCD接口</font>
  6. <font size="4">6       output               lcd_de,      //LCD 数据使能信号</font>
  7. <font size="4">7       output               lcd_hs,      //LCD 行同步信号</font>
  8. <font size="4">8       output               lcd_vs,      //LCD 场同步信号</font>
  9. <font size="4">9       output               lcd_bl,      //LCD 背光控制信号</font>
  10. <font size="4">10      output               lcd_clk,     //LCD 像素时钟  </font>
  11. <font size="4">11      inout        [23:0]  lcd_rgb,     //LCD RGB888颜色数据</font>
  12. <font size="4">12      </font>
  13. <font size="4">13      //RTC实时时钟</font>
  14. <font size="4">14      output               iic_scl,     //RTC的时钟线scl</font>
  15. <font size="4">15      inout                iic_sda      //RTC的数据线sda    </font>
  16. <font size="4">16      );                                                      </font>
  17. <font size="4">17  </font>
  18. <font size="4">18  //parameter define</font>
  19. <font size="4">19  parameter    SLAVE_ADDR = 7'b101_0001   ; //器件地址(SLAVE_ADDR)</font>
  20. <font size="4">20  parameter    BIT_CTRL   = 1'b0          ; //字地址位控制参数(16b/8b)</font>
  21. <font size="4">21  parameter    CLK_FREQ   = 26'd50_000_000; //i2c_dri模块的驱动时钟频率(CLK_FREQ)</font>
  22. <font size="4">22  parameter    I2C_FREQ   = 18'd250_000   ; //I2C的SCL时钟频率</font>
  23. <font size="4">23  parameter    TIME_INIT  = 48'h20_01_01_09_30_00;//初始时间</font>
  24. <font size="4">24  </font>
  25. <font size="4">25  //wire define</font>
  26. <font size="4">26  wire          dri_clk   ;   //I2C操作时钟</font>
  27. <font size="4">27  wire          i2c_exec  ;   //I2C触发控制</font>
  28. <font size="4">28  wire  [15:0]  i2c_addr  ;   //I2C操作地址</font>
  29. <font size="4">29  wire  [ 7:0]  i2c_data_w;   //I2C写入的数据</font>
  30. <font size="4">30  wire          i2c_done  ;   //I2C操作结束标志</font>
  31. <font size="4">31  wire          i2c_ack   ;   //I2C应答标志 0:应答 1:未应答</font>
  32. <font size="4">32  wire          i2c_rh_wl ;   //I2C读写控制</font>
  33. <font size="4">33  wire  [ 7:0]  i2c_data_r;   //I2C读出的数据</font>
  34. <font size="4">34  </font>
  35. <font size="4">35  wire    [7:0]  sec      ;   //秒</font>
  36. <font size="4">36  wire    [7:0]  min      ;   //分</font>
  37. <font size="4">37  wire    [7:0]  hour     ;   //时</font>
  38. <font size="4">38  wire    [7:0]  day      ;   //日</font>
  39. <font size="4">39  wire    [7:0]  mon      ;   //月</font>
  40. <font size="4">40  wire    [7:0]  year     ;   //年</font>
  41. <font size="4">41  wire           clk_100m ;</font>
  42. <font size="4">42  wire           clk_50m  ; </font>
  43. <font size="4">43  //*****************************************************</font>
  44. <font size="4">44  //**                    main code</font>
  45. <font size="4">45  //*****************************************************</font>
  46. <font size="4">46  </font>
  47. <font size="4">47  pll instance_name</font>
  48. <font size="4">48  (// Clock in ports</font>
  49. <font size="4">49      .CLK_IN1(sys_clk),      // IN</font>
  50. <font size="4">50      // Clock out ports</font>
  51. <font size="4">51      .CLK_OUT1(clk_100m),     // OUT</font>
  52. <font size="4">52      .CLK_OUT2(clk_50m));    // OUT</font>
  53. <font size="4">53  </font>
  54. <font size="4">54  //i2c驱动模块</font>
  55. <font size="4">55  i2c_dri #(</font>
  56. <font size="4">56      .SLAVE_ADDR  (SLAVE_ADDR),  //EEPROM从机地址</font>
  57. <font size="4">57      .CLK_FREQ    (CLK_FREQ  ),  //模块输入的时钟频率</font>
  58. <font size="4">58      .I2C_FREQ    (I2C_FREQ  )   //IIC_SCL的时钟频率</font>
  59. <font size="4">59  ) u_i2c_dri(</font>
  60. <font size="4">60      .clk         (clk_50m   ),  </font>
  61. <font size="4">61      .rst_n       (sys_rst_n ),  </font>
  62. <font size="4">62      //i2c interface</font>
  63. <font size="4">63      .i2c_exec    (i2c_exec  ), </font>
  64. <font size="4">64      .bit_ctrl    (BIT_CTRL  ), </font>
  65. <font size="4">65      .i2c_rh_wl   (i2c_rh_wl ), </font>
  66. <font size="4">66      .i2c_addr    (i2c_addr  ), </font>
  67. <font size="4">67      .i2c_data_w  (i2c_data_w), </font>
  68. <font size="4">68      .i2c_data_r  (i2c_data_r), </font>
  69. <font size="4">69      .i2c_done    (i2c_done  ), </font>
  70. <font size="4">70      .i2c_ack     (i2c_ack   ), </font>
  71. <font size="4">71      .scl         (iic_scl   ), </font>
  72. <font size="4">72      .sda         (iic_sda   ), </font>
  73. <font size="4">73      //user interface</font>
  74. <font size="4">74      .dri_clk     (dri_clk   )  </font>
  75. <font size="4">75  );</font>
  76. <font size="4">76  </font>
  77. <font size="4">77  //PCF8563控制模块</font>
  78. <font size="4">78  pcf8563_ctrl #(</font>
  79. <font size="4">79      .TIME_INIT (TIME_INIT)</font>
  80. <font size="4">80  )u_pcf8563_ctrl(</font>
  81. <font size="4">81      .clk         (dri_clk   ),</font>
  82. <font size="4">82      .rst_n       (sys_rst_n ),</font>
  83. <font size="4">83      //IIC</font>
  84. <font size="4">84      .i2c_rh_wl   (i2c_rh_wl ),</font>
  85. <font size="4">85      .i2c_exec    (i2c_exec  ),</font>
  86. <font size="4">86      .i2c_addr    (i2c_addr  ),</font>
  87. <font size="4">87      .i2c_data_w  (i2c_data_w),</font>
  88. <font size="4">88      .i2c_data_r  (i2c_data_r),</font>
  89. <font size="4">89      .i2c_done    (i2c_done  ),</font>
  90. <font size="4">90      //时间和日期</font>
  91. <font size="4">91      .sec         (sec       ),</font>
  92. <font size="4">92      .min         (min       ),</font>
  93. <font size="4">93      .hour        (hour      ),</font>
  94. <font size="4">94      .day         (day       ),</font>
  95. <font size="4">95      .mon         (mon       ),</font>
  96. <font size="4">96      .year        (year      )</font>
  97. <font size="4">97      );</font>
  98. <font size="4">98  </font>
  99. <font size="4">99  //LCD字符显示模块</font>
  100. <font size="4">100 lcd_disp_char u_lcd_disp_char(</font>
  101. <font size="4">101     .sys_clk     (clk_100m   ),</font>
  102. <font size="4">102     .sys_rst_n   (sys_rst_n ),</font>
  103. <font size="4">103     //时间和日期</font>
  104. <font size="4">104     .sec         (sec       ),</font>
  105. <font size="4">105     .min         (min       ),</font>
  106. <font size="4">106     .hour        (hour      ),</font>
  107. <font size="4">107     .day         (day       ),</font>
  108. <font size="4">108     .mon         (mon       ),</font>
  109. <font size="4">109     .year        (year      ),</font>
  110. <font size="4">110     //RGB LCD接口</font>
  111. <font size="4">111     .lcd_de      (lcd_de    ),</font>
  112. <font size="4">112     .lcd_hs      (lcd_hs    ),</font>
  113. <font size="4">113     .lcd_vs      (lcd_vs    ),</font>
  114. <font size="4">114     .lcd_bl      (lcd_bl    ),    </font>
  115. <font size="4">115     .lcd_clk     (lcd_clk   ),</font>
  116. <font size="4">116     .lcd_rgb     (lcd_rgb   )</font>
  117. <font size="4">117     );</font>
  118. <font size="4">118 </font>
  119. <font size="4">119 endmodule</font>
复制代码

代码中第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实时时钟控制模块的代码如下所示:
  1. <font size="4">1   module pcf8563_ctrl #(</font>
  2. <font size="4">2       // 初始时间设置,从高到低为年到秒,各占8bit</font>
  3. <font size="4">3       parameter  TIME_INIT = 48'h20_10_26_09_30_00)(</font>
  4. <font size="4">4       input                 clk       , //时钟信号</font>
  5. <font size="4">5       input                 rst_n     , //复位信号</font>
  6. <font size="4">6   </font>
  7. <font size="4">7       //i2c interface</font>
  8. <font size="4">8       output   reg          i2c_rh_wl , //I2C读写控制信号</font>
  9. <font size="4">9       output   reg          i2c_exec  , //I2C触发执行信号</font>
  10. <font size="4">10      output   reg  [15:0]  i2c_addr  , //I2C器件内地址</font>
  11. <font size="4">11      output   reg  [7:0]   i2c_data_w, //I2C要写的数据</font>
  12. <font size="4">12      input         [7:0]   i2c_data_r, //I2C读出的数据</font>
  13. <font size="4">13      input                 i2c_done  , //I2C一次操作完成</font>
  14. <font size="4">14  </font>
  15. <font size="4">15      //PCF8563T的秒、分、时、日、月、年数据</font>
  16. <font size="4">16      output   reg   [7:0]  sec,        //秒</font>
  17. <font size="4">17      output   reg   [7:0]  min,        //分</font>
  18. <font size="4">18      output   reg   [7:0]  hour,       //时</font>
  19. <font size="4">19      output   reg   [7:0]  day,        //日</font>
  20. <font size="4">20      output   reg   [7:0]  mon,        //月</font>
  21. <font size="4">21      output   reg   [7:0]  year        //年</font>
  22. <font size="4">22  );</font>
  23. <font size="4">23  </font>
  24. <font size="4">24  //reg define</font>
  25. <font size="4">25  reg   [3:0]     flow_cnt  ;            // 状态流控制</font>
  26. <font size="4">26  reg   [12:0]    wait_cnt  ;            // 计数等待</font>
  27. <font size="4">27  </font>
  28. <font size="4">28  //*****************************************************</font>
  29. <font size="4">29  //**                    main code</font>
  30. <font size="4">30  //*****************************************************</font>
  31. <font size="4">31  </font>
  32. <font size="4">32  //先向PCF8563中写入初始化日期和时间,再从中读出日期和时间</font>
  33. <font size="4">33  always @(posedge clk or negedge rst_n) begin</font>
  34. <font size="4">34      if(!rst_n) begin</font>
  35. <font size="4">35          sec        <= 8'h0;</font>
  36. <font size="4">36          min        <= 8'h0;</font>
  37. <font size="4">37          hour       <= 8'h0;</font>
  38. <font size="4">38          day        <= 8'h0;</font>
  39. <font size="4">39          mon        <= 8'h0;</font>
  40. <font size="4">40          year       <= 8'h0;</font>
  41. <font size="4">41          i2c_exec   <= 1'b0;</font>
  42. <font size="4">42          i2c_rh_wl  <= 1'b0;</font>
  43. <font size="4">43          i2c_addr   <= 8'd0;</font>
  44. <font size="4">44          i2c_data_w <= 8'd0;</font>
  45. <font size="4">45          flow_cnt   <= 4'd0;</font>
  46. <font size="4">46          wait_cnt   <= 13'd0;</font>
  47. <font size="4">47      end</font>
  48. <font size="4">48      else begin</font>
  49. <font size="4">49          i2c_exec <= 1'b0;</font>
  50. <font size="4">50          case(flow_cnt)</font>
  51. <font size="4">51              //上电初始化</font>
  52. <font size="4">52              4'd0: begin</font>
  53. <font size="4">53                  if(wait_cnt == 13'd8000) begin</font>
  54. <font size="4">54                      wait_cnt<= 12'd0;</font>
  55. <font size="4">55                      flow_cnt<= flow_cnt + 1'b1;</font>
  56. <font size="4">56                  end</font>
  57. <font size="4">57                  else</font>
  58. <font size="4">58                      wait_cnt<= wait_cnt + 1'b1;</font>
  59. <font size="4">59              end</font>
  60. <font size="4">60              //写读秒</font>
  61. <font size="4">61              4'd1: begin</font>
  62. <font size="4">62                  i2c_exec  <= 1'b1;</font>
  63. <font size="4">63                  i2c_addr  <= 8'h02;</font>
  64. <font size="4">64                  flow_cnt  <= flow_cnt + 1'b1;</font>
  65. <font size="4">65                  i2c_data_w<= TIME_INIT[7:0];</font>
  66. <font size="4">66              end</font>
  67. <font size="4">67              4'd2: begin</font>
  68. <font size="4">68                  if(i2c_done == 1'b1) begin</font>
  69. <font size="4">69                      sec     <= i2c_data_r[6:0];</font>
  70. <font size="4">70                      flow_cnt<= flow_cnt + 1'b1;</font>
  71. <font size="4">71                  end</font>
  72. <font size="4">72              end</font>
  73. <font size="4">73              //写读分</font>
  74. <font size="4">74              4'd3: begin</font>
  75. <font size="4">75                  i2c_exec  <= 1'b1;</font>
  76. <font size="4">76                  i2c_addr  <= 8'h03;</font>
  77. <font size="4">77                  flow_cnt  <= flow_cnt + 1'b1;</font>
  78. <font size="4">78                  i2c_data_w<= TIME_INIT[15:8];</font>
  79. <font size="4">79              end</font>
  80. <font size="4">80              4'd4: begin</font>
  81. <font size="4">81                  if(i2c_done == 1'b1) begin</font>
  82. <font size="4">82                      min     <= i2c_data_r[6:0];</font>
  83. <font size="4">83                      flow_cnt<= flow_cnt + 1'b1;</font>
  84. <font size="4">84                  end</font>
  85. <font size="4">85              end</font>
  86. <font size="4">86              //写读时</font>
  87. <font size="4">87              4'd5: begin</font>
  88. <font size="4">88                  i2c_exec  <= 1'b1;</font>
  89. <font size="4">89                  i2c_addr  <= 8'h04;</font>
  90. <font size="4">90                  flow_cnt  <= flow_cnt + 1'b1;</font>
  91. <font size="4">91                  i2c_data_w<= TIME_INIT[23:16];</font>
  92. <font size="4">92              end</font>
  93. <font size="4">93              4'd6: begin</font>
  94. <font size="4">94                  if(i2c_done == 1'b1) begin</font>
  95. <font size="4">95                      hour    <= i2c_data_r[5:0];</font>
  96. <font size="4">96                      flow_cnt<= flow_cnt + 1'b1;</font>
  97. <font size="4">97                  end</font>
  98. <font size="4">98              end</font>
  99. <font size="4">99              //写读天</font>
  100. <font size="4">100             4'd7: begin</font>
  101. <font size="4">101                 i2c_exec  <= 1'b1;</font>
  102. <font size="4">102                 i2c_addr  <= 8'h05;</font>
  103. <font size="4">103                 flow_cnt  <= flow_cnt + 1'b1;</font>
  104. <font size="4">104                 i2c_data_w<= TIME_INIT[31:24];</font>
  105. <font size="4">105             end</font>
  106. <font size="4">106             4'd8: begin</font>
  107. <font size="4">107                 if(i2c_done == 1'b1) begin</font>
  108. <font size="4">108                     day     <= i2c_data_r[5:0];</font>
  109. <font size="4">109                     flow_cnt<= flow_cnt + 1'b1;</font>
  110. <font size="4">110                 end</font>
  111. <font size="4">111             end</font>
  112. <font size="4">112             //写读月</font>
  113. <font size="4">113             4'd9: begin</font>
  114. <font size="4">114                 i2c_exec  <= 1'b1;</font>
  115. <font size="4">115                 i2c_addr  <= 8'h07;</font>
  116. <font size="4">116                 flow_cnt  <= flow_cnt + 1'b1;</font>
  117. <font size="4">117                 i2c_data_w<= TIME_INIT[39:32];</font>
  118. <font size="4">118             end</font>
  119. <font size="4">119             4'd10: begin</font>
  120. <font size="4">120                 if(i2c_done == 1'b1) begin</font>
  121. <font size="4">121                     mon     <= i2c_data_r[4:0];</font>
  122. <font size="4">122                     flow_cnt<= flow_cnt + 1'b1;</font>
  123. <font size="4">123                 end</font>
  124. <font size="4">124             end</font>
  125. <font size="4">125             //写读年</font>
  126. <font size="4">126             4'd11: begin</font>
  127. <font size="4">127                 i2c_exec  <= 1'b1;</font>
  128. <font size="4">128                 i2c_addr  <= 8'h08;</font>
  129. <font size="4">129                 flow_cnt  <= flow_cnt + 1'b1;</font>
  130. <font size="4">130                 i2c_data_w<= TIME_INIT[47:40];</font>
  131. <font size="4">131             end</font>
  132. <font size="4">132             4'd12: begin</font>
  133. <font size="4">133                 if(i2c_done == 1'b1) begin</font>
  134. <font size="4">134                     year     <= i2c_data_r;</font>
  135. <font size="4">135                     i2c_rh_wl<= 1'b1;</font>
  136. <font size="4">136                     flow_cnt <= 4'd1;</font>
  137. <font size="4">137                 end</font>
  138. <font size="4">138             end</font>
  139. <font size="4">139             default: flow_cnt <= 4'd0;</font>
  140. <font size="4">140         endcase</font>
  141. <font size="4">141     end</font>
  142. <font size="4">142 end</font>
  143. <font size="4">143 </font>
  144. <font size="4">144 endmodule</font>
复制代码

程序中定义了一个状态流控制计数器(flow_cnt),先将初始日期和时间(TIME_INIT)写入PCF8563中,然后会循环从PCF8563中读出秒、分、时、日、月和年。在写操作是i2c_rh_wl(I2C读写控制信号)为低电平,读操作时拉高i2c_rh_wl信号。
LCD字符显示模块(lcd_disp_char)的代码由“RGB-LCD字符和图片显示”实验的代码修改而来,除lcd_disp_char顶层模块外,唯一不同的地方在LCD显示模块。
LCD显示模块的代码如下所示:
  1. <font size="4">1   module lcd_display(</font>
  2. <font size="4">2       input                lcd_pclk ,</font>
  3. <font size="4">3       input                rst_n ,</font>
  4. <font size="4">4       </font>
  5. <font size="4">5       //日历数据</font>
  6. <font size="4">6       input         [7:0]  sec,        //秒</font>
  7. <font size="4">7       input         [7:0]  min,        //分</font>
  8. <font size="4">8       input         [7:0]  hour,       //时</font>
  9. <font size="4">9       input         [7:0]  day,        //日</font>
  10. <font size="4">10      input         [7:0]  mon,        //月</font>
  11. <font size="4">11      input         [7:0]  year,       //年</font>
  12. <font size="4">12      </font>
  13. <font size="4">13      //LCD数据接口</font>
  14. <font size="4">14      input        [10:0]  pixel_xpos, //像素点横坐标</font>
  15. <font size="4">15      input        [10:0]  pixel_ypos, //像素点纵坐标</font>
  16. <font size="4">16      output  reg  [23:0]  pixel_data  //像素点数据</font>
  17. <font size="4">17  );</font>
  18. <font size="4">18  </font>
  19. <font size="4">19  //parameter define</font>
  20. <font size="4">20  localparam CHAR_POS_X_1  = 11'd1;  //第1行字符区域起始点横坐标</font>
  21. <font size="4">21  localparam CHAR_POS_Y_1  = 11'd1;  //第1行字符区域起始点纵坐标</font>
  22. <font size="4">22  localparam CHAR_POS_X_2  = 11'd17; //第2行字符区域起始点横坐标</font>
  23. <font size="4">23  localparam CHAR_POS_Y_2  = 11'd17; //第2行字符区域起始点纵坐标</font>
  24. <font size="4">24  localparam CHAR_WIDTH_1  = 11'd80; //第1行字符区域的宽度,第1行共10个字符(加空格)</font>
  25. <font size="4">25  localparam CHAR_WIDTH_2  = 11'd64; //第2行字符区域的宽度,第2行共8个字符(加空格)</font>
  26. <font size="4">26  localparam CHAR_HEIGHT   = 11'd16; //单个字符的高度</font>
  27. <font size="4">27  localparam WHITE  = 24'hffffff;    //背景色,白色</font>
  28. <font size="4">28  localparam BLACK  = 24'h000000;    //字符颜色,黑色</font>
  29. <font size="4">29  </font>
  30. <font size="4">30  //reg define</font>
  31. <font size="4">31  reg  [127:0]  char  [9:0] ;        //字符数组</font>
  32. <font size="4">32  </font>
  33. <font size="4">33  //*****************************************************</font>
  34. <font size="4">34  //**                    main code</font>
  35. <font size="4">35  //*****************************************************</font>
  36. <font size="4">36  </font>
  37. <font size="4">37  //字符数组初始值,用于存储字模数据(由取模软件生成,单个数字字体大小:16*8)</font>
  38. <font size="4">38  always @(posedge lcd_pclk ) begin</font>
  39. <font size="4">39      char[0] <= 128'h00000018244242424242424224180000 ;  // "0"</font>
  40. <font size="4">40      char[1] <= 128'h000000107010101010101010107C0000 ;  // "1"</font>
  41. <font size="4">41      char[2] <= 128'h0000003C4242420404081020427E0000 ;  // "2"</font>
  42. <font size="4">42      char[3] <= 128'h0000003C424204180402024244380000 ;  // "3"</font>
  43. <font size="4">43      char[4] <= 128'h000000040C14242444447E04041E0000 ;  // "4"</font>
  44. <font size="4">44      char[5] <= 128'h0000007E404040586402024244380000 ;  // "5"</font>
  45. <font size="4">45      char[6] <= 128'h0000001C244040586442424224180000 ;  // "6"</font>
  46. <font size="4">46      char[7] <= 128'h0000007E444408081010101010100000 ;  // "7"</font>
  47. <font size="4">47      char[8] <= 128'h0000003C4242422418244242423C0000 ;  // "8"</font>
  48. <font size="4">48      char[9] <= 128'h0000001824424242261A020224380000 ;  // "9"</font>
  49. <font size="4">49  end</font>
  50. <font size="4">50  </font>
  51. <font size="4">51  //不同的区域绘制不同的像素数据</font>
  52. <font size="4">52  always @(posedge lcd_pclk or negedge rst_n ) begin</font>
  53. <font size="4">53      if (!rst_n)  begin</font>
  54. <font size="4">54          pixel_data <= BLACK;</font>
  55. <font size="4">55      end</font>
  56. <font size="4">56      </font>
  57. <font size="4">57      //在第一行显示年的千位 固定值"2"</font>
  58. <font size="4">58      else if(     (pixel_xpos >= CHAR_POS_X_1)                    </font>
  59. <font size="4">59                && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*1)</font>
  60. <font size="4">60                && (pixel_ypos >= CHAR_POS_Y_1)                    </font>
  61. <font size="4">61                && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  62. <font size="4">62          if(char [2] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  63. <font size="4">63                        - (pixel_xpos-CHAR_POS_X_1) -1 ] )  </font>
  64. <font size="4">64              pixel_data <= BLACK;         //显示字符为黑色</font>
  65. <font size="4">65          else</font>
  66. <font size="4">66              pixel_data <= WHITE;        //显示字符区域背景为白色</font>
  67. <font size="4">67      end</font>
  68. <font size="4">68      </font>
  69. <font size="4">69      //在第一行显示年的百位 固定值"0"</font>
  70. <font size="4">70      else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*1) </font>
  71. <font size="4">71                && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*2)</font>
  72. <font size="4">72                && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  73. <font size="4">73                && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  74. <font size="4">74          if(char [0] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  75. <font size="4">75                      - (pixel_xpos-(CHAR_POS_X_1 + CHAR_WIDTH_1/10*1)) -1 ])</font>
  76. <font size="4">76              pixel_data <= BLACK;</font>
  77. <font size="4">77          else</font>
  78. <font size="4">78              pixel_data <= WHITE;</font>
  79. <font size="4">79      end</font>
  80. <font size="4">80      </font>
  81. <font size="4">81      //在第一行显示年的十位</font>
  82. <font size="4">82      else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*2) </font>
  83. <font size="4">83                && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*3)</font>
  84. <font size="4">84                && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  85. <font size="4">85                && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  86. <font size="4">86          if(char [year[7:4]] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  87. <font size="4">87                                - (pixel_xpos-(CHAR_POS_X_1 + CHAR_WIDTH_1/10*2)) -1 ])</font>
  88. <font size="4">88              pixel_data <= BLACK;</font>
  89. <font size="4">89          else</font>
  90. <font size="4">90              pixel_data <= WHITE;</font>
  91. <font size="4">91      end</font>
  92. <font size="4">92      </font>
  93. <font size="4">93      //在第一行显示年的个位</font>
  94. <font size="4">94      else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*3) </font>
  95. <font size="4">95                && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*4)</font>
  96. <font size="4">96                && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  97. <font size="4">97                && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  98. <font size="4">98          if(char [year[3:0]] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  99. <font size="4">99                                - (pixel_xpos-(CHAR_POS_X_1 + CHAR_WIDTH_1/10*3)) -1 ])</font>
  100. <font size="4">100             pixel_data <= BLACK;</font>
  101. <font size="4">101         else</font>
  102. <font size="4">102             pixel_data <= WHITE;</font>
  103. <font size="4">103     end</font>
  104. <font size="4">104     </font>
  105. <font size="4">105     //在第一行显示空格</font>
  106. <font size="4">106     else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*4) </font>
  107. <font size="4">107               && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*5)</font>
  108. <font size="4">108               && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  109. <font size="4">109               && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  110. <font size="4">110         pixel_data <= WHITE;</font>
  111. <font size="4">111     end</font>
  112. <font size="4">112     </font>
  113. <font size="4">113     //在第一行显示月的十位</font>
  114. <font size="4">114     else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*5) </font>
  115. <font size="4">115               && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*6)</font>
  116. <font size="4">116               && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  117. <font size="4">117               && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)) begin</font>
  118. <font size="4">118         if(char [mon[7:4]] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  119. <font size="4">119                              - (pixel_xpos-(CHAR_POS_X_1 + CHAR_WIDTH_1/10*5)) -1 ])</font>
  120. <font size="4">120             pixel_data <= BLACK;</font>
  121. <font size="4">121         else</font>
  122. <font size="4">122             pixel_data <= WHITE;</font>
  123. <font size="4">123     end</font>
  124. <font size="4">124     </font>
  125. <font size="4">125     //在第一行显示月的个位</font>
  126. <font size="4">126     else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*6) </font>
  127. <font size="4">127               && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*7)</font>
  128. <font size="4">128               && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  129. <font size="4">129               && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  130. <font size="4">130         if(char [mon[3:0]] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  131. <font size="4">131                              - (pixel_xpos-(CHAR_POS_X_1 + CHAR_WIDTH_1/10*6)) -1 ])</font>
  132. <font size="4">132             pixel_data <= BLACK;</font>
  133. <font size="4">133         else</font>
  134. <font size="4">134             pixel_data <= WHITE;</font>
  135. <font size="4">135     end</font>
  136. <font size="4">136     </font>
  137. <font size="4">137     //在第一行显示空格</font>
  138. <font size="4">138     else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*7) </font>
  139. <font size="4">139               && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*8)</font>
  140. <font size="4">140               && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  141. <font size="4">141               && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  142. <font size="4">142         pixel_data <= WHITE;</font>
  143. <font size="4">143     end </font>
  144. <font size="4">144     </font>
  145. <font size="4">145     //在第一行显示日的十位</font>
  146. <font size="4">146     else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*8) </font>
  147. <font size="4">147               && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1/10*9)</font>
  148. <font size="4">148               && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  149. <font size="4">149               && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  150. <font size="4">150         if(char [day[7:4]] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  151. <font size="4">151                              - (pixel_xpos-(CHAR_POS_X_1 + CHAR_WIDTH_1/10*8)) -1 ])</font>
  152. <font size="4">152             pixel_data <= BLACK;</font>
  153. <font size="4">153         else</font>
  154. <font size="4">154             pixel_data <= WHITE;</font>
  155. <font size="4">155     end</font>
  156. <font size="4">156     </font>
  157. <font size="4">157     //在第一行显示日的个位</font>
  158. <font size="4">158     else if(     (pixel_xpos >= CHAR_POS_X_1 + CHAR_WIDTH_1/10*9) </font>
  159. <font size="4">159               && (pixel_xpos <  CHAR_POS_X_1 + CHAR_WIDTH_1)</font>
  160. <font size="4">160               && (pixel_ypos >= CHAR_POS_Y_1)                  </font>
  161. <font size="4">161               && (pixel_ypos <  CHAR_POS_Y_1 + CHAR_HEIGHT)  ) begin</font>
  162. <font size="4">162         if(char [day[3:0]] [ (CHAR_HEIGHT+CHAR_POS_Y_1 - pixel_ypos)*8 </font>
  163. <font size="4">163                              - (pixel_xpos-(CHAR_POS_X_1 + CHAR_WIDTH_1/10*9)) -1 ])</font>
  164. <font size="4">164             pixel_data <= BLACK;</font>
  165. <font size="4">165         else</font>
  166. <font size="4">166             pixel_data <= WHITE;</font>
  167. <font size="4">167     end</font>
  168. <font size="4">168     </font>
  169. <font size="4">169     //在第二行显示时的十位</font>
  170. <font size="4">170     else if(     (pixel_xpos >= CHAR_POS_X_2)                  </font>
  171. <font size="4">171               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2/8*1)</font>
  172. <font size="4">172               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  173. <font size="4">173               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  174. <font size="4">174         if(char [hour[7:4]] [ (CHAR_HEIGHT+CHAR_POS_Y_2 - pixel_ypos)*8 </font>
  175. <font size="4">175                               - (pixel_xpos-CHAR_POS_X_2) -1 ] )</font>
  176. <font size="4">176             pixel_data <= BLACK;</font>
  177. <font size="4">177         else</font>
  178. <font size="4">178             pixel_data <= WHITE;</font>
  179. <font size="4">179     end</font>
  180. <font size="4">180     </font>
  181. <font size="4">181     //在第二行显示时的个位</font>
  182. <font size="4">182     else if(     (pixel_xpos >= CHAR_POS_X_2 + CHAR_WIDTH_2/8*1) </font>
  183. <font size="4">183               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2/8*2)</font>
  184. <font size="4">184               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  185. <font size="4">185               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  186. <font size="4">186         if(char [hour[3:0]] [ (CHAR_HEIGHT+CHAR_POS_Y_2 - pixel_ypos)*8 </font>
  187. <font size="4">187                               - (pixel_xpos-(CHAR_POS_X_2 + CHAR_WIDTH_2/8*1)) -1 ])</font>
  188. <font size="4">188             pixel_data <= BLACK;</font>
  189. <font size="4">189         else</font>
  190. <font size="4">190             pixel_data <= WHITE;</font>
  191. <font size="4">191     end</font>
  192. <font size="4">192     </font>
  193. <font size="4">193     //在第二行显示空格</font>
  194. <font size="4">194     else if(     (pixel_xpos >= CHAR_POS_X_2 + CHAR_WIDTH_2/8*2) </font>
  195. <font size="4">195               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2/8*3)</font>
  196. <font size="4">196               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  197. <font size="4">197               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  198. <font size="4">198         pixel_data <= WHITE;</font>
  199. <font size="4">199     end</font>
  200. <font size="4">200     </font>
  201. <font size="4">201     //在第二行显示分的十位</font>
  202. <font size="4">202     else if(     (pixel_xpos >= CHAR_POS_X_2 + CHAR_WIDTH_2/8*3) </font>
  203. <font size="4">203               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2/8*4)</font>
  204. <font size="4">204               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  205. <font size="4">205               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  206. <font size="4">206         if(char [min[7:4]] [ (CHAR_HEIGHT+CHAR_POS_Y_2 - pixel_ypos)*8 </font>
  207. <font size="4">207                              - (pixel_xpos-(CHAR_POS_X_2 + CHAR_WIDTH_2/8*3)) -1 ])</font>
  208. <font size="4">208             pixel_data <= BLACK;</font>
  209. <font size="4">209         else</font>
  210. <font size="4">210             pixel_data <= WHITE;</font>
  211. <font size="4">211     end</font>
  212. <font size="4">212     </font>
  213. <font size="4">213     //在第二行显示分的个位</font>
  214. <font size="4">214     else if(     (pixel_xpos >= CHAR_POS_X_2 + CHAR_WIDTH_2/8*4) </font>
  215. <font size="4">215               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2/8*5)</font>
  216. <font size="4">216               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  217. <font size="4">217               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  218. <font size="4">218         if(char [min[3:0]] [ (CHAR_HEIGHT+CHAR_POS_Y_2 - pixel_ypos)*8 </font>
  219. <font size="4">219                              - (pixel_xpos-(CHAR_POS_X_2 + CHAR_WIDTH_2/8*4)) -1 ])</font>
  220. <font size="4">220             pixel_data <= BLACK;</font>
  221. <font size="4">221         else</font>
  222. <font size="4">222             pixel_data <= WHITE;</font>
  223. <font size="4">223     end</font>
  224. <font size="4">224     </font>
  225. <font size="4">225     //在第二行显示空格</font>
  226. <font size="4">226     else if(     (pixel_xpos >= CHAR_POS_X_2 + CHAR_WIDTH_2/8*5) </font>
  227. <font size="4">227               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2/8*6)</font>
  228. <font size="4">228               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  229. <font size="4">229               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  230. <font size="4">230         pixel_data <= WHITE;</font>
  231. <font size="4">231     end </font>
  232. <font size="4">232     </font>
  233. <font size="4">233     //在第二行显示秒的十位</font>
  234. <font size="4">234     else if(     (pixel_xpos >= CHAR_POS_X_2 + CHAR_WIDTH_2/8*6) </font>
  235. <font size="4">235               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2/8*7)</font>
  236. <font size="4">236               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  237. <font size="4">237               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  238. <font size="4">238         if(char [sec[7:4]] [ (CHAR_HEIGHT+CHAR_POS_Y_2 - pixel_ypos)*8 </font>
  239. <font size="4">239                               - (pixel_xpos-(CHAR_POS_X_2 + CHAR_WIDTH_2/8*6)) -1 ])</font>
  240. <font size="4">240             pixel_data <= BLACK;</font>
  241. <font size="4">241         else</font>
  242. <font size="4">242             pixel_data <= WHITE;</font>
  243. <font size="4">243     end</font>
  244. <font size="4">244     </font>
  245. <font size="4">245     //在第二行显示秒的个位    </font>
  246. <font size="4">246     else if(     (pixel_xpos >= CHAR_POS_X_2 + CHAR_WIDTH_2/8*7) </font>
  247. <font size="4">247               && (pixel_xpos <  CHAR_POS_X_2 + CHAR_WIDTH_2)</font>
  248. <font size="4">248               && (pixel_ypos >= CHAR_POS_Y_2)                  </font>
  249. <font size="4">249               && (pixel_ypos <  CHAR_POS_Y_2 + CHAR_HEIGHT)  ) begin</font>
  250. <font size="4">250         if(char [sec[3:0]] [ (CHAR_HEIGHT+CHAR_POS_Y_2 - pixel_ypos)*8 </font>
  251. <font size="4">251                              - (pixel_xpos-(CHAR_POS_X_2 + CHAR_WIDTH_2/8*7)) -1 ])</font>
  252. <font size="4">252             pixel_data <= BLACK;</font>
  253. <font size="4">253         else</font>
  254. <font size="4">254             pixel_data <= WHITE;</font>
  255. <font size="4">255     end</font>
  256. <font size="4">256     </font>
  257. <font size="4">257     else begin</font>
  258. <font size="4">258         pixel_data <= WHITE;    //屏幕背景为白色</font>
  259. <font size="4">259     end</font>
  260. <font size="4">260 end</font>
  261. <font size="4">261 </font>
  262. <font size="4">262 endmodule </font>
复制代码

我们的显示内容首先分成两行,第一行显示年月日,第二行显示时分秒。程序中第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”的字模数据,由取模软件生成,先将软件设置成字符模式,取模软件的设置如下:
2825810.png

图 28.4.2 字符软件设置

这里将点阵设置为16,即一个数字的字符用一行来表示。
生成字模的界面如下:
2825909.png

图 28.4.3 生成字模的软件设置

程序中第51行至260行代码根据输入的日期、时间和字符区域的坐标显示在LCD上,字符颜色为黑色,背景色为白色。


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-10-3 18:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表