历史上的今天

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

2021年11月12日 | 51单片机实现两片联级74HC595依次点亮LED后依次熄灭

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

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

二、编写程序


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

---- @Project: LED-74HC595

---- @File: main.c

---- @Edit: ZHQ

---- @Version: V1.0

---- @CreationTime: 20200525

---- @ModifiedTime: 20200525

---- @Description: 第1个至第8个LED灯,先依次逐个亮,再依次逐个灭。第9至第16个LED灯一直灭。

---- 单片机:AT89C52

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

#include "reg52.h"

/*——————宏定义——————*/

#define FOSC 11059200L

#define T1MS (65536-FOSC/12/1000)   /*1ms timer calculation method in 12Tmode*/

 

#define const_time_level_01_08  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_01_08 = 0; /*第1个至第8个LED跑马灯的步骤变量*/

unsigned int  uiTimeCnt_01_08 = 0; /*第1个至第8个LED跑马灯的统计定时中断次数的延时计数器*/

 

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 初始化单片机

**/

void Init(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_01_08(void)

{

switch(ucLedStep_01_08)

{

case 0:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED1 = 1;

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

ucLedStep_01_08 = 1;

}

break;

case 1:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED2 = 1;

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

ucLedStep_01_08 = 2;

}

break;

case 2:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED3 = 1;

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

ucLedStep_01_08 = 3;

}

break;

case 3:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED4 = 1;

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

ucLedStep_01_08 = 4;

}

break;

case 4:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED5 = 1;

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

ucLedStep_01_08 = 5;

}

break;

case 5:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED6 = 1;

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

ucLedStep_01_08 = 6;

}

break;

case 6:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED7 = 1;

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

ucLedStep_01_08 = 7;

}

break;

case 7:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED8 = 1;

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

ucLedStep_01_08 = 8;

}

break;

case 8:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED8 = 0;

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

ucLedStep_01_08 = 9;

}

break;

case 9:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED7 = 0;

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

ucLedStep_01_08 = 10;

}

break;

case 10:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED6 = 0;

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

ucLedStep_01_08 = 11;

}

break;

case 11:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED5 = 0;

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

ucLedStep_01_08 = 12;

}

break;

case 12:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED4 = 0;

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

ucLedStep_01_08 = 13;

}

break;

case 13:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED3 = 0;

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

ucLedStep_01_08 = 14;

}

break;

case 14:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED2 = 0;

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

ucLedStep_01_08 = 15;

}

break;

case 15:

if(uiTimeCnt_01_08 >= const_time_level_01_08)

{

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

ucLED1 = 0;

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

ucLedStep_01_08 = 0;

}

break;

}

}

/**

* @brief  定时器0中断函数

* @param  无

* @retval 无

**/

void ISR_T0(void) interrupt 1

{

TF0 = 0;  /*清除中断标志*/

  TR0 = 0; /*关中断*/

if(uiTimeCnt_01_08 < 0xffff) /*设定这个条件,防止uiTimeCnt超范围。*/

{

uiTimeCnt_01_08 ++;

}

TL0 = T1MS;                     /*initial timer0 low byte*/

[1] [2]
关键字:51单片机  74HC595  点亮LED 引用地址:51单片机实现两片联级74HC595依次点亮LED后依次熄灭

上一篇:51单片机实现两片联级74HC595依次点亮且每次只能点亮一个
下一篇:51单片机实现两片联级74HC595驱动16个LED灯

推荐阅读

今年5月31日,58岁的Jean-Marc Chery被任命为意法半导体总裁兼CEO,他是意法半导体管理委员会唯一成员,并担任其他执行委员会主席。作为一名在意法半导体已经有超过30年工龄的老将,他曾担任过多个重要职位,例如CTO ,COO,2017年7月起担任意法半导体副CEO,他非常谙熟意法半导体的经营,在全球经济形势变幻莫测的今天,他将领导意法半导体走一条什么样的...
  作为一种通用测试测量仪器,示波器在通信、工业自动化、教育、计算机、国防、航空航天等领域的应用中,发挥着重要的作用。随着系统的信号时钟速度越来越快,各行业应用对示波器的要求也在不断发展。除了在性能上要求更高的带宽、更快的采样率和更深存储长度之外,从应用角度来看,示波器正被越来越频繁地应用于测试复杂信号,包括产品研发、模拟和数字...
我们已对华为畅享Z 5G进行了分析,此次价值观我们将对元器件数量及其成本进行分析。 器件分析说明: 在开始分析之前,需要对元器件分析的一些概念和问题进行说明。我们是通过市场官方公开渠道购买机器,每个产品同一个元器件可能会有不一样的供应商,所以我们以购买拆解的机器为准...
一、使用proteus绘制简单的电路图,用于后续仿真二、编写程序/********************************************************************************************************************---- @Project: Independent-KEY---- @File: main.c---- @Edit: ZHQ---- @Version: V1.0---- @CreationTime: 20200508---- @ModifiedTime: 20200508---- @Description:...

史海拾趣

问答坊 | AI 解惑

HT1380串行时钟芯片

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

查看全部问答∨

Introduction to NI VeriStand

Introduction to NI VeriStand…

查看全部问答∨

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

请大家看下下面打问号几行代码,抛开其功能不说,真的是奇怪了,我都看了又看,头都大了,就是不知道为什么,请朋友们指点下 #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 要求:至少五年以上相关工作经验,英文流利。…

查看全部问答∨

批评英蓓特,一个细节反映出的不认真

还是说说今天参加安富利的“ARM研讨会”,参观展台时,逛到了英蓓特(EMBEST)那里。大家可能知道,这家公司就是专门围绕ARM生存的,有很多ARM开发板。我在看到英蓓特展台的易拉宝时,楞了一下,原来上面罗列的产品线时,赫然有“Luminary系列”。 ...…

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

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

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

更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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