74hc595驱动数码管
avr74hc595驱动四位数码管程序

avr74hc595驱动四位数码管程序
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define wei1_h PORTB|=BIT(4);//第1位为高电平
#define wei1_l DDRB&=~BIT(4);//第1位为低电平
#define wei4_h PORTB|=BIT(7);//第4位为高电平
#define wei4_l DDRB&=~BIT(7);//第4位为低电平
void hc595_write(uchar dat)
{
uchar i;
PORTC&=~BIT(7);//输出使能 低有效
DDRC|=BIT(7);
{
wei1_h;//位1
hc595_write(0x3f);//显示0
}
}
#define wei2_h PORTB|=BIT(5);//第2位为高电平
#define wei2_l DDRB&=~BIT(5);//第2位为低电平
#define wei3_h PORTB|=BIT(6);//第3位为高电平
#define wei3_l DDRB&=~BIT(6);//第3位为低电平
PORTB&=~BIT(3);
DDRB|=BIT(3);//MISO置底
PORTB|=BIT(3);
DDRB|=BIT(3);//MISO制高
for(i=0;i<8;i++)
{
PORTB&=~BIT(1);
74HC595与数码管

第十九篇 74HC595与数码管2011-03-08 15:07第十九篇 74HC595与数先引用一句官方语:“74HC595是硅结构的CMOS器件,兼容低电压TTL电路,遵守JEDEC标准。
长话短说,它的功能是8位串行输入并行输出移位寄存器,也就是串行转并行。
下图是封装图:74HC595内部有两个寄存器:8位移位寄存器和8为存储寄存器,下面要PROTEUS做下各个引脚的调试一下可以看出:DS为串行数据输入口;SH_CP为串行时钟输入口,SH_CP每个上升沿到来时,芯片内部的移位寄存高位移出丢失,次高位成为最高位,并在Q7'体现出来(根据Q7'可以看出,74HC595也有串行输寄存器的值输出到存储寄存器,存储寄存器直接和引脚Q0~Q7相连,所以存储寄存器的值会直接反行功能;OE是输出使能,高电平时Q0~Q7为高阻态,低电平时Q0~Q7为存储寄存器的值;MR为低时无效;VCC接电源;GND接地。
好了,所有引脚介绍完了。
有的封装图引脚名字不太一样,功能下面用两片74HC595(U1和U2)分别控制四位数码管(U1)的显示和选位(U2),为了减少连线U1的DS),这样连续向U2的DS写两个字节(第一个是要显示的数字,第二个是位选),就可以连SH_CP,P0.6连DS,P0.7连P0.7ST_CP)就可以操作此四连共阴数码管(注意是共阴,不是上篇示的数字”和“位选”取反即可)。
如下图:这个实验测试下://*********************************************************************************** //功能:LPC2103利用两片74HC595操作四位共阴数码管//说明://用两片74HC595(U1和U2)分别控制四位数码管(U1)的显示和选位(U2),//为了减少连线,两片74HC595串联(U2的Q7'输出到U1的DS),这样连续向U2的DS写//两个字节(第一个是要显示的数字,第二个是位选),就可以显示了。
74HC595驱动四位数码管

_____________________________________________________
电源端/地端电流 ±70 mA
_____________________________________________________
74HC595
74HC595控制四位数码管
74HC595芯片资料
74HC595是8位串入并出的接口芯片
74HC595芯片资料
74HC595芯片资料
74HC595的控制端说明
CR(10脚):低电平时将移位寄存器的数据清零,通常将字接VCC CPSR(11脚):上升沿时数据寄存器的数据移位。Q0-Q1-..Q7:下降沿移位寄存器数据不 变。(脉冲宽度:5V时,大于几十纳秒就行了,通常选微秒级) CPLA(12脚):高电平时移位寄存器的数据进入数据存储寄存器,低电平时存储寄存器数据 不变,通常将CPLA置为低电平,当移位结束后,在CPLA端产生一个正脉冲 (5V时,大于几十纳秒就行了,通常都选微秒级),更新显示数据。 EN(13脚):高电平时禁止输出(高阻态),如果单片机的引脚下不紧张,用一个引脚控制 它,可以方便的产生闪烁和熄灭的效果,比通过数据端移位控制要省时省力。
输出电压 VO -0.5~VCC+0.5 V
_____________________________________________________
钳位二极管电流 IIK/IOK ±20 mA
_________________________________________5芯片资料
极限参数:
参数 电源电压 输入电压 符号 VCC VI 参数范围 -0.5~7 -0.5~VCC+0.5 单位 V V
51单片机+74HC595驱动数码管程序

51单片机+74HC595驱动数码管程序这里是电路图:完整的源码和图纸下载地址:51hei/bbs/dpj-20392-1.html下面是51 单片机驱动74hc595 芯片的程序:#include //包含51 单片机的头文件#include #define uint unsigned int#define uchar unsigned char//sbit sin_595 =P1;//sbit rclk_595 =P1;//sb it sclk_595 =P1 ;//sbit s_clr =P1;sb it a_cp_595 =P2; //串行移位时钟脉冲sh_cp_595sbit b_cp_595 =P2;//输出锁存器控制脉冲st_cp_595//sbit _oe_595 =P1 ; //8 位并行输出使能/禁止(高阻态)sbit ds_595=P2 ; //串行数据输入extern uchar datas[6]; //存放6 个数码管的显示数字uchar ledcode[]={0xC0,// 00xF9,// 10xA4,// 20xB0,// 30x99,// 40x92,// 50x82,// 60xF8,// 70x80,// 80x90,// 90x88,// A0x83,// B0xC6,// C0xA1,// D0x86,// E0x8E// F};void delay(uint z){uint t1,y;for(t1=z;t1>0;t1--)for(y=110;y>0;y--);}voidled_display(void){ uchar i,j; bit testb; uchar bdata movebit[6]; uchar bdata test; //_oe_595=0; //选中数码管for(i=0;i<6;i++) movebit[i]=ledcode[datas[i]]; // P1=0; delay(1); for(i=0;i<6;i++) //数据移位{ test=movebit[i]; for(j=0;j<8;j++) { testb=test&0x80; test=test<<1; if(testb) { ds_595=1; } else {ds_595=0; }a_cp_595=1; a_cp_595=0; } //数据移位} b_cp_595=0; b_cp_595=1; b_cp_595=0;} tips:感谢大家的阅读,本文由我司收集整编。
74HC595驱动两个7段数码管

一个程序输出正好要用两个BCD数码管显示P0的读出数据,不巧手头只有单个的这种共阳极7段数码管。
于是用两片74HC595驱动了这两个数码管,达到显示数据的目的。
网上的很多程序都是74HC595驱动多位数码管的,如果要驱动这样比较“原始”的单个数码管,只好自己参考了一些程序,改写了程序,仿真以及实践成功。
本程序简单修改也可以用在其他74HC595电路以及7段数码管驱动等应用上。
Proteus仿真画面如下:源程序如下:#include<reg51.h> //51头文件#include<intrins.h>//“空指令”头文件sbit H_SH=P3^0;sbit H_DS=P3^1;sbit H_ST=P3^2; //H 管脚定义sbit L_SH=P3^3;sbit L_DS=P3^4;sbit L_ST=P3^5; //L 管脚定义int num[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳极数码管,先显示A~H各段,确认各段电路是否正常,然后显示0~F。
// int num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴极数码管的编码//-----延时子程序------void delay(int i) //延时大小与i有关{int j;while(i--)for(j=255;j>0;j--);}//-----LED显示子程序------void led(){static int j=0;int i;for(i=0;i<8;i++){H_DS=(num[j]<<i)&0x80;//位//shcp=0;H_SH=0;_nop_();_nop_();H_SH=1; //上升沿有效}//stcp=0;H_ST=0;_nop_();_nop_();H_ST=1; //上升沿有效j++;if(j==24)j=0; //满24后,从新计次}void led1(){static int j=0;int i;for(i=0;i<8;i++){L_DS=(num[j]<<i)&0x80;//位L_SH=0;_nop_();_nop_();L_SH=1; //上升沿有效}L_ST=0;_nop_();_nop_();L_ST=1; //上升沿有效j++;if(j==24)j=0; //满24后,从新计次}//---主程序-------void main(){while(1) //循环{led();delay(100);led1();delay(100);}}。
74hc595寄存器工作原理

74hc595寄存器工作原理74HC595是一种串行输入并行输出的移位寄存器,常用于扩展微控制器的输出端口。
它可以将少量的IO口通过串行输入的方式扩展成更多的输出端口,提高了系统的可扩展性和灵活性。
本文将从74HC595寄存器的工作原理、应用场景和使用方法等方面进行介绍。
一、工作原理74HC595寄存器由8个输出端口(Q0-Q7)、三个控制端口(SER、SRCLK、RCLK)和一个串行数据输入端口(SER)组成。
其工作原理如下:1. 初始化:将SRCLK和RCLK置为低电平,将SER和SRCLR(异步清零端)置为高电平。
2. 数据输入:通过SER输入要输出的数据,然后将SRCLK引脚置为高电平,使得SRCLK上升沿时,数据从SER端口输入到寄存器。
重复此操作,直到输入完所有数据。
3. 数据输出:输入完所有数据后,将RCLK引脚置为高电平,使得RCLK上升沿时,数据从寄存器输出到输出端口Q0-Q7。
通过上述过程,可以将串行输入的数据转换为并行输出,从而实现多个输出端口的控制。
二、应用场景74HC595寄存器广泛应用于各种需要扩展输出端口的场景,例如LED数码管显示、驱动数码管显示、控制继电器等。
1. LED数码管显示:通过74HC595寄存器的输出端口控制多个LED数码管的显示。
将LED数码管的阳极连接到电源,将74HC595寄存器的输出端口连接到LED数码管的阴极,通过控制输出端口的高低电平来控制LED的亮暗。
2. 驱动数码管显示:通过74HC595寄存器的输出端口控制多个数码管的显示。
将数码管的段选引脚连接到74HC595寄存器的输出端口,通过控制输出端口的高低电平来控制数码管的显示。
3. 控制继电器:通过74HC595寄存器的输出端口控制多个继电器的开关。
将继电器的控制端口连接到74HC595寄存器的输出端口,通过控制输出端口的高低电平来控制继电器的开关状态。
三、使用方法使用74HC595寄存器需要按照以下步骤进行:1. 初始化:将SRCLK和RCLK置为低电平,将SER和SRCLR置为高电平。
595驱动数码管

器件:74hc595.引脚说明:SDA:数据输入口。
SH_CP:数据输入控制端,在每个SH_CP的上升沿, SDA口上的数据移入寄存器, 在SH_CP的第9个上升沿, 数据开始从QS移出。
ST_CP:数据置入锁存器控制端。
Q0~Q7:数据并行输出端。
数据从SDA 口送入74HC595 , 在每个SH_CP的上升沿, SDA口上的数据移入寄存器, 在SH_CP的第9个上升沿, 数据开始从QS 移出。
如果把第一个74HC595的QS和第二个74HC595 的SDA 相接, 数据即移入第二个74HC595中,照此一个一个接下去, 可接任意多个。
数据全部送完后, 给ST_CP一个上升沿, 寄存器中的数据即置入锁存器。
此时如果EN 为低电平, 数据即从并口Q0~Q7输出, 把Q0~Q7 与LED的8 段相接, LED就可以实现显示了。
要想软件改变LED的亮度, 只需改变EN的占空比就行了。
实验原理及内部结构:如图所示:74HC595 内含8 位串入、串/并出移位寄存器和8位三态输出锁存器。
寄存器和锁存器分别有各自的时钟输入(SH_CP和ST_CP) , 都是上升沿有效。
当SH_CP从低到高电平跳变时,串行输入数据(SDA) 移入寄存器;当ST_CP从低到高电平跳变时, 寄存器的数据置入锁存器。
清除端(CLR) 的低电平只对寄存器复位(QS 为低电平) ,而对锁存器无影响。
当输出允许控制(EN) 为高电平时, 并行输出(Q0~Q7) 为高阻态, 而串行输出(QS) 不受影响。
74HC595 最多需要5 根控制线,即SDA、SH_CP、ST_CP、CLR 和EN。
其中CLR 可以直接接到高电平, 用软件来实现寄存器清零; 如果不需要软件改变亮度, EN可以直接接到低电平, 而用硬件来改变亮度。
把其余三根线和单片机的I/ O 口相接, 即可实现对LED 的控制。
数据从SDA 口送入74HC595 ,在每个SH_CP的上升沿, SDA口上的数据移入寄存器, 在SH_CP的第9个上升沿, 数据开始从QS 移出。
74HC595驱动两位数码管

在前文讲述1位LED数码管显示的基础之上,本文进一步介绍2位LED数码管的工作原理及用法。
1.1 2位LED数码管工作原理与1位数码管不同的是,2位数码管显示时要进行位选。
如图1.2所示,公共脚10决定位DIG1是否有效,公共脚5决定位DIG2是否有效。
图1.1与图1.2显示了2位数码管引脚分布和内部电路设计。
其中笔段分布如图1.1所示,引脚对应笔段分布如图1.2所示。
图1.1 2位数码管笔段图1.2 2位数码管引脚图2位数码管引脚分如:1) 公共脚:10、5 ;2)DIG:A-3 B-9 C-8 D-6 E-7 F-4 G-1 DP- 2。
1.2 74HC595简介74HC595是一款具有8位移位寄存器和一个存储器,三态输出功能的驱动芯片。
移位寄存器和存储器分别具有独立的时钟信号。
数据在SHCP的上升沿输入,在STCP的上升沿进入到存储寄存器中去。
如果两个时钟连在一起,则移位寄存器总是比存储寄存器早一个脉冲。
移位寄存器有一个串行移位输入(DS),和一个串行输出(Q7’),和一个异步的低电平复位(MR),存储寄存器有一个并行8位的,具备三态的总线输出,当使能OE时(为低电平),存储寄存器的数据输出到总线。
图1.3 74HC595引脚图74HC595引脚排布如图1.3所示,引脚功能见表1.1。
表1.1 74HC595引脚功能1.3硬件电路设计1.3.1设计原理本设计采用LPC2103自带的硬件SPI接口与74HC595进行数据传输。
74HC595将LPC2103发送过来的8位串行数据转换成8位并行数据来驱动2位共阳数码管。
与1位数码管类似,2位LED数码管的输入端在5 V电源或高于TTL高电平(3.5 V)的电路信号相接时,一定要串加限流电阻,以免损坏器件。
如图1.4所示2位数码管设计原理图。
位选控制脚如表1.2所示。
由于本设计采用共阳数码管,所以2位数码管位选引脚选择用LPC2103的P0.8与P0.9控制。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
74hc595驱动数码管版本一顶层例化文件module seg7x8(input CLOCK_50, // 板载50MHz时钟input Q_KEY, // 板载按键RSToutput [7:0] SEG7_SEG, // 七段数码管 段脚 output [2:0] SEG7_SEL // 七段数码管 待译位脚);// 显示效果:// -------------------------// |1 |2.|3 |4 | |B |C |D |// -------------------------seg7x8_drive u0(.i_clk (CLOCK_50),.i_rst_n (Q_KEY),.i_turn_off (8'b0000_1000), // 熄灭位[2进制][此处取第3位.i_dp (8'b0100_0000), // 小数点位[2进制][此处取第6位 .i_data (32'h1234_ABCD), // 欲显数据[16进制].o_seg(SEG7_SEG),.o_sel(SEG7_SEL));endmodule驱动文件module seg7x8_drive(input i_clk,input i_rst_n,input [7:0] i_turn_off, // 熄灭位[2进制input [7:0] i_dp, // 小数点位[2进制input [31:0] i_data, // 欲显数据[16进制output [7:0] o_seg, // 段脚output [2:0] o_sel // 使用74HC138译出位脚 );//++++++++++++++++++++++++++++++++++++++// 分频部分 开始//++++++++++++++++++++++++++++++++++++++reg [16:0] cnt; // 计数子always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)cnt <= 0;elsecnt <= cnt + 1'b1;wire seg7_clk = cnt[16]; // (2^17/50M = 2.6114)ms //--------------------------------------// 分频部分 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 动态扫描, 生成seg7_addr 开始//++++++++++++++++++++++++++++++++++++++reg [2:0] seg7_addr; // 第几个seg7always @ (posedge seg7_clk, negedge i_rst_n)if (!i_rst_n)seg7_addr <= 0;elseseg7_addr <= seg7_addr + 1'b1;//--------------------------------------// 动态扫描, 生成seg7_addr 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 译出位码 开始//++++++++++++++++++++++++++++++++++++++reg [2:0] o_sel_r; // 位选码寄存器// 开发板上SEG7的方向是低位在左,高位在右// 但是实际上我们看数的方向是高位在左,低位在右// 故此处将第0位对应DIG[7],第7位对应DIG[0]alwayscase (seg7_addr)0 : o_sel_r = 3'b111; // SEG7[7]1 : o_sel_r = 3'b110; // SEG7[6]2 : o_sel_r = 3'b101; // SEG7[5]3 : o_sel_r = 3'b100; // SEG7[4]4 : o_sel_r = 3'b011; // SEG7[3]5 : o_sel_r = 3'b010; // SEG7[2]6 : o_sel_r = 3'b001; // SEG7[1]7 : o_sel_r = 3'b000; // SEG7[0]endcase//--------------------------------------// 根据seg7_addr, 译出位码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 选择熄灭码 开始//++++++++++++++++++++++++++++++++++++++reg turn_off_r; // 熄灭码alwayscase (seg7_addr)0 : turn_off_r = i_turn_off[0];1 : turn_off_r = i_turn_off[1];2 : turn_off_r = i_turn_off[2];3 : turn_off_r = i_turn_off[3];4 : turn_off_r = i_turn_off[4];5 : turn_off_r = i_turn_off[5];6 : turn_off_r = i_turn_off[6];7 : turn_off_r = i_turn_off[7];endcase//--------------------------------------// 根据seg7_addr, 选择熄灭码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 选择小数点码 开始//++++++++++++++++++++++++++++++++++++++reg dp_r; // 小数点码alwayscase (seg7_addr)0 : dp_r = i_dp[0];1 : dp_r = i_dp[1];2 : dp_r = i_dp[2];3 : dp_r = i_dp[3];4 : dp_r = i_dp[4];5 : dp_r = i_dp[5];6 : dp_r = i_dp[6];7 : dp_r = i_dp[7];endcase//--------------------------------------// 根据seg7_addr, 选择小数点码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 选择待译段码 开始//++++++++++++++++++++++++++++++++++++++reg [3:0] seg_data_r; // 待译段码alwayscase (seg7_addr)0 : seg_data_r = i_data[3:0];1 : seg_data_r = i_data[7:4];2 : seg_data_r = i_data[11:8];3 : seg_data_r = i_data[15:12];4 : seg_data_r = i_data[19:16];5 : seg_data_r = i_data[23:20];6 : seg_data_r = i_data[27:24];7 : seg_data_r = i_data[31:28];endcase//--------------------------------------// 根据seg7_addr, 选择待译段码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据熄灭码/小数点码/待译段码// 译出段码,开始//++++++++++++++++++++++++++++++++++++++reg [7:0] o_seg_r; // 段码寄存器/** 0* -------* | |* 5| 6 |1* -------* | |* 4| |2* ------- . 7* 3*/// 共阳always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)o_seg_r <= 8'hFF; // 送熄灭码 elseif(turn_off_r) // 送熄灭码 o_seg_r <= 8'hFF;elseif(!dp_r)case(seg_data_r) // 无小数点 4'h0 : o_seg_r <= 8'hC0;4'h1 : o_seg_r <= 8'hF9;4'h2 : o_seg_r <= 8'hA4;4'h3 : o_seg_r <= 8'hB0;4'h4 : o_seg_r <= 8'h99;4'h5 : o_seg_r <= 8'h92;4'h6 : o_seg_r <= 8'h82;4'h7 : o_seg_r <= 8'hF8;4'h8 : o_seg_r <= 8'h80;4'h9 : o_seg_r <= 8'h90;4'hA : o_seg_r <= 8'h88;4'hB : o_seg_r <= 8'h83;4'hC : o_seg_r <= 8'hC6;4'hD : o_seg_r <= 8'hA1;4'hE : o_seg_r <= 8'h86;4'hF : o_seg_r <= 8'h8E;endcaseelsecase(seg_data_r) // 加小数点4'h0 : o_seg_r <= 8'hC0 ^ 8'h80;4'h1 : o_seg_r <= 8'hF9 ^ 8'h80;4'h2 : o_seg_r <= 8'hA4 ^ 8'h80;4'h3 : o_seg_r <= 8'hB0 ^ 8'h80;4'h4 : o_seg_r <= 8'h99 ^ 8'h80;4'h5 : o_seg_r <= 8'h92 ^ 8'h80;4'h6 : o_seg_r <= 8'h82 ^ 8'h80;4'h7 : o_seg_r <= 8'hF8 ^ 8'h80;4'h8 : o_seg_r <= 8'h80 ^ 8'h80;4'h9 : o_seg_r <= 8'h90 ^ 8'h80;4'hA : o_seg_r <= 8'h88 ^ 8'h80;4'hB : o_seg_r <= 8'h83 ^ 8'h80;4'hC : o_seg_r <= 8'hC6 ^ 8'h80;4'hD : o_seg_r <= 8'hA1 ^ 8'h80;4'hE : o_seg_r <= 8'h86 ^ 8'h80;4'hF : o_seg_r <= 8'h8E ^ 8'h80;endcase//--------------------------------------// 根据熄灭码/小数点码/待译段码// 译出段码,结束//--------------------------------------assign o_sel = o_sel_r; // 寄存器输出位选码 assign o_seg = o_seg_r; // 寄存器输出段码endmodule版本2顶层例化文件module seg7x8(input CLOCK_50, // 板载50MHz时钟input [1:1] KEY, // KEY[1]output [7:0] SEG7_SEG, // 七段数码管 段脚 output [7:0] SEG7_DIG // 七段数码管 位脚);// 显示效果:// -------------------------// |1 |2.|3 |4 | |B |C |D |// -------------------------seg7x8_drive u0(.i_clk (CLOCK_50),.i_rst_n (KEY),.i_turn_off (8'b0000_1000), // 熄灭位[2进制][此处取第3位.i_dp (8'b0100_0000), // 小数点位[2进制][此处取第6位 .i_data (32'h1234_ABCD), // 欲显数据[16进制].o_seg (SEG7_SEG),.o_dig (SEG7_DIG));endmodule驱动文件module seg7x8_drive(input i_clk,input i_rst_n,input [7:0] i_turn_off, // 熄灭位[2进制input [7:0] i_dp, // 小数点位[2进制input [31:0] i_data, // 欲显数据[16进制output [7:0] o_seg, // 段脚output [7:0] o_dig // 位脚);//++++++++++++++++++++++++++++++++++++++// 分频部分 开始//++++++++++++++++++++++++++++++++++++++reg [16:0] cnt; // 计数子always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)cnt <= 0;elsecnt <= cnt + 1'b1;wire seg7_clk = cnt[16]; // (2^17/50M = 2.6114)ms //--------------------------------------// 分频部分 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 动态扫描, 生成seg7_addr 开始//++++++++++++++++++++++++++++++++++++++reg [2:0] seg7_addr; // 第几个seg7always @ (posedge seg7_clk, negedge i_rst_n)if (!i_rst_n)seg7_addr <= 0;elseseg7_addr <= seg7_addr + 1'b1;//--------------------------------------// 动态扫描, 生成seg7_addr 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 译出位码 开始//++++++++++++++++++++++++++++++++++++++reg [7:0] o_dig_r; // 位码寄存器// 开发板上SEG7的方向是低位在左,高位在右// 但是实际上我们看数的方向是高位在左,低位在右// 故此处将第0位对应DIG[7],第7位对应DIG[0]alwayscase (seg7_addr)0 : o_dig_r = 8'b0000_0001;1 : o_dig_r = 8'b0000_0010;2 : o_dig_r = 8'b0000_0100;3 : o_dig_r = 8'b0000_1000;4 : o_dig_r = 8'b0001_0000;5 : o_dig_r = 8'b0010_0000;6 : o_dig_r = 8'b0100_0000;7 : o_dig_r = 8'b1000_0000;endcase//--------------------------------------// 根据seg7_addr, 译出位码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 选择熄灭码 开始//++++++++++++++++++++++++++++++++++++++reg turn_off_r; // 熄灭码alwayscase (seg7_addr)0 : turn_off_r = i_turn_off[0];1 : turn_off_r = i_turn_off[1];2 : turn_off_r = i_turn_off[2];3 : turn_off_r = i_turn_off[3];4 : turn_off_r = i_turn_off[4];5 : turn_off_r = i_turn_off[5];6 : turn_off_r = i_turn_off[6];7 : turn_off_r = i_turn_off[7];endcase//--------------------------------------// 根据seg7_addr, 选择熄灭码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 选择小数点码 开始//++++++++++++++++++++++++++++++++++++++reg dp_r; // 小数点码alwayscase (seg7_addr)0 : dp_r = i_dp[0];1 : dp_r = i_dp[1];2 : dp_r = i_dp[2];3 : dp_r = i_dp[3];4 : dp_r = i_dp[4];5 : dp_r = i_dp[5];6 : dp_r = i_dp[6];7 : dp_r = i_dp[7];endcase//--------------------------------------// 根据seg7_addr, 选择小数点码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据seg7_addr, 选择待译段码 开始//++++++++++++++++++++++++++++++++++++++reg [3:0] seg_data_r; // 待译段码alwayscase (seg7_addr)0 : seg_data_r = i_data[3:0];1 : seg_data_r = i_data[7:4];2 : seg_data_r = i_data[11:8];3 : seg_data_r = i_data[15:12];4 : seg_data_r = i_data[19:16];5 : seg_data_r = i_data[23:20];6 : seg_data_r = i_data[27:24];7 : seg_data_r = i_data[31:28];endcase//--------------------------------------// 根据seg7_addr, 选择待译段码 结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 根据熄灭码/小数点码/待译段码// 译出段码,开始//++++++++++++++++++++++++++++++++++++++reg [7:0] o_seg_r; // 段码寄存器/** 0* -------* | |* 5| 6 |1* -------* | |* 4| |2* ------- . 7* 3*/// 共阳always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)o_seg_r <= 8'hFF; // 送熄灭码 elseif(turn_off_r) // 送熄灭码 o_seg_r <= 8'hFF;elseif(!dp_r)case(seg_data_r) // 无小数点 4'h0 : o_seg_r <= 8'hC0;4'h1 : o_seg_r <= 8'hF9;4'h2 : o_seg_r <= 8'hA4;4'h3 : o_seg_r <= 8'hB0;4'h4 : o_seg_r <= 8'h99;4'h5 : o_seg_r <= 8'h92;4'h6 : o_seg_r <= 8'h82;4'h7 : o_seg_r <= 8'hF8;4'h8 : o_seg_r <= 8'h80;4'h9 : o_seg_r <= 8'h90;4'hA : o_seg_r <= 8'h88;4'hB : o_seg_r <= 8'h83;4'hC : o_seg_r <= 8'hC6;4'hD : o_seg_r <= 8'hA1;4'hE : o_seg_r <= 8'h86;4'hF : o_seg_r <= 8'h8E;endcaseelsecase(seg_data_r) // 加小数点4'h0 : o_seg_r <= 8'hC0 ^ 8'h80;4'h1 : o_seg_r <= 8'hF9 ^ 8'h80;4'h2 : o_seg_r <= 8'hA4 ^ 8'h80;4'h3 : o_seg_r <= 8'hB0 ^ 8'h80;4'h4 : o_seg_r <= 8'h99 ^ 8'h80;4'h5 : o_seg_r <= 8'h92 ^ 8'h80;4'h6 : o_seg_r <= 8'h82 ^ 8'h80;4'h7 : o_seg_r <= 8'hF8 ^ 8'h80;4'h8 : o_seg_r <= 8'h80 ^ 8'h80;4'h9 : o_seg_r <= 8'h90 ^ 8'h80;4'hA : o_seg_r <= 8'h88 ^ 8'h80;4'hB : o_seg_r <= 8'h83 ^ 8'h80;4'hC : o_seg_r <= 8'hC6 ^ 8'h80;4'hD : o_seg_r <= 8'hA1 ^ 8'h80;4'hE : o_seg_r <= 8'h86 ^ 8'h80;4'hF : o_seg_r <= 8'h8E ^ 8'h80;endcase//--------------------------------------// 根据熄灭码/小数点码/待译段码// 译出段码,结束//--------------------------------------/** | c[1]* b[in] -|* | e[out]*/assign o_dig = ~o_dig_r; // 寄存器输出位码 assign o_seg = o_seg_r; // 寄存器输出段码endmodul。