(完整版)595驱动数码管
74hc595驱动数码管

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。
595驱动数码管共阳极电路

595驱动数码管共阳极电路在数码技术中,数码管是一种常见的输出设备,它通常用于显示数字。
而在数码管的分类中,共阳极电路是其中一种常见且常用的驱动方式之一。
本文将详细介绍共阳极电路及其工作原理,并提供相应的指导意义。
首先,我们来了解一下数码管的基本原理。
数码管由若干个发光二极管(LED)组成,可以通过控制LED的开关状态来显示不同的数字。
而共阳极电路是一种电路设计,它将数码管的阳极(正极)连接在一起并与电源正极相连,而每个LED的阴极(负极)则通过控制电路独立地连接在电源的负极上。
通过对每个LED独立的控制,可以实现在数码管上显示各种数字、字母或符号。
接下来,我们来了解共阳极电路的工作原理。
当控制端输入高电平时,相应的LED会被打开,并且由于阳极与正极相连,电流会从正极流入阳极,再经过相应的LED灯亮起。
而当控制端输入低电平时,相应的LED则会被关闭,此时电流无法从正极流入,数码管对应的LED 灯则熄灭。
通过这样的开关控制,可以实现对数码管的数字显示控制。
为了更好地理解共阳极电路的原理,我们可以通过一个简单的实例来说明。
假设我们有一个四位共阳极的数码管,并且我们希望在上面显示数字“1234”。
首先,我们需要在一个时钟周期内依次控制并打开第一位、第二位、第三位和第四位的LED灯。
具体操作是先将控制端1置高电平,使得第一位的LED灯点亮,其它位的LED灯都熄灭。
然后,我们将控制端2置高电平,那么第一位的LED灯熄灭,第二位的LED灯点亮,其它位的LED灯仍然熄灭。
依次类推,最后我们将控制端4置高电平,此时第三位的LED灯熄灭,第四位的LED灯点亮,数码管上的数字“1234”就完成了显示。
通过以上的实例,我们可以看到,在共阳极电路中,为了控制数码管的显示,我们需要按照顺序依次控制各个位上的LED灯的开关状态。
这样的操作需要通过相应的控制器或者微控制器来实现。
当我们需要显示多位数字时,只需要根据对应的编码关系,依次控制各个位上的LED灯,就可以实现数字的显示。
ATMEGA16端口SPI扩展例子及源代码(HC595,驱动四位数码管)

A TMEGA16端口扩展例子及源代码青岛科技大学树立学院王泽华说明:1、数码管为共阳极。
2、HC595两片,第一片锁存段码,第二片锁存位码。
3、外部晶振8MHz该图可放大观看,例如拷贝到剪切板,然后复制到画图软件中。
这样比较清楚4、PROTEUL下溶思位的选择如下图所示。
源代码如下:可直接拷贝编译运行。
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */#define F_CPU 8000000UL/* 定义SPI端口数据方向寄存器*/#define DD_SS 4#define DD_MOSI 5#define DD_MISO 6#define DD_SCK 7/* 定义SPI端口数据寄存器*/#define DR_SS 4#include <avr/io.h>#include <util/delay.h>/* 共阳极段码*/const unsigned char SEG_CODE[]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09}; /* 位码*/const unsigned char BIT_CODE[]={0x80,0x40,0x20,0x10};/* SPI端口初始化*/void SPI_master_init(){/* 定义SPI主机,SS线,MOSI线,SCK线为输出*/DDRB = (1<<DD_SS) | (1<<DD_MOSI) | (1<<DD_SCK);/* 打开SPI端口,设本机为SPI主机,SCK=FOSC/16 */SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);/* SPI工作于MODE4 */SPCR |= (1<<CPOL) | (1<<CPHA);}/* 传输,特别用于只发不收,例如2片HC595控制数码管显示,每次传输两字节,第一字节为位码,第二字节为段码*/void SPI_master_send(char *pData, int iDataLen){int i;char temp;/* 拉低SS引脚,告之从机,开始数据传输*/PORTB &= ~( 1<<DR_SS );/* 发送数据*/for( i=0; i<iDataLen; i++){SPDR = pData[i];/* 等待发送完成*/while( !( SPSR & (1<<SPIF) ) );/* 清标志寄存器SPIF WCOL */temp = SPSR;temp = SPDR;}/* 拉高SS引脚,完成一次通讯,对HC595,拉高后595将移位寄存器数据锁存入数据寄存器*/PORTB |= ( 1<<DR_SS );}int main(){unsigned char i;char cData[2];/* SPI端口初始化*/SPI_master_init();while(1){for(i=0; i<4; i++){/* 先关闭数码管,消隐*/cData[0] = BIT_CODE[i];cData[1] = 0xFF;SPI_master_send(cData,2);/* 发送显示的数据*/cData[0] = BIT_CODE[i];cData[1] = SEG_CODE[i];SPI_master_send(cData,2);_delay_ms(4);}}}。
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);}}。
51单片机hc595控制一位数码管

/*用hc595控制数码管,显示键盘的值*/#include<reg52.h>#define unchar unsigned char#define unint unsigned intunchar temp,num;sbit scl=P3^6;sbit sda=P3^4;sbit rclk=P3^5; //寄存器时钟unchar code table[]={0x40,0xf9,0x24,0x30,0x99,0x12,0x02,0xf8,0x00,0x10,0xbf,0xb9,0xb6,0}; //数码管编码void delay1()//短延时{;;}void delay(int z) //长延时{int a,b;for(a=0;a<110;a++)for(b=0;b<z;b++);}void init()//初始化{scl=1;sda=1;rclk=0;}void start()//开始条件{scl=1;delay1();sda=1;delay1();sda=0;delay1();}void stop()//停止{scl=1;delay1();sda=0;delay1();sda=1;delay1();}void write(unsigned char temp)//写{int i;start();for(i=0;i<8;i++){scl=0;rclk=0;delay1();sda=(bit)(temp&0x80);delay1();scl=1;delay1();delay1();temp<<=1;} rclk=1;stop();}//键盘扫描unchar scan(){// unchar num,temp;// num=17;P2=0xfd;temp=P2;temp=temp&0xf0;while(temp!=0xf0){P2=0xfd;temp=P2;temp=temp&0xf0;delay(10);while(temp!=0xf0){temp=P2;temp=temp&0xf0;switch(temp){case 0xe0:num=1;break;case 0xd0:num=2;break;case 0xb0:num=3;break;case 0x70:num=4;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}// display(num-1);}}P2=0xfb;temp=P2;temp=temp&0xf0;while(temp!=0xf0){P2=0xfb;temp=P2;temp=temp&0xf0;delay(10);while(temp!=0xf0){temp=P2;switch(temp){case 0xeb:num=5;break;case 0xdb:num=6;break;case 0xbb:num=7;break;case 0x7b:num=8;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}//display(num-1);}}P2=0xf7;temp=P2;temp=temp&0xf0;while(temp!=0xf0){P2=0xf7;temp=P2;temp=temp&0xf0;delay(10);while(temp!=0xf0){temp=P2;switch(temp){case 0xe7:num=9;break;case 0xd7:num=10;break;case 0xb7:num=11;break;case 0x77:num=12;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}// display(num-1);//delay(100);}}return num;}/*void display(unchar num) {P0=table[num-1];delay(10);} */void main()//主函数{init();delay1();while(1)//大循环{write(table[scan()]);}}。
74hc595驱动数码管

74HC595的工作原理74HC595是具有8位移位寄存器和一个存储器,三态输出功能。
移位寄存器和存储器是分别的时钟。
数据在SHcp的上升沿输入,在STcp的上升沿进入的存储寄存器中去。
如果两个时钟连在一起,则移位寄存器总是比存储寄存器早一个脉冲。
移位寄存器有一个串行移位输入(Ds),和一个串行输出(Q7’),和一个异步的低电平复位,存储寄存器有一个并行8位的,具备三态的总线输出,当使能OE时(为低电平),存储寄存器的数据输出到总线。
74HC595各个引脚的功能:Q1~7 是并行数据输出口,即储寄存器的数据输出口Q7' 串行输出口,其应该接SPI总线的MISO接口STcp 存储寄存器的时钟脉冲输入口SHcp 移位寄存器的时钟脉冲输入口OE的非输出使能端MR的非芯片复位端Ds 串行数据输入端程序说明:每当SHcp上升沿到来时,DS引脚当前电平值在移位寄存器中左移一位,在下一个上升沿到来时移位寄存器中的所有位都会向左移一位,同时Q7'也会串行输出移位寄存器中高位的值,这样连续进行8次,就可以把数组中每一个数(8位的数)送到移位寄存器;然后当STcp上升沿到来时,移位寄存器的值将会被锁存到锁存器里,并从Q1~7引脚输出。
//74HC595串行输出数据void outdisp(unsigned char num){unsigned char i;for (i=0;i<8;i++ ){DS=num;SHCP=1;SHCP=0;num<<=1;}}74595的数据端:1)、QA--QH: 八位并行输出端,可以直接控制数码管的8个段。
2)、QH': 级联输出端。
我将它接下一个595的SER端。
3)、SER: 串行数据输入端。
74595的控制端说明:1) 、/SCLR(10脚): 低点平时将移位寄存器的数据清零。
通常我将它接Vcc。
2)、SCK(11脚):上升沿时数据寄存器的数据移位。
AVR单片机595驱动8位数码管的显示的电路实现

A VR单片机595驱动数码管显示一、电路实现8位数码管的电路如下图所示数码管是一种半导体发光器件,其基本单元是发光二极管。
数码管按段数分为七段数码管和八段数码管(还有一种“米”字型的数码管,其段数更多),八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示),其基本原理是:将所有LED的一端(正极、负极均可)连在一起作为一个公共端,然后通过分别控制这组LED的另一个端口来使部分LED点亮,从而达到显示一定字形的目的。
数码管的分类:按能显示多少个“8”可分为1位、2位、4位等等数码管;按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。
共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。
共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。
当某一字段的阴极为高电平时,相应字段就不亮。
共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。
共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。
当某一字段的阳极为低电平时,相应字段就不亮。
我们在实际使用中一定要搞清楚数码管是共阴极的还是共阳极的。
数码管段、位引脚的确定(以4位8段数码管为例),我们在实际应用中购买的数码管不像电阻、电容、集成等元件那样有数据手册或者直接在元件上标明管脚序号和用途,并且市场上数码管的管脚排列顺序并不是一致的,所以我们购买回来的数码管一般都要亲自测量一下各个引脚的用途,怎么测量呢?数码管引脚测量分三步:极性判断(共阳极还是共阴极)、公共端判断(位选端口)、段码端判断(段选端口)。
首先要确定数码管是共阴极还是共阳极的:找一个3到5V的直流电源,准备几个1K或者几百欧姆的电阻。
将电源的正极串接一个电阻后连在数码管的任意一个脚上,然后将电源的负极逐个接到数码管的其余引脚上,观察数码管的某一段是否会点亮,如果全部引脚试过都没有亮的,那么将电源正极(串电阻)换一个引脚再试,直到有一个LED发光,这时固定电源负极不动,电源正极(串电阻)逐个接到数码管的其余引脚上,如果有8段LED都亮,说明该数码管是共阴极的。
74hc595芯片驱动数码管的工作原理

74hc595芯片驱动数码管的工作原理
74HC595 是一种串行输入、并行输出的移位寄存器芯片,常被用于驱动数码管、LED 等输出设备。
它的工作原理基于串行-并行转换和移位操作。
以下是使用74HC595 驱动数码管的基本工作原理:
一、串行输入:74HC595 芯片具有三个输入引脚,分别是:
DS(Data Input):串行数据输入
SHCP(Shift Register Clock Input):移位寄存器时钟输入
STCP(Storage Register Clock Input):存储寄存器时钟输入
通过串行数据输入引脚DS,可以将一个字节的数据(8位)串行输入到74HC595 中。
二、移位操作:在输入完一个字节数据后,通过向SHCP 引脚提供时钟信号,数据将从串行输入DS 移位到移位寄存器中。
三、并行输出:74HC595 还有8 个并行输出引脚,分别是Q0 到Q7。
这些输出引脚可以连接到数码管的段或LED 灯的正极。
通过向STCP 引脚提供时钟信号,移位寄存器中的数据会并行输出到存储寄存器中。
四、存储寄存器:存储寄存器中的数据在时钟信号到达STCP 时被锁存,此时数据会被保持在存储寄存器中,不再改变。
通过不断重复以上的移位和存储操作,可以将多个字节的数据依次输出到74HC595 的并行输出引脚,从而实现对多个数码管或LED 灯的控制。
总的来说,74HC595 通过串行输入、移位操作和并行输出的方式,实现了对大量输出设备的控制。
这种级联的方式可以有效地减少需要的引脚数量,适用于有限的GPIO 资源的情况。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
器件: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 的QS和第二个74HC595 的SDA 相接, 数据即移入第二个74HC595 中, 照此一个一个接下去, 可接任意多个。
数据全部送完后, 给ST_CP 一个上升沿,寄存器中的数据即置入锁存器。
此时如果EN 为低电平, 数据即从并口Q0~Q7 输出, 把Q0~Q7 与LED 的8 段相接, LED就可以实现显示了。
要想软件改变LED 的亮度, 只需改变EN 的占空比就行了。
LED 的亮度用PR1~PR3 的阻值来控制。
P1 口的P115 、P116 、P117 用来控制LED 的显示,分别接到ST_CP、SH_CP和SDA 脚。
实验内容:
按下图连接器件:
程序如下所示:。