数码管动态扫描显示

摸鱼记录 Day_16 (゚O゚)

review

前边已经学习了:

串口接收:Vivado 串口接收优化-CSDN博客

1. 今日摸鱼任务

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 串口接收数据 并用数码管显示 (゚O゚) 小梅哥视频: 17A 数码管段码显示与动态扫描原理_哔哩哔哩_bilibili 17B 数码管动态扫描显示数字逻辑建模_哔哩哔哩_bilibili 17C 数码管动态扫描显示的Verilog实现_哔哩哔哩_bilibili 17D 使能时钟和门控时钟的原理与差异_哔哩哔哩_bilibili //虽然看起来很多,但是不会很难滴 (゚O゚) |

2. 数码管显示原理

ACZ702 EDA 扩展板上板载的是共阳数码管。同时为了显示数字或字符,必须对数字或字符进行编码译码。

先不考虑小数点也就是简化为 7 段数码管,其编码译码格式如下表所示:

段式数码管工作方式有两种:静态显示方式和动态显示方式。

静态显示:每个数码管的段选必须接一个 8 位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。

这种方法由于每个数码管均需要独立的数据线,硬件电路比较复杂,成本较高,很少使用。

动态显示:将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
电路结构如下所示,这样 3 个数码管接在一起就比静态的少了 7*2 个 I/O 。
sel拉高选中

3. 时钟分频:门控时钟与使能时钟

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 门控时钟: 使用计数器和逻辑门翻转产生 |
| reg [14:0]div_clk; always@(posedge clk or negedge reset_n) if(!reset_n) div_clk <= 1'b0; else if(div_clk == 24999) div_clk <= 1'b0; else div_clk <= div_clk + 1'b1; always@(posedge clk or negedge reset_n) if(!reset_n) clk_1 <= 1'b0; else if(div_clk == 24999) clk_1 <= ~clk_1; |
| 使能时钟: 用到计数器,但是不会用到反相器,生成的信号也不会直接用于其他电路的触发 |
| reg [14:0]div_clk; always@(posedge clk or negedge reset_n) if(!reset_n) div_clk <= 1'b0; else if(div_clk == 24999) div_clk <= 1'b0; else div_clk <= div_clk + 1'b1; always@(posedge clk or negedge reset_n) if(!reset_n) disp_en <= 1'b0; else if(div_clk == 24999) disp_en <= 1'b1; else disp_en <= 1'b0; |
| |
| 对比: 门控时钟的时钟延迟不稳定,且延迟比较大 使得时钟的波形变差 驱动能力差 小结:设计中一般情况下使用使能时钟的时钟分频方式 |

4. hex_8

4.1 design sources

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| hex_8 |
| |
| |
| module hex_8(input clk, input reset_n, input [31:0]disp_data, output reg [7:0]sel, output reg [7:0]seg ); //[31:0]disp_data 16hex 4*8 //[7:0]sel 位选信号 //[7:0]seg 段选信号 // 1kHz分频时钟 reg [14:0]div_clk; always@(posedge clk or negedge reset_n) if(!reset_n) div_clk <= 1'b0; else if(div_clk == 24999) div_clk <= 1'b0; else div_clk <= div_clk + 1'b1; reg disp_en; always@(posedge clk or negedge reset_n) if(!reset_n) disp_en <= 1'b0; else if(div_clk == 24999) disp_en <= 1'b1; else disp_en <= 1'b0; // 位选sel reg[2:0]sel_num; always@(posedge clk or negedge reset_n) if(!reset_n) sel_num <= 3'b000; else if(disp_en) sel_num <= sel_num + 1'b1; //sel_num =3'b111; +1'b1 3'b000; always@(posedge clk or negedge reset_n) if(!reset_n) sel <= 8'b0000_0000; else case(sel_num) 0:sel <= 8'b0000_0001; 1:sel <= 8'b0000_0010; 2:sel <= 8'b0000_0100; 3:sel <= 8'b0000_1000; 4:sel <= 8'b0001_0000; 5:sel <= 8'b0010_0000; 6:sel <= 8'b0100_0000; 7:sel <= 8'b1000_0000; endcase // 段选seg [31:0]disp_data 16hex 4*8 reg [3:0] dis_tmp; always@(posedge clk ) case(sel_num) //高位放前面 0:dis_tmp <= disp_data[31:28]; 1:dis_tmp <= disp_data[27:24]; 2:dis_tmp <= disp_data[23:20]; 3:dis_tmp <= disp_data[19:16]; 4:dis_tmp <= disp_data[15:12]; 5:dis_tmp <= disp_data[11:8]; 6:dis_tmp <= disp_data[7:4]; 7:dis_tmp <= disp_data[3:0]; endcase always@(posedge clk) case(dis_tmp) 0:seg <= 8'hc0; 1:seg <= 8'hf9; 2:seg <= 8'ha4; 3:seg <= 8'hb0; 4:seg <= 8'h99; 5:seg <= 8'h92; 6:seg <= 8'h82; 7:seg <= 8'hf8; 8:seg <= 8'h80; 9:seg <= 8'h90; 4'ha:seg <= 8'h88; 4'hb:seg <= 8'h83; 4'hc:seg <= 8'hc6; 4'hd:seg <= 8'ha1; 4'he:seg <= 8'h86; 4'hf:seg <= 8'h8e; endcase endmodule |

4.2 hex_8_tb

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `timescale 1ns / 1ns module hex_8_tb( ); reg clk , reset_n; reg [31:0]disp_data; wire[7:0]sel; wire[7:0]seg; hex_8 hex_8_(. clk(clk), . reset_n(reset_n), . disp_data(disp_data), . sel(sel), . seg(seg) ); initial clk = 1 ; always#10 clk = ~clk; initial begin reset_n = 0 ; #201; reset_n = 1 ; disp_data = 32'h01234567; #10000000; disp_data = 32'h89abcdef; #10000000; $stop; end endmodule |
| |
| 红色框框内输入数据发生了改变,但是很快就会闪过去 所以没有像串口发送添加一个存储数据让其保持一个运行周期 Vivado 串口通信(UART)------串口发送-CSDN博客 |

5. 串口接收 + 数码管动态显示

5.1 design sources

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| module uart_rx(input clk , input reset_n , input uart_rx , output reg [7:0]rx_data, output reg rx_done ); //默认使用波特率BAUD 9600 时钟频率 CLK_FREQ 50MHz // parameter start_bit = 0 ; // parameter stop_bit = 1 ; parameter BAUD = 9600; parameter CLK_FREQ = 50_000_000; parameter bps_c = CLK_FREQ / BAUD ; reg rx_en ; reg[3:0] rx_flag; // bps reg [30:0] counter_bps ; always@(posedge clk or negedge reset_n) if(! reset_n) counter_bps <= 0 ; else if (rx_en) if(counter_bps == bps_c - 1) counter_bps <= 0 ; else counter_bps <= counter_bps + 1'b1 ; else counter_bps <= 0 ; reg dff_rx_0 , dff_rx_1 ; reg r_uart_rx; wire neg_rx_go ; always@(posedge clk ) dff_rx_0 <= uart_rx ; always@(posedge clk ) dff_rx_1 <= dff_rx_0 ; always@(posedge clk ) r_uart_rx <= dff_rx_1 ; assign neg_rx_go = (dff_rx_1 == 0)&&(r_uart_rx == 1); // rx_en always@(posedge clk or negedge reset_n) if(! reset_n) rx_en <= 0 ; else if(neg_rx_go) rx_en <= 1 ; else if((rx_flag==9)&&(counter_bps == bps_c / 2)) rx_en <= 0 ; else if((rx_flag==0)&&(counter_bps == bps_c/2 )&&(dff_rx_1==1)) rx_en <= 0 ; // rx_flag always@(posedge clk or negedge reset_n) if(!reset_n) rx_flag <= 4'b0000 ; else if((rx_flag == 9)&&(counter_bps == bps_c /2)) rx_flag <= 4'b0000 ; else if(counter_bps == bps_c - 1) rx_flag <= rx_flag + 1'b1 ; // [7:0]r_rx_data reg [7:0] r_rx_data; always@(posedge clk ) if(!rx_en) r_rx_data <= r_rx_data; else if(counter_bps == bps_c / 2) begin case(rx_flag) 1 : r_rx_data[0] <= dff_rx_1; 2 : r_rx_data[1] <= dff_rx_1; 3 : r_rx_data[2] <= dff_rx_1; 4 : r_rx_data[3] <= dff_rx_1; 5 : r_rx_data[4] <= dff_rx_1; 6 : r_rx_data[5] <= dff_rx_1; 7 : r_rx_data[6] <= dff_rx_1; 8 : r_rx_data[7] <= dff_rx_1; default : r_rx_data <= r_rx_data; endcase end // rx_done always@(posedge clk) rx_done <= (rx_flag==9)&&(counter_bps == bps_c /2); // rx_data ; always@(posedge clk) if(rx_done) rx_data <= r_rx_data; endmodule |
| rx_hex8 |
| module rx_hex8(input clk, input reset_n, input uart_rx , output [7:0]sel, output [7:0]seg ); reg [1:0] rx_done_flag; reg [31:0]disp_data; wire [7:0] rx_data; wire rx_done; uart_rx uart_rx_(. clk(clk) , . reset_n(reset_n) ,.uart_rx(uart_rx) , . rx_data(rx_data), . rx_done(rx_done) ); always@(posedge clk or negedge reset_n) if(! reset_n) rx_done_flag <= 2'b11 ; else if(rx_done) rx_done_flag <= rx_done_flag + 1'b1 ; always@(posedge clk or negedge reset_n) if(! reset_n) disp_data <= 8'h0000_0000 ; else case(rx_done_flag) 0:begin disp_data <= disp_data; disp_data[7:0] <= rx_data;end 1:begin disp_data <= disp_data; disp_data[15:8] <= rx_data;end 2:begin disp_data <= disp_data; disp_data[23:16] <= rx_data;end 3:begin disp_data <= disp_data; disp_data[31:24] <= rx_data;end endcase hex_8 hex_8_(. clk(clk), . reset_n(reset_n), . disp_data(disp_data), .sel(sel), .seg(seg) ); endmodule |

5.2 rx_hex8_tb

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `timescale 1ns / 1ns module hex_8_tb( ); reg clk , reset_n , uart_rx_; wire[7:0]sel; wire[7:0]seg; rx_hex8 rx_hex8_(. clk(clk), . reset_n(reset_n), . uart_rx(uart_rx_), . sel(sel), . seg(seg) ); initial clk = 1 ; always#10 clk = ~clk; initial begin reset_n = 0 ; #201; reset_n = 1 ; uart_rx_ = 1 ;#(5208*20); //0 f uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); //9 6 uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); //4 5 uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); // 3 c uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); //0 f uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20); uart_rx_ = 1 ; #(5208*20); # 10000; $stop; end endmodule |
| |

//好耶~~~~~

//摸鱼结束哩 (゚O゚)

//顺便挖坑SPI协议

相关推荐
云山工作室2 小时前
基于单片机和LabVIEW的多路数据采集器系统设计(论文+源码)
单片机·嵌入式硬件·毕业设计·labview·毕设
辰哥单片机设计2 小时前
STM32项目分享:智能热水器
stm32·单片机·嵌入式硬件
___波子 Pro Max.3 小时前
序列化 vs 反序列化
stm32·单片机·嵌入式硬件
梁洪飞3 小时前
使用rockchip sdk提供的uboot调通网络
linux·网络·arm开发·嵌入式硬件·arm
小渔村的拉线工3 小时前
20.IIC通信上拉电阻的计算
嵌入式硬件·iic·硬件知识·上拉电阻
来生硬件工程师4 小时前
【信号完整性与电源完整性分析】什么是信号完整性?什么是电源完整性?
笔记·stm32·单片机·嵌入式硬件·硬件工程
单片机系统设计4 小时前
基于STM32的宠物智能喂食系统
c语言·stm32·单片机·嵌入式硬件·物联网·毕业设计·宠物
雾削木4 小时前
STM32 HAL DS1302时钟模块
stm32·单片机·嵌入式硬件
啊阿狸不会拉杆5 小时前
《计算机操作系统》第六章-输入输出系统
java·开发语言·c++·人工智能·嵌入式硬件·os·计算机操作系统
国科安芯5 小时前
商业卫星轴角转换器的抗辐照MCU尺寸约束研究
单片机·嵌入式硬件·架构·安全性测试