OpenEdv-开源电子网

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

[国产FPGA] 《ATK-DFPGL22G 之FPGA开发指南》第十四章 动态数码管显示实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4666
金钱
4666
注册时间
2019-5-8
在线时间
1224 小时
发表于 2023-11-10 16:33:09 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2023-11-10 16:33 编辑

第十四章 动态数码管显示实验

1)实验平台:正点原子 ATK-DFPGL22G开发板

2) 章节摘自【正点原子】ATK-DFPGL22G之FPGA开发指南_V1.0


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz-PGL22G.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)FPGA技术交流QQ群:435699340

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

经过上一章的学习,我们已经知道如何使用数码管静态驱动的方式使数码管显示数字,但在很多情况下,我们需要让数码管各个位显示不同的数字,这就需要以动态驱动的方式驱动数码管。本章我们主要介绍数码管动态驱动的原理以及如何使用动态驱动的方式在数码管上显示变化的数字。
本章包括以下几个部分:
1.1 简介
1.2 实验任务
1.3 硬件设计
1.4 程序设计
1.5 下载验证

1.1 简介
在“数码管静态显示实验”章节我们详细地介绍了有关数码管方面的知识和数码管的静态驱动,让大家对数码管的驱动有了基本的了解。由于一般的静态驱动操作虽然方便,但占用的I/0口较多,例如要驱动6位8段数码管,以静态驱动方式让数码管各个位显示不同的数值,如“123456”,需要占用6×8=48个I/O口,虽然对于FPGA这种I/O口较多的芯片而言,在资源允许的情况下可以使用,但一般不建议浪费宝贵的I/O口资源,尤其在I/O口资源紧张的情况下,所以对于多位数码管一般采用动态驱动方式使数码管显示数字。那么什么是动态驱动方式呢?

为了更好的理解数码管动态驱动,我们首先了解下市面上常见的多位数码管的内部连接。以两位数码管为例,其内部连接如下图。由此图可知,两位8段数码管共10个引脚,每位数码管的阳极连接在一起,为共阳极数码管,每位数码管相同段的led的阴极连接在一起,这样当给第10和第5脚高电平,给第3脚低电平时,两个数码管的发光二极管A都点亮,对于此种数码管以静态方式驱动显然不可能显示像“18”这种个位与十位不同的数字。那么该如何显示数字“18”呢?                             
image001.png
图 14.1.1 多位数码管内部连接图

既然同时给第10和第5脚高电平不可行,那么是不是可以先给第5脚高电平,第10脚低电平,此时,让其显示数字“8”时,左边的数码管不显示,右边的数码管显示数字“8”;然后给第10脚高电平,第5脚低电平,此时,让其显示数字“1”时,左边的数码管显示数字“1”,右边的数码管不显示,这样就可以显示数字“18”了。但有一个问题,多长时间切换显示的数码管呢,时间如果太长就只能看到数字“8”或数字“1”了,时间太短呢,结果是显示不清晰而且显示亮度不够。由于人眼的视觉暂留(人眼在观察景物时,光信号传人大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”)及发光二极管的余辉效应(当停止向发光二极管供电时,发光二极管亮度仍能维持一段时间),每位数码管的点亮时间为1~2ms时,显示效果能满足使用需要。数码管的这种驱动方式称为数码管的动态驱动,实际上就是分时轮流控制不同数码管的显示。

1.2 实验任务
本节实验任务是使用FPGA开发板上的6位数码管以动态方式从0开始计数,每100ms计数值增加一,当计数值从0增加到999999后重新从0开始计数。

1.3 硬件设计
数码管接口部分的硬件设计原理及本实验中各端口信号的管脚分配与“数码管静态显示实验”完全相同,请参考“数码管静态显示实验”中的硬件设计部分。

1.4 程序设计
由实验任务和动态驱动的原理我们可以知道,若要让6个数码管轮流显示对应的数字,首先需要一个数码管动态显示模块,能够依次点亮6个数码管,并将对应的数据输出至数码管,也就是需要分别控制段选和位选信号;同时还需要一个计数模块,能够将0—999999依次输出至数码管动态显示模块。根据实验任务,我们可以大致规划出系统的控制流程:首先我们需要一个数码管动态显示模块在数码管上显示数据,其次需要一个计数控制模块实现从0到999999的变化,并将产生的数值通过数码管动态显示模块在数码管上显示出来。由此画出系统的功能框图如下所示:
image004.png
图 14.4.1 数码管动态显示实验系统框图

程序中各模块端口及信号连接如下图所示:
image005.png
图 14.4.2 顶层模块原理图

FPGA顶层(top_seg_led)例化了以下两个模块:计数模块(count)以及数码管动态显示模块(seg_led)。实现各模块之间数据的交互。计数模块将计数值通过data端口传递给数码管动态显示模块,使能信号en使能数码管显示数据,小数点显示信号point控制小数点的显示,符号信号sign可以让数码管显示负号。

计数模块(count):显示的数字每100ms加“1”。

数码管动态显示模块(seg_led):数码管动态显示模块在数码管上以动态方式显示数值。

顶层模块的代码如下:
  1. 1  module top_seg_led(
  2. 2       //global clock
  3. 3       input           sys_clk  ,       // 全局时钟信号
  4. 4       input           sys_rst_n,       // 复位信号(低有效)
  5. 5  
  6. 6       //seg_led interface
  7. 7       output    [5:0  seg_sel  ,       // 数码管位选信号
  8. 8       output    [7:0  seg_led          // 数码管段选信号
  9. 9  );
  10. 10
  11. 11 //wire define
  12. 12 wire    [19:0  data;                // 数码管显示的数值
  13. 13 wire    [ 5:0  point;               // 数码管小数点的位置
  14. 14 wire            en;                   // 数码管显示使能信号
  15. 15 wire            sign;                 // 数码管显示数据的符号位
  16. 16
  17. 17 //*****************************************************
  18. 18 //**                    main code
  19. 19 //*****************************************************
  20. 20
  21. 21 //计数器模块,产生数码管需要显示的数据
  22. 22 count u_count(
  23. 23      .clk           (sys_clk  ),       // 时钟信号
  24. 24      .rst_n         (sys_rst_n),       // 复位信号
  25. 25
  26. 26      .data          (data     ),       // 6位数码管要显示的数值
  27. 27      .point         (point    ),       // 小数点具体显示的位置,高电平有效
  28. 28      .en            (en       ),       // 数码管使能信号
  29. 29      .sign          (sign     )        // 符号位
  30. 30 );
  31. 31
  32. 32 //数码管动态显示模块
  33. 33 seg_led u_seg_led(
  34. 34      .clk           (sys_clk  ),       // 时钟信号
  35. 35      .rst_n         (sys_rst_n),       // 复位信号
  36. 36
  37. 37      .data          (data     ),       // 显示的数值
  38. 38      .point         (point    ),       // 小数点具体显示的位置,高电平有效
  39. 39      .en            (en       ),       // 数码管使能信号
  40. 40      .sign          (sign     ),       // 符号位,高电平显示负号(-)
  41. 41      
  42. 42      .seg_sel       (seg_sel  ),       // 位选
  43. 43      .seg_led       (seg_led  )        // 段选
  44. 44 );
  45. 45
  46. 46 endmodule
复制代码
顶层模块中主要完成对其余模块的例化,并且实现各模块之间信号的交互。计数模块输出的数值data连接至数码管显示模块的输入端口data,数码管显示模块将输入的数据data输出至数码管上显示。

计数模块的代码如下所示:
  1. 1  module count(
  2. 2       //mudule clock
  3. 3       input                  clk  ,      // 时钟信号
  4. 4       input                  rst_n,      // 复位信号
  5. 5      
  6. 6       //user interface
  7. 7       output   reg [19:0     data ,      // 6个数码管要显示的数值
  8. 8       output   reg [ 5:0     point,      // 小数点的位置,高电平点亮对应数码管位上的小数点
  9. 9       output   reg           en   ,      // 数码管使能信号
  10. 10      output   reg           sign        // 符号位,高电平时显示负号,低电平不显示负号
  11. 11 );
  12. 12
  13. 13 //parameter define
  14. 14 parameter  MAX_NUM = 23'd5000_000;      // 计数器计数的最大值
  15. 15
  16. 16 //reg define
  17. 17 reg    [22:0   cnt ;                  // 计数器,用于计时100ms
  18. 18 reg             flag;                   // 标志信号
  19. 19
  20. 20 //*****************************************************
  21. 21 //**                    main code
  22. 22 //*****************************************************
  23. 23
  24. 24 //计数器对系统时钟计数达100ms时,输出一个时钟周期的脉冲信号
  25. 25 always @ (posedge clk or negedge rst_n) begin
  26. 26      if (!rst_n) begin
  27. 27          cnt <= 23'b0;
  28. 28          flag<= 1'b0;
  29. 29      end
  30. 30      else if (cnt < MAX_NUM - 1'b1) begin
  31. 31          cnt <= cnt + 1'b1;
  32. 32          flag<= 1'b0;
  33. 33      end
  34. 34      else begin
  35. 35          cnt <= 23'b0;
  36. 36          flag <= 1'b1;
  37. 37      end
  38. 38 end
  39. 39
  40. 40 //数码管需要显示的数据,从0累加到999999
  41. 41 always @ (posedge clk or negedge rst_n) begin
  42. 42      if (!rst_n)begin
  43. 43          data <= 20'b0;
  44. 44          point <=6'b000000;
  45. 45          en   <= 1'b0;
  46. 46          sign <= 1'b0;
  47. 47      end
  48. 48      else begin
  49. 49          point <= 6'b000000;             //不显示小数点
  50. 50          en   <= 1'b1;                  //打开数码管使能信号
  51. 51          sign <= 1'b0;                  //不显示负号
  52. 52          if (flag) begin                 //显示数值每隔0.1s累加一次
  53. 53              if(data < 20'd999999)
  54. 54                  data <= data +1'b1;     
  55. 55              else
  56. 56                  data <= 20'b0;
  57. 57          end
  58. 58      end
  59. 59 end
  60. 60
  61. 61 endmodule
复制代码
码中第14行的参数MAX_NUM为计数的最大计数值,由于是对时钟计数,相当于计时,第25行的always语句块表示的是当计数器cnt计数值小于MAX_NUM - 1'b1时,标志(flag)为“0”,否则标志(flag)为“1”,并且计数器cnt清零。

数码管动态显示模块的代码如下:
  1. 1  module seg_led(
  2. 2       input                  clk    ,        // 时钟信号
  3. 3       input                  rst_n  ,        // 复位信号
  4. 4  
  5. 5       input         [19:0    data   ,        // 6位数码管要显示的数值
  6. 6       input         [5:0     point  ,        // 小数点具体显示的位置,从高到
  7. 7       input                  en     ,        // 数码管使能信号
  8. 8       input                  sign   ,        // 符号位(高电平显示“-”号)
  9. 9  
  10. 10      output   reg  [5:0     seg_sel,        // 数码管位选,最左侧数码管为最
  11. 11      output   reg  [7:0    seg_led         //数码管段选
  12. 12      );
  13. 13
  14. 14 //parameter define
  15. 15 localparam  CLK_DIVIDE =4'd10     ;        // 时钟分频系数
  16. 16 localparam  MAX_NUM   = 13'd5000 ;        // 对数码管驱动时钟(5MHz)计数1m
  17. 17
  18. 18 //reg define
  19. 19 reg    [ 3:0            clk_cnt  ;        // 时钟分频计数器
  20. 20 reg                       dri_clk  ;        // 数码管的驱动时钟,5MHz
  21. 21 reg    [23:0            num      ;        // 24位bcd码寄存器
  22. 22 reg    [12:0            cnt0     ;        // 数码管驱动时钟计数器
  23. 23 reg                       flag     ;        // 标志信号(标志着cnt0计数达1m
  24. 24 reg    [7:0             cnt_sel  ;        // 数码管位选计数器
  25. 25 reg    [3:0             num_disp ;        // 当前数码管显示的数据
  26. 26 reg                       dot_disp ;        // 当前数码管显示的小数点
  27. 27
  28. 28 //wire define
  29. 29 wire   [3:0             data0    ;        // 个位数
  30. 30 wire   [3:0             data1    ;        // 十位数
  31. 31 wire   [3:0             data2    ;        // 百位数
  32. 32 wire   [3:0             data3    ;        // 千位数
  33. 33 wire   [3:0             data4    ;        // 万位数
  34. 34 wire   [3:0             data5    ;        // 十万位数
  35. 35
  36. 36 //*****************************************************
  37. 37 //**                    main code
  38. 38 //*****************************************************
  39. 39
  40. 40 //提取显示数值所对应的十进制数的各个位
  41. 41 assign  data0 = data % 4'd10;               // 个位数
  42. 42 assign  data1 = data / 4'd10 % 4'd10   ;    // 十位数
  43. 43 assign  data2 = data / 7'd100 % 4'd10  ;    //百位数
  44. 44 assign  data3 = data / 10'd1000 % 4'd10 ;   // 千位数
  45. 45 assign  data4 = data / 14'd10000 % 4'd10;   // 万位数
  46. 46 assign  data5 = data / 17'd100000;          // 十万位数
  47. 47
  48. 48 //对系统时钟10分频,得到的频率为5MHz的数码管驱动时钟dri_clk
  49. 49 always @(posedge clk or negedge rst_n) begin
  50. 50     if(!rst_n) begin
  51. 51         clk_cnt <= 4'd0;
  52. 52         dri_clk <= 1'b1;
  53. 53     end
  54. 54     else if(clk_cnt == CLK_DIVIDE / 2 - 1) begin
  55. 55         clk_cnt <= 4'd0;
  56. 56         dri_clk <= ~dri_clk;
  57. 57     end
  58. 58     else begin
  59. 59         clk_cnt <= clk_cnt +1'b1;
  60. 60         dri_clk <= dri_clk;
  61. 61     end
  62. 62 end
  63. 63
  64. 64 //将20位2进制数转换为8421bcd码(即使用4位二进制数表示1位十进制数)·
  65. 65 always @ (posedge dri_clk or negedge rst_n) begin
  66. 66      if (!rst_n)
  67. 67          num <= 24'b0;
  68. 68      else begin
  69. 69          if (data5 || point[5]) begin     //如果显示数据为6位十进制数,
  70. 70              num[23:20 <= data5;         //则依次给6位数码管赋值
  71. 71              num[19:16 <= data4;
  72. 72              num[15:12 <= data3;
  73. 73              num[11:8  <= data2;
  74. 74              num[ 7:4  <= data1;
  75. 75              num[ 3:0  <= data0;
  76. 76          end
  77. 77          else begin                        
  78. 78              if (data4 || point[4]) begin //如果显示数据为5位十进制数,则给
  79. 79                  num[19:0 <= {data4,data3,data2,data1,data0};
  80. 80                  if(sign)                  
  81. 81                      num[23:20 <= 4'd11; //如果需要显示负号,则最高位(第6
  82. 82                  else
  83. 83                      num[23:20 <= 4'd10; //不需要显示负号时,则第6位不显示
  84. 84              end
  85. 85              else begin                   //如果显示数据为4位十进制数,则给
  86. 86                  if (data3 || point[3]) begin
  87. 87                      num[15: 0 <= {data3,data2,data1,data0};
  88. 88                      num[23:20 <= 4'd10; //第6位不显示任何字符
  89. 89                      if(sign)             //如果需要显示负号,则最高位(第5
  90. 90                          num[19:16 <= 4'd11;
  91. 91                      else                //不需要显示负号时,则第5位不显示
  92. 92                          num[19:16 <= 4'd10;
  93. 93                  end
  94. 94                  else begin               //如果显示数据为3位十进制数,则给
  95. 95                      if (data2 || point[2]) begin
  96. 96                          num[11: 0 <= {data2,data1,data0};
  97. 97                                           //第6、5位不显示任何字符
  98. 98                          num[23:16 <= {2{4'd10}};
  99. 99                          if(sign)         //如果需要显示负号,则最高位(第4
  100. 100                             num[15:12 <= 4'd11;
  101. 101                         else            //不需要显示负号时,则第4位不显示
  102. 102                             num[15:12 <= 4'd10;
  103. 103                     end
  104. 104                     else begin           //如果显示数据为2位十进制数,则给
  105. 105                         if (data1 || point[1]) begin
  106. 106                             num[ 7: 0 <= {data1,data0};
  107. 107                                          //第6、5、4位不显示任何字符
  108. 108                             num[23:12 <= {3{4'd10}};
  109. 109                             if(sign)     //如果需要显示负号,则最高位(第3
  110. 110                                 num[11:8  <= 4'd11;
  111. 111                             else         //不需要显示负号时,则第3位不显示
  112. 112                                 num[11:8 <=  4'd10;
  113. 113                         end
  114. 114                         else begin       //如果显示数据为1位十进制数,则给
  115. 115                             num[3:0 <= data0;
  116. 116                                          //第6、5位不显示任何字符
  117. 117                             num[23:8 <= {4{4'd10}};
  118. 118                             if(sign)     //如果需要显示负号,则最高位(第2
  119. 119                                 num[7:4 <= 4'd11;
  120. 120                             else         //不需要显示负号时,则第2位不显示
  121. 121                                 num[7:4 <= 4'd10;
  122. 122                         end
  123. 123                     end
  124. 124                 end
  125. 125             end
  126. 126         end
  127. 127     end
  128. 128 end
  129. 129
  130. 130 //每当计数器对数码管驱动时钟计数时间达1ms,输出一个时钟周期的脉冲信号
  131. 131 always @ (posedge dri_clk or negedge rst_n) begin
  132. 132     if (rst_n == 1'b0) begin
  133. 133         cnt0 <= 13'b0;
  134. 134         flag <= 1'b0;
  135. 135      end
  136. 136     else if (cnt0 < MAX_NUM - 1'b1) begin
  137. 137         cnt0 <= cnt0 + 1'b1;
  138. 138         flag <= 1'b0;
  139. 139      end
  140. 140     else begin
  141. 141         cnt0 <= 13'b0;
  142. 142         flag <= 1'b1;
  143. 143      end
  144. 144 end
  145. 145
  146. 146 //cnt_sel从0计数到5,用于选择当前处于显示状态的数码管
  147. 147 always @ (posedge dri_clk or negedge rst_n) begin
  148. 148     if (rst_n == 1'b0)
  149. 149         cnt_sel <= 8'b0;
  150. 150     else if(flag) begin
  151. 151         if(cnt_sel < 8'd11)
  152. 152             cnt_sel <= cnt_sel + 1'b1;
  153. 153         else
  154. 154             cnt_sel <= 8'b0;
  155. 155     end
  156. 156     else
  157. 157         cnt_sel <= cnt_sel;
  158. 158 end
  159. 159
  160. 160 //控制数码管位选信号,使6位数码管轮流显示
  161. 161 always @ (posedge dri_clk or negedge rst_n) begin
  162. 162     if(!rst_n) begin
  163. 163         seg_sel  <= 6'b000000;              //位选信号高电平有效
  164. 164         num_disp <= 4'b0;           
  165. 165         dot_disp <= 1'b1;                  //共阳极数码管,低电平导通
  166. 166     end
  167. 167     else begin
  168. 168         if(en) begin
  169. 169             case (cnt_sel)
  170. 170                 8'd0 :begin
  171. 171                     seg_sel  <= 6'b000001;  //显示数码管最低位
  172. 172                     num_disp <= num[3:0 ;  //显示的数据
  173. 173                     dot_disp <= ~point[0];  //显示的小数点
  174. 174                 end
  175. 175                 8'd1 :begin
  176. 176                     seg_sel  <= 6'b000000;  //清空
  177. 177                     num_disp <= 4'd10;
  178. 178                 end
  179. 179                 8'd2 :begin
  180. 180                     seg_sel  <= 6'b000010;  //显示数码管第1位
  181. 181                     num_disp <= num[7:4 ;
  182. 182                     dot_disp <= ~point[1];
  183. 183                 end
  184. 184                 8'd3 :begin
  185. 185                     seg_sel  <= 6'b000000;  //清空
  186. 186                     num_disp <= 4'd10;
  187. 187                 end
  188. 188                 8'd4 :begin
  189. 189                     seg_sel  <= 6'b000100;  //显示数码管第2位
  190. 190                     num_disp <= num[11:8];
  191. 191                     dot_disp <= ~point[2];
  192. 192                 end
  193. 193                 8'd5 :begin
  194. 194                     seg_sel  <= 6'b000000;  //清空
  195. 195                     num_disp <= 4'd10;
  196. 196                 end
  197. 197                 8'd6 :begin
  198. 198                     seg_sel  <= 6'b001000;  //显示数码管第3位
  199. 199                     num_disp <= num[15:12];
  200. 200                     dot_disp <= ~point[3];
  201. 201                 end
  202. 202                 8'd7 :begin
  203. 203                     seg_sel  <= 6'b000000;  //清空
  204. 204                     num_disp <= 4'd10;
  205. 205                 end
  206. 206                 8'd8 :begin
  207. 207                     seg_sel  <= (6'b010000);  //显示数码管第4位
  208. 208                     num_disp <= num[19:16];
  209. 209                     dot_disp <= ~point[4];
  210. 210                 end
  211. 211                 8'd9 :begin
  212. 212                     seg_sel  <= 6'b000000;  //清空
  213. 213                     num_disp <= 4'd10;
  214. 214                 end
  215. 215                 8'd10 :begin
  216. 216                     seg_sel  <= 6'b100000;  //显示数码管最高位
  217. 217                     num_disp <= num[23:20];
  218. 218                     dot_disp <= ~point[5];
  219. 219                 end
  220. 220                 8'd11 :begin
  221. 221                     seg_sel  <= 6'b000000;  //清空
  222. 222                     num_disp <= 4'd10;
  223. 223                 end
  224. 224                 default :begin
  225. 225                     seg_sel  <= 6'b000000;
  226. 226                     num_disp <= 4'b0;
  227. 227                     dot_disp <= 1'b1;
  228. 228                 end
  229. 229             endcase
  230. 230         end
  231. 231         else begin
  232. 232             seg_sel  <= 6'b000000;          //使能信号为0时,所有数码管均不
  233. 233             num_disp <= 4'b0;
  234. 234             dot_disp <= 1'b1;
  235. 235         end
  236. 236     end
  237. 237 end
  238. 238
  239. 239 //控制数码管段选信号,显示字符
  240. 240 always @ (posedge dri_clk or negedge rst_n) begin
  241. 241     if (!rst_n)
  242. 242         seg_led <= ~(8'hc0);
  243. 243     else begin
  244. 244         case (num_disp)
  245. 245             4'd0 : seg_led <= ~{dot_disp,(7'b1000000)}; //显示数字 0
  246. 246             4'd1 : seg_led <= ~{dot_disp,(7'b1111001)}; //显示数字 1
  247. 247             4'd2 : seg_led <= ~{dot_disp,(7'b0100100)}; //显示数字 2
  248. 248             4'd3 : seg_led <= ~{dot_disp,(7'b0110000)}; //显示数字 3
  249. 249             4'd4 : seg_led <= ~{dot_disp,(7'b0011001)}; //显示数字 4
  250. 250             4'd5 : seg_led <= ~{dot_disp,(7'b0010010)}; //显示数字 5
  251. 251             4'd6 : seg_led <= ~{dot_disp,(7'b0000010)}; //显示数字 6
  252. 252             4'd7 : seg_led <= ~{dot_disp,(7'b1111000)}; //显示数字 7
  253. 253             4'd8 : seg_led <= ~{dot_disp,(7'b0000000)}; //显示数字 8
  254. 254             4'd9 : seg_led <= ~{dot_disp,(7'b0010000)}; //显示数字 9
  255. 255             4'd10: seg_led <= ~8'b11111111;           //不显示任何字符
  256. 256             4'd11: seg_led <= ~8'b10111111;           //显示负号(-)
  257. 257             default:
  258. 258                    seg_led <= {~dot_disp,~(7'b1000000)};
  259. 259         endcase
  260. 260     end
  261. 261 end
  262. 262
  263. 263 endmodule
复制代码
在170行到223行中,可以看到由于数码管硬件引起的程序改动,即在每次刷新一位显示后关闭所有显示,这样会使FPGA管脚受程序控制直接接地,从而快速释放MOS管的电压,这样可以有效避免显示残留的问题。

数码管动态显示模块不仅可以将数值显示在数码管上,而且可以控制小数点的显示以及显示负数。数码管驱动模块没有在高位填充“0”,除非该位显示小数点。结合第131行开始的always语句块可知,cnt每1ms的时间变化一次;而从第161行的case语句块可知,cnt控制数码管的位选和段选。

1.5 下载验证
首先将下载器一端连接电脑,另一端与开发板上的JTAG下载口相连,最后连接电源线并打开电源开关。接下来我们下载程序,验证数码管动态显示的功能。

下载完成后观察到开发板上数码管显示的值从“0”增加到“999999”,如下图所示,说明数码管动态显示实验程序下载验证成功。
image007.png
图 14.5.1 动态数码管显示实验结果显示
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 17:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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