历史上的今天

今天是:2024年11月12日(星期二)

2021年11月12日 | 51单片机实现两片联级74HC595驱动16个LED灯

发布者:GoldenHarmony 来源: eefocus关键字:51单片机  74HC595  LED灯 手机看文章 扫描二维码
随时随地手机看文章

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

二、编写程序


/********************************************************************************************************************

----@Project:LED-74HC595

----@File:main.c

----@Edit:ZHQ

----@Version:V1.0

----@CreationTime:20200524

----@ModifiedTime:20200524

----@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 ucLED1 = 0;   /*代表16个灯的亮灭状态,0代表灭,1代表亮*/

unsigned char ucLED2 = 0;

unsigned char ucLED3 = 0;

unsigned char ucLED4 = 0;

unsigned char ucLED5 = 0;

unsigned char ucLED6 = 0;

unsigned char ucLED7 = 0;

unsigned char ucLED8 = 0;

unsigned char ucLED9 = 0;

unsigned char ucLED10 = 0;

unsigned char ucLED11 = 0;

unsigned char ucLED12 = 0;

unsigned char ucLED13 = 0;

unsigned char ucLED14 = 0;

unsigned char ucLED15 = 0;

unsigned char ucLED16 = 0;

 

 

unsigned char ucLed_update = 0;  /*刷新变量。每次更改LED灯的状态都要更新一次。*/

 

unsigned char ucLedStep = 0; /*步骤变量*/

unsigned int  uiTimeCnt = 0; /*统计定时中断次数的延时计数器*/

 

unsigned char ucLedStatus16_09 = 0;   /*代表底层74HC595输出状态的中间变量*/

unsigned char ucLedStatus08_01 = 0;   /*代表底层74HC595输出状态的中间变量*/

 

/**

* @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   {

      for(j=0;j<500;j++)  /*内嵌循环的空指令数量*/

          {

             ; /*一个分号相当于执行一条空语句*/

          }

   }

}

/**

* @brief  延时函数

* @param  无

* @retval 无

**/

void Delay_Short(unsigned int uiDelayShort)

{

   unsigned int i;

   for(i=0;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 

* 把74HC595驱动程序翻译成类似单片机IO口直接驱动方式的过程。

* 每次更新LED输出,记得都要把ucLed_update置1表示更新。

**/

void LED_Update()

{

if(ucLed_update == 1)

{

ucLed_update = 0;/*及时清零,让它产生只更新一次的效果,避免一直更新。*/

if(ucLED1 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x01;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0xfe;

}

if(ucLED2 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x02;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0xfd;

}

if(ucLED3 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x04;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0xfb;

}

if(ucLED4 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x08;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0xf7;

}

if(ucLED5 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x10;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0xef;

}

if(ucLED6 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x20;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0xdf;

}

if(ucLED7 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x40;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0xbf;

}

if(ucLED8 == 1)

{

ucLedStatus08_01 = ucLedStatus08_01 | 0x80;

}

else

{

ucLedStatus08_01 = ucLedStatus08_01 & 0x7f;

}

if(ucLED9 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x01;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0xfe;

}

if(ucLED10 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x02;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0xfd;

}

if(ucLED11 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x04;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0xfb;

}

if(ucLED12 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x08;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0xf7;

}

if(ucLED13 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x10;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0xef;

}

if(ucLED14 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x20;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0xdf;

}

if(ucLED15 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x40;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0xbf;

}

if(ucLED16 == 1)

{

ucLedStatus16_09 = ucLedStatus16_09 | 0x80;

}

else

{

ucLedStatus16_09 = ucLedStatus16_09 & 0x7f;

}

HC595_Drive(ucLedStatus16_09, ucLedStatus08_01);

}

}

/**

* @brief  LED闪烁函数

* @param  无

* @retval 无

**/

void LED_Flicker(void)

{

switch(ucLedStep)

{

case 0:

if(uiTimeCnt >= const_time_level)

{

uiTimeCnt = 0;/*时间计数器清零*/

ucLED1 = 1;/*每个变量都代表一个LED灯的状态*/

ucLED2 = 0;

ucLED3 = 1;

ucLED4 = 0;

ucLED5 = 1;

ucLED6 = 0;

ucLED7 = 1;

ucLED8 = 0;

ucLED9 = 1;

ucLED10 = 0;

ucLED11 = 1;

ucLED12 = 0;

ucLED13 = 1;

ucLED14 = 0;

ucLED15 = 1;

ucLED16 = 0;

ucLed_update = 1;  /*更新显示*/

ucLedStep = 1;

}

break;

case 1:

if(uiTimeCnt >= const_time_level)

{

uiTimeCnt = 0;/*时间计数器清零*/

ucLED1 = 0;/*每个变量都代表一个LED灯的状态*/

ucLED2 = 1;

ucLED3 = 0;

ucLED4 = 1;

ucLED5 = 0;

ucLED6 = 1;

ucLED7 = 0;

ucLED8 = 1;

ucLED9 = 0;

ucLED10 = 1;

ucLED11 = 0;

ucLED12 = 1;

ucLED13 = 0;

ucLED14 = 1;

ucLED15 = 0;

ucLED16 = 1;

ucLed_update = 1;  /*更新显示*/

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();

/*LED更新函数*/

LED_Update(); 

}

}

 

三、仿真实现


关键字:51单片机  74HC595  LED灯 引用地址:51单片机实现两片联级74HC595驱动16个LED灯

上一篇:51单片机实现两片联级74HC595依次点亮LED后依次熄灭
下一篇:51单片机实现矩阵键盘的组合按键触发

推荐阅读

《日经》亚洲科技业最值得关注的女性,唯一入榜台湾人!全球硅晶圆第3大供应商、台积电关键上游,环球晶圆营收六年间暴增95倍,连11季成长。但今年股价大起大落,在半导体景气反转、市场质疑供过于求之际,董事长徐秀兰为何敢于逆势扩厂,让竞业赞赏「这就是徐秀兰厉害的地方」? 环球晶圆董事长徐秀兰接受《天下》专访这天,一见到去年曾访问过她的记者,...
简单扼要void IWDG_Init(void)//初始化{  IWDG->KR = 0xcc;//启动IWDG  IWDG->KR = 0x55;//解除PR及RLR的写保护  IWDG->RLR = 0xff;//看门狗计数器重载值  IWDG->PR = 0x06;//分频系数256 1724.63ms  IWDG->KR = 0xaa;//刷新IDDG,避免产生看门狗复位,同时恢复PR及RLR的写保护 } void IWDG_Feed(void)//喂狗{ IWDG->KR = 0xaa;}
10月末,IC载板大厂欣兴山莺厂区发生了火灾。当时业界评估,山莺厂区是欣兴主要芯片尺寸覆晶封装(FC CSP)载板的生产基地,客户群包括高通、联发科与海思(华为),目前载板持续供不应求,欣兴火灾恐造成市场供给更加吃紧。据digitimes最新消息,业界传出,自欣兴火灾后,IC载板新一轮的涨价潮似乎正式启动,涨价幅度约在20%~40%之间,台系载板三雄欣兴...
本文提到的有以下内容:时钟系统与总线矩阵SysTick系统定时器RTC实时时钟看门狗定时器通用定时器 一、时钟系统与总线矩阵  stm32F4的时钟树如下图所示:  在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。HSI是高速内部时钟,RC振荡器,频率为8MHz。HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。LSI是低速...

史海拾趣

问答坊 | AI 解惑

HT1380串行时钟芯片

HT1380串行时钟芯片一般来说,HT系列的芯片在串行口的应用一直以来就是很好的在单片机 这个领域,串行时钟一直占着很重要的位置…

查看全部问答∨

Introduction to NI VeriStand

Introduction to NI VeriStand…

查看全部问答∨

工程师们看过来——电气测量时,聪明人所做的10件糊涂事

本人搜集到的一篇很好的文章,因此转载给各位大虾,希望对工程师们有所帮助: 何靠与电打交道来谋生的人很快都会对任何“带电”的物体生出理性的敬意,哪怕是“带电”的机会很小。然而,需要按时完成一项工作或者使某个关键设备恢复联机的紧迫压力 ...…

查看全部问答∨

奇怪了,请大家看下做标记的那几行代码

请大家看下下面打问号几行代码,抛开其功能不说,真的是奇怪了,我都看了又看,头都大了,就是不知道为什么,请朋友们指点下 #include<reg52.h>                     &nbs ...…

查看全部问答∨

evc托盘编程

使用evc4.0编写一个系统托盘,就是我的程序起来之后,不显示对话框,自动出现一个图标到右下角,通过双机图标,可以弹出对话框。 右键单击右下角图标,可以弹出一个菜单。 不知道如何实现这些功能,请兄弟姐妹们帮个忙!…

查看全部问答∨

请高手帮忙~~~在EVC下的2个函数没定义.

error C2065: \'GetRunningObjectTable\' : undeclared identifier error C2065: \'CreateItemMoniker\' : undeclared identifier 我用的是EVC 4.0+SP4…

查看全部问答∨

si4010有没有人用过,求探讨

si4010有没有人用过,求探讨,开发软件,调试软件,烧录工具等等…

查看全部问答∨

STM32的驱动库好用吗?效率高吗?优化的吗?准备上STM32

    N多年没买过开发板了,也没用过仿真器了。都是用软件编译调试好,直接ISP,然后通过串口命令开启调试信息的输出。    昨天买了块STM32F103全功能型开发板,他们的办事效率真低(深圳到广州通常当 ...…

查看全部问答∨

求IAR Embedded Workbench for MCS-51 完整版

各位高手,小弟求IAR Embedded Workbench for MCS-51完整版,有哪位高人有,能否分享一下。我的邮箱jinghongchen@126.com…

查看全部问答∨

猎头招聘

世界500强招聘压力传感器SAE,如有兴趣可发简历至:aerie.song@seek-jobs.com.cn 要求:至少五年以上相关工作经验,英文流利。…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved