首页 > 编程知识 正文

74hc165级联扩展电路,74hc595驱动16个LED灯亮灭

时间:2023-05-06 10:59:53 阅读:214444 作者:1106

一、使用proteus绘制简单的电路图,用于后续仿真

 

二、编写程序

/********************************************************************************************************************----@Project:LED-74HC595----@File:main.c----@Edit:ZHQ----@Version:V1.0----@CreationTime:20200515----@ModifiedTime:20200515----@Description:两片联级的74HC595驱动的16个LED灯交叉闪烁。比如,先是第1,3,5,7,9,11,13,15八个灯亮,其它的灯都灭。然后再反过来,原来亮的就灭,原来灭的就亮。交替闪烁。----单片机:AT89C52********************************************************************************************************************/#include "reg52.h"/*——————宏定义——————*/#define FOSC 11059200L#define T1MS (65536-FOSC/12/1000) /*1ms timer calculation method in 12Tmode*/#define const_time_level 400 /*——————变量函数定义及声明——————*//*定义74HC595*/sbit Hc595_Sh = P2^3;sbit Hc595_St = P2^4;sbit Hc595_Ds = P2^5;unsigned char ucLedStep = 0; /*步骤变量*/unsigned int uiTimeCnt = 0; /*统计定时中断次数的延时计数器*//*** @brief 定时器0初始化函数* @param 无* @retval 初始化T0**/void Init_T0(void){TMOD = 0x01; /*set timer0 as mode1 (16-bit)*/TL0 = T1MS; /*initial timer0 low byte*/TH0 = T1MS >> 8; /*initial timer0 high byte*/}/*** @brief 外围初始化函数* @param 无* @retval 初始化外围**/void Init_Peripheral(void){ET0 = 1;/*允许定时中断*/TR0 = 1;/*启动定时中断*/EA = 1;/*开总中断*/}/*** @brief 初始化函数* @param 无* @retval 初始化单片机**/voidInit(void){Init_T0();}/*** @brief 延时函数* @param 无* @retval 无**/void Delay_Long(unsigned int uiDelayLong){ unsigned int i; unsigned int j; for(i=0;i<uiDelayLong;i++) { for(j=0;j<500;j++) /*内嵌循环的空指令数量*/ { ; /*一个分号相当于执行一条空语句*/ } }}/*** @brief 延时函数* @param 无* @retval 无**/void Delay_Short(unsigned int uiDelayShort){ unsigned int i; for(i=0;i<uiDelayShort;i++) { ; /*一个分号相当于执行一条空语句*/ }}/*** @brief 595驱动函数* @param 无* @retval * 两个联级74HC595的工作过程:* 每个74HC595内部都有一个8位的寄存器,两个联级起来就有两个寄存器。ST引脚就相当于一个刷新* 信号引脚,当ST引脚产生一个上升沿信号时,就会把寄存器的数值输出到74HC595的输出引脚并且锁存起来,* DS是数据引脚,SH是把新数据送入寄存器的时钟信号。也就是说,SH引脚负责把数据送入到寄存器里,ST引脚* 负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。**/void HC595_Drive(unsigned char ucLedStatusTemp16_09, unsigned char ucLedStatusTemp08_01){unsigned char i;unsigned char ucTempData;Hc595_Sh = 0;Hc595_St = 0;ucTempData = ucLedStatusTemp16_09;/*先送高8位*/for(i = 0; i < 8; i ++){if(ucTempData >= 0x80){Hc595_Ds = 1;}else{Hc595_Ds = 0;}Hc595_Sh = 0;/*SH引脚的上升沿把数据送入寄存器*/Delay_Short(15); Hc595_Sh = 1;Delay_Short(15); ucTempData = ucTempData <<1;}ucTempData = ucLedStatusTemp08_01;/*再先送低8位*/for(i = 0; i < 8; i ++){if(ucTempData >= 0x80){Hc595_Ds = 1;}else{Hc595_Ds = 0;}Hc595_Sh = 0;/*SH引脚的上升沿把数据送入寄存器*/Delay_Short(15); Hc595_Sh = 1;Delay_Short(15); ucTempData = ucTempData <<1;}Hc595_St = 0;/*ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来*/Delay_Short(15);Hc595_St = 1;Delay_Short(15);Hc595_Sh = 0;/*拉低,抗干扰就增强*/Hc595_St = 0;Hc595_Ds = 0;}/*** @brief LED闪烁函数* @param 无* @retval 无**/void LED_Flicker(void){switch(ucLedStep){case 0:if(uiTimeCnt >= const_time_level){uiTimeCnt = 0;/*时间计数器清零*/HC595_Drive(0x55, 0x55);ucLedStep = 1;}break;case 1:if(uiTimeCnt >= const_time_level){uiTimeCnt = 0;/*时间计数器清零*/HC595_Drive(0xaa, 0xaa);ucLedStep = 0;}break;}}/*** @brief 定时器0中断函数* @param 无* @retval 无**/void ISR_T0(void)interrupt 1{TF0 = 0; /*清除中断标志*/ TR0 = 0; /*关中断*/if(uiTimeCnt < 0xffff)/*设定这个条件,防止uiTimeCnt超范围。*/{uiTimeCnt ++;}TL0 = T1MS; /*initial timer0 low byte*/TH0 = T1MS >> 8; /*initial timer0 high byte*/ TR0 = 1; /*开中断*/}/*——————主函数——————*//*** @brief 主函数* @param 无* @retval 实现LED灯闪烁**/void main(){/*单片机初始化*/Init();/*延时,延时时间一般是0.3秒到2秒之间,等待外围芯片和模块上电稳定*/Delay_Long(100);/*单片机外围初始化*/Init_Peripheral();while(1){/*按键服务函数*/LED_Flicker();}}

三、仿真实现

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。