stm32使用三片74HC595级联程序代码
- 格式:docx
- 大小:8.84 KB
- 文档页数:1
74HC595是一款常见的LED驱动芯片,通常用于驱动并联的LED灯串。
它具有串行输入和并行输出,可以将一条数据线上的数据转换为N条LED灯串的数据线。
在使用74HC595时,通常需要编写一些代码来控制其工作。
首先,我们需要了解74HC595的工作原理。
它通过串行数据输入线(通常是3条数据线)接收数据,然后将这些数据转换为并行输出,驱动LED灯串。
在74HC595中,高电平表示LED灯串的导通状态,低电平表示LED灯串的截止状态。
在正极高电平的情况下,也就是说,当数据线上的电平为高电平时,LED灯串导通。
这通常意味着我们在编写代码时需要将数据线上的数据设置为高电平状态。
下面是一个简单的例子,展示如何使用Arduino编写代码来控制74HC595驱动LED灯串。
在这个例子中,我们假设74HC595有3条数据线(SDA, SCL, CPOL),并且连接到Arduino的数字引脚上。
```C++#define DATA_PIN1 7 // Data Pin 1 (SDA)#define DATA_PIN2 8 // Data Pin 2 (SCL)#define CPOL_PIN 9 // Clock Polarity (CPOL)void setup() {pinMode(DATA_PIN1, OUTPUT);pinMode(DATA_PIN2, OUTPUT);pinMode(CPOL_PIN, OUTPUT);}void loop() {// 设置数据线为高电平状态digitalWrite(DATA_PIN1, HIGH);digitalWrite(DATA_PIN2, HIGH);// 设置时钟信号为低电平状态(CPOL设置为0)digitalWrite(CPOL_PIN, LOW);// 设置计数器到LED状态顺序:a b c(在串行二进制数字系统中的1-11代码中)delayMicroseconds(5); // Clock duration = 5μs for "a" to LED, and the shift out will take another 1.7μs (Assuming SCLK = 20MHz and assuming CPOL=0)digitalWrite(DATA_PIN1, LOW); // This is a 0 shift on Data Pin 1, resulting in a bit to be on "LED on second line". It also adjusts clock speed and start counting at a high rate. delayMicroseconds(2.7); // Clock duration = 2.7μs for "b" to LED and the shift out will take another 2μs. It takes a minimum of 4μs for all the bits to be shifted out (Assuming SCLK = 20MHz and assuming CPOL=0). This is also when we will know if there was any "ababab" noise. If so, just skip this iteration and wait for a few more before again setting "a" as bit.digitalWrite(DATA_PIN2, HIGH); // This is a 1 shift on Data Pin 2. The last bit was low and the current bit is now being sent to the LEDs.delayMicroseconds(2.3); // Shift duration for "c" is around 2μs and then the shift out of the bits is complete.}```请注意,这是一个基本的示例代码,可能需要根据您的具体硬件配置和LED灯串连接进行调整。
74hc595.c#include "74hc595.h"/******************功能:定义HC595的功能引脚备注:变更引脚,由MX配置完成*******************/const T_HC595_PIN hc595 ={.sck_port = HC595_SCK_GPIO_Port.sck_pin = HC595_SCK_Pin //数据输入时钟线.data_port = HC595_SI_GPIO_Port.data_pin = HC595_SI_Pin //数据线.rck_port = HC595_RCK_GPIO_Port.rck_pin = HC595_RCK_Pin //输出存储器锁存时钟线.en_port = HC595_OE_GPIO_Port.en_pin = HC595_OE_Pin //芯片使能};/******************函数名:hc595Delay功能:实现us级延迟形参:cnt--us值返回值:无备注:*******************/void hc595Delay(volatile uint16_t cnt){while(cnt--)continue;}/******************************函数名:hc595Init功能:初始化hc595的使能脚(EN),默认工作状态形参:pin--hc595引脚结构体返回值:备注:0--器件屏蔽 1--器件工作*******************************/void hc595Init(const T_HC595_PIN *pin){HAL_GPIO_WritePin(pin->en_port pin->en_pin GPIO_PIN_RESET);}/******************************函数名:hc595DeInit功能:初始化hc595的使能脚(EN),默认休息状态形参:pin--hc595引脚结构体返回值:备注:0--器件屏蔽 1--器件工作*******************************/void hc595DeInit(const T_HC595_PIN *pin){HAL_GPIO_WritePin(pin->en_port pin->en_pin GPIO_PIN_SET);}/******************************函数名:hc595WriteStr功能:向hc595输出字符形参:pin--引脚结构体 data--数据字节组 length--数据字节长度返回值:备注:1、数据输出方向--高位先进,QH=高八位,QG,高七位,QF,高六位,依次下去。
74HC595按键显示程序#include<reg51.h>#include<intrins.h>sbit DS=P1^1;sbit SH_CP=P1^2;sbit ST_CP=P1^3;sbit K1=P1^4;sbit K2=P1^5;sbit K3=P1^6;sbit K4=P1^7;unsigned char code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc6}; unsigned char code wei[]={0xfe,0xfd,0xfb,0xf7};char num1,num2,num3,num4,su,D,C,num_1,num_2;int A;void delay(int x)//延时{int a,b;for(a=0;a<=x;a++)for(b=0;b<=110;b++);}void num_in(char su)//数据输入{int j;for(j=0;j<8;j++){SH_CP=0;DS=su&0x80;su<<=1;SH_CP=1;_nop_();}}void num_out()//数据输出{ST_CP=0;ST_CP=1;_nop_();}void display()//显示子程序{num_in(wei[0]);num_in(duan[num_1]);num_out();delay(3);num_in(wei[1]);num_in(duan[num_2]);num_out();delay(3);num_in(wei[2]);num_in(duan[num3]);num_out();delay(3);num_in(wei[3]);num_in(duan[num4]);num_out();delay(3);}void display_1()//显示子程序1 {num_in(wei[0]);num_in(duan[num1]);num_out();delay(3);num_in(wei[1]);num_in(duan[num2]);num_out();delay(3);num_in(wei[2]);num_in(duan[num3]);num_out();delay(3);num_in(wei[3]);num_in(duan[num4]);num_out();delay(3);}void menu()//菜单程序0~9{switch(D){case 1: {num_1=10; num_2=10; num3=1; num4=11;};break;case 2: {num_1=10; num_2=10; num3=2; num4=11;};break;case 3: {num_1=10; num_2=10; num3=3; num4=11;};break;case 4: {num_1=10; num_2=10; num3=4; num4=11;};break;case 5: {num_1=10; num_2=10; num3=5; num4=11;};break;case 6: {num_1=10; num_2=10; num3=6; num4=11;};break;case 7: {num_1=10; num_2=10; num3=7; num4=11;};break;case 8: {num_1=10; num_2=10; num3=8; num4=11;};break;case 9: {num_1=10; num_2=10; num3=9; num4=11;};break;case 0: {num_1=10; num_2=10; num3=0; num4=11;};break;}}void xiugai() //修改按键{if(K2==0){delay(3);if(num1==10)num1=0;if(K2==0)num1++;while(!K2)display();}}void tuichu(){if(K1==0){delay(3);if(K1==0)A=!A;while(!K1)display();}}void shezhi() //设置按键{while(K1==1){int c,d;for(c=0;c<20;c++){xiugai();display_1();}for(d=0;d<20;d++){xiugai();display();}}}void xianshi()//显示按键{if(K1==0){delay(3);if(K1==0){while(K4==1)display_1();}while(!K1)display();}}unsigned char keyuse()//按键程序{if(K1==0){delay(3);if(K1==0)A=!A;while(!K1)display();}if(K2==0){delay(3);if(K2==0);while(!K2)display();}if(K3==0){delay(3);if(K3==0)shezhi();while(!K3)display();}if(K4==0){delay(3);if(K4==0){if(D==10)D=0;menu();D++;}while(!K4)display();}}void main()//主程序{while(1){keyuse();display();xianshi();}}。
74HC595在单片机上的应用及程序74HC595具有8位串入并出的三态门电路。
高速率:最高55MHz(5V工作电压)宽的工作电压范围:2V -6V每个口的最大电流值(QA-QH):±35mA当单片机的I/O资源比较紧张时,采用595并进行级联是一个很好的选择。
管脚定义:PIN NO symbol name and function15 QA data output1 QB data output2 QC data output3 QD data output4 QE data output5 QF data output6 QG data output7 QH data output8 GND ground9 QH’ serial data outputs10 /SCLR shift register clock input11 SCK shift register clock input12 RCK storage register clock input13 /G output enable input14 SI serial data input16 Vcc positive supply voltage时序图:请参照595的数据手册程序编制:端口定义设置:sbit DATA=P1^5;sbit SHIFT=P1^6;sbit STORAGE=P1^7;1、写595Void write_595(uchar x)//功能:将无符号8位数x,写入到595的shife register{Uchar j;For(j=0;j<8;j++)//循环8次,以便shift register保存8位数据{X=x<<1;//将数据左移一位,最高位数据进入到CY中SHIFT=0;//shift端置0_nop_();_nop_();_nop_();DATA=CY;//将一位数据送入595串口数据端SHIFT=1;//shift端产生一个上升沿,数据就送入到了shift register_nop_();//延时_nop_();_nop_();SHIFT=0;//shift端产生一个下降沿,shift register内容保持不变}}3、595数据的输出/********595输出函数函数*******************/void out_595(void){STORAGE=0;_nop_();_nop_();STORAGE=1;//上升沿shift register 的内容保存到store register _nop_();_nop_();STORAGE=0;//下降沿store register 的内容保持不变}4、只要在主函数中分别调用以上两个函数即可将要显示的数值X 显示出来。
74HC595串行动态数码管显示与X5045操作示例2007-3-7 11:18:00推荐;晶振工作在11.059200M赫兹;单片机为89C51;$NOMOD51;$INCLUDE (AT89X52.H);******************************************************************* ;资源定义RCLK_595 EQU P2.1 ;上升沿时移位寄存器的数据进入数据存储寄存器SRCLK_595 EQU P2.2 ;上升沿时数据寄存器的数据移位SER_595 EQU P2.3 ;串行数据输入端X5045_CS EQU P1.0 ;用于给出X5045的CS信号X5045_SCK EQU P1.1 ;用于给出X5045的SCK信号X5045_SI EQU P1.2 ;用于给出X5045的SI信号X5045_SO EQU P1.3 ;用于给出X5045的SO信号RUN_LED EQU P1.5 ;用于控制指示灯亮灭DISP_START EQU 40H ;40-47H是显示缓冲区,存放8个有效数据DSEG AT 20H;DISP_BUFFER_START DATA 57H ;存放显示缓冲区首地址DISP_P DATA 58H ;存放显示指针,012345 67DISP_CTRL DATA 59H ;存放显示位码LED_DELAY DATA 60H ;LED闪烁的延时计数器LED_DELAY_VALUE EQU 0FFH ;LED闪烁的延时计数器值;******************************************************************* ;******************************************************************* ;中断入口CSEGORG 0000HJMP START;******************************************************************* ;主程序ORG 0033HSTART:MOV R7,#00HDJNZ R7,$ ;延时MOV SP,#65H ;堆栈初始化为60HLCALL SYS_INIT ;系统初始化MOV LED_DELAY,#LED_DELAY_VALUE ;LED闪烁计数器赋初值;MOV DISP_BUFFER_START,#DISP_START ;显示第一组数据MOV DISP_P,#0 ;显示第一个数据MOV DISP_CTRL,#01111111B ;显示最高位;MOV BUFFER_P,#BUFFER_START ;初始化接收缓冲区指针;主循环MAIN_LOOP:DJNZ LED_DELAY,MAIN_LOOP_NEXT2CPL RUN_LED ;指示灯闪烁,表示正常运行MOV LED_DELAY,#LED_DELAY_VALUEMAIN_LOOP_NEXT2:;显示1MOV R1,#8MOV R0,#DISP_STARTMOV A,#01H ;1INIT_DISP_BUFFER1:MOV @R0,AINC R0DJNZ R1,INIT_DISP_BUFFER1SETB TR1DISP_1_1:CALL DISPJNB TF1,DISP_1_1CLR TF1DISP_1_2:CALL DISPJNB TF1,DISP_1_2CLR TF1DISP_1_3:CALL DISPJNB TF1,DISP_1_3CLR TF1DISP_1_4:CALL DISPJNB TF1,DISP_1_4CLR TF1DISP_1_5:CALL DISPJNB TF1,DISP_1_5CLR TF1DISP_1_6:CALL DISPJNB TF1,DISP_1_6CLR TF1CLR TR1;显示2MOV R1,#8MOV R0,#DISP_STARTMOV A,#02H ;1INIT_DISP_BUFFER2:MOV @R0,AINC R0DJNZ R1,INIT_DISP_BUFFER2SETB TR1DISP_2_1:CALL DISPJNB TF1,DISP_2_1CLR TF1DISP_2_2:CALL DISPJNB TF1,DISP_2_2CLR TF1DISP_2_3:CALL DISPJNB TF1,DISP_2_3CLR TF1CLR TR1JMP MAIN_LOOP;******************************************************************* ;******************************************************************* ;系统初始化程序SYS_INIT:MOV R0,#00HSYS_INIT_LOOP:MOV R1,#00HDJNZ R1,$DJNZ R0,SYS_INIT_LOOP ;延时0.13S;内部RAM(30H-5fH)清零MOV R1,#30HMOV A,#0ZERO_LOOP: MOV @R1,AINC R1CJNE R1,#60H,ZERO_LOOP;显示缓冲区初始化MOV R1,#8MOV R0,#DISP_STARTMOV A,#01H ;1INIT_DISP_BUFFER:MOV @R0,AINC R0DJNZ R1,INIT_DISP_BUFFER;禁止各中断MOV IE,#00HMOV IP,#00H;****************************;x5045初始化;x5045引脚输入输出初始化;????LCALL WRITE_06H ;向X5045写入WREN指令(写允许)MOV R0,#00H;1.4S复位LCALL WRITE_01H ;将R0的内容(00H)写入X5045状态寄存器LCALL WRITE_04H ;向X5045写入WRDI指令(写禁止);****************************;****************************;串行口初始化;定时器1产生波特率,方式2;MOV TMOD,#00100000BMOV TMOD,#00010000B ;方式1,16位定时器模式;串口方式3,11位,附加位作为奇偶校验位MOV SCON,#11000000B;SMOD=0ANL PCON,#01111111B;MOV TL1,#0FDH ;波特率9600;MOV TH1,#0FDH ;自动装载值MOV TL1,#LOW(65536 - 65536) ;60MSMOV TH1,#HIGH(65536 - 65536);SETB REN ;允许接收;SETB TR1 ;启动定时器1;*******************************ret;******************************************************************** ******;******************************************************************* ;******************************************************************* ;8位共阴极动态数码管显示扫描子程序DISP: MOV R5,DISP_CTRLCALL WRITE8_595 ;写入位码MOV A,#DISP_START ;显示缓冲区首地址ADD A,DISP_P ;加上缓冲区偏移MOV R0,AMOV A,@R0;转换为显示码MOV DPTR,#TABMOVC A,@A+DPTRMOV R5,ACALL WRITE8_595 ;写入段码;上升沿移位寄存器的数据进入数据存储寄存器CLR RCLK_595NOPSETB RCLK_595MOV A,DISP_CTRLCJNE A,#0FEH,FLASH_DISP;显示到最右那一位则重新循环显示MOV DISP_CTRL,#01111111BMOV DISP_P,#0JMP DISP_RETURNFLASH_DISP:;刷新位码和显示指针RR AMOV DISP_CTRL,AMOV A,DISP_PINC AMOV DISP_P,ADISP_RETURN:RET;******************************************************************* ;******************************************************************* ;向74HC595写入8位数据,低位在前;入口:R5存放8位要写入的数据;注意:但是数据并没有从移位寄存器的数据进入数据存储寄存器,调用它的程序需处理; 初始时引脚状态无影响WRITE8_595:MOV A,R5MOV R5,#8WRITE8_595_LOOP:RRC AMOV SER_595,CCLR SRCLK_595NOPSETB SRCLK_595 ;移位数据,上升沿数据移位DJNZ R5,WRITE8_595_LOOPRET;*******************************************************************TAB: DB 3FH,06H,5BH,4FH,66H ;共阴极数码管显示码 DB 6DH,7DH,07H,7FH,6FH;******************************************************************* ;******************************************************************** ******;******************************************************************** ******;功能:X5045内置看门狗复位;******************************************************************** *******WDT_RST: CLR X5045_CSNOPNOPSETB X5045_CSNOPRET;******************************************************************** ******;******************************************************************** ******;功能:向X5045的SPI接口发送8位数据;入口参数:待发送数据在A中;占用:A,R0,R1;******************************************************************** *******SPI_WRITE8: MOV R7,#08HNEXT0466: RLC AMOV X5045_SI,CNOPNOPSETB X5045_SCKNOPNOPCLR X5045_SCKDJNZ R7,NEXT0466RET;******************************************************************** ******;功能:向X5045写入WREN指令(写允许);******************************************************************** *******WRITE_06H: MOV A,#06HCLR X5045_SCKCLR X5045_CSLCALL SPI_WRITE8SETB X5045_CSRET;******************************************************************** ******;功能:向X5045写入WRDI指令(写禁止);******************************************************************** *******WRITE_04H: MOV A,#04HCLR X5045_SCKCLR X5045_CSLCALL SPI_WRITE8SETB X5045_CSRET;******************************************************************** ******;功能:将R0的内容写入X5045状态寄存器;******************************************************************** *******WRITE_01H: MOV A,#01HCLR X5045_SCKCLR X5045_CSLCALL SPI_WRITE8MOV A,R0LCALL SPI_WRITE8SETB X5045_CSRET;******************************************************************** *******END。
74HC595 芯片的应用实例
在学习51 单片机控制LED 点阵的时候碰到74HC595 芯片,大学学的数电知识忘了差不多了,就在网上搜了一些资料,看到这篇写的不错,把大部分文章转过来,最后面是我的开发板里的程序资料。
下面是正文:
这个夏季学习semiok 同学自己动手焊接了一个LED 显示屏,MCU 用的是ATmega16,实现字幕的滚动显示,由于成本问题,只做了16*64 大小的,也就只能显示4 个中文汉字,这是研究显示驱动的时候找到的关于74HC595 的资料,有时间就把所有制作过程放上来。
正面样子还行
背面惨不忍睹
74HC595 同数据相关的引脚可以分为三类:
SDI:串行数据输入,接单片机的某个I/O 引脚。
Q0~Q7:8 位并行数据输出,可以直接控制8 个LED,或者是七段数码管。
74hc595;文件名:74hc595.c;功能:使用74HC595制作6位静态显示电路,在数码管上分别显示123456。
;硬件:见图8-4*/#include "pic.h"typedef unsigned char uchar;typedef unsigned int uint;__CONFIG(HS&WDTDIS&LVPDIS);//配置文件,设置为HS方式振荡,禁止看门狗,低压编程关闭#define Dat RB1 //定义串行数据输入端#define Clk R B0 //定义时钟端#define RCK RB2 //定义控制端uchar DispBuf[6]={1,2,3,4,5,6};const uchar DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x8 6,0x8E,0xFF};//定义定形码表void SendData(unsigned char SendDat) //传送一个字节的数据数据{ unsigned char i;for(i=0;i<8;i++){ if((SendDat&0x80)==0)Dat=0;elseDat=1;Clk=0;Clk=1;SendDat=SendDat<<1;}}void Disp(){ uchar c;uchar i;RCK=0; //存储寄存器输入禁止for(i=0;i<6;i++){ c=DispBuf[5-i]; //取出待显示字符,先送高位SendData(DispTab[c]); //送出字形码数据}RCK=1; //存储寄存器输入允许}void main(){ TRISB=0; //设置PORTB为输出Disp();for(;;);}。
74hc595串联编程2009-02-16 18:46分类:默认分类字号:大中小做了个51的开发板,功能比较多,但是PIN资源就这么多,对于一些比较简单的功能模块作了串并处理。
板里8个LED灯和X8的led数码管,如果直接连接到单片机上要使用12个管脚,稍作处理,只要3个就行。
先说595的使用,关键是11脚CLK控制为上升沿时,串行数据输入移位寄存器,输入后看12脚STCP,如果是上升沿就并行输出,这里是三个过程,输入允许-》串行输入-》输出允许,这三个过程要处理好先后问题,我编程的时候就是用循环将这三个过程层次化。
/**********************************************************************************************************************LED灯为末级,SEG8选通信号为次级,首级是段码。
*************************************************************************************/#include"reg52.h"#define uchar unsigned char#define uint unsigned intuchar bdata outbyte;sbit bitout outbyte^7;sbit bout = P1^5; //位输出sbit sclk = P1^6; //输入允许同步信号sbit slclk = P1^7; //输出允许信号uchar code segment[]={}; //这里要看是共阴还是共阳uchar code tab[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x800}; //led显示void leddisp(uchar i , uchar location, uchar m){uchar j;outbyte=tab[m];for(j=0;j<8;j++){bout = bitout;sclk=0;sclk=1;sclk=0;outbyte = outbyte<<1;}outbyte=location;for(j=0;j<8;j++){bout = bitout;sclk=0;sclk=1;sclk=0;outbyte = outbyte<<1;}outbyte=segment[i];for(j=0;j<8;j++){bout = bitout;sclk=0;sclk=1;sclk=0;outbyte = outbyte<<1;}slclk = 0;slclk = 0;slclk = 0;}void main(){uchar i=0;uchar location=1;uchar m=1;while(1){leddisp(i,location,m);i++;location = location<<1;if(i == 8){i = 0;location = 1;}}}。