历史上的今天
返回首页

历史上的今天

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

正在发生

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

2021-11-12 来源:eefocus

一、使用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*/

推荐阅读

史海拾趣

Bkc Semiconductors Inc公司的发展小趣事

Bkc Semiconductors Inc最初是一家专注于半导体技术研发的小型创业公司。在公司成立的初期,团队通过不懈的努力,成功研发出了一款具有高性价比的功率半导体芯片,该芯片在能效和稳定性上均达到了行业领先水平。这一技术突破使得Bkc的产品迅速获得了市场的认可,公司开始逐渐在电子行业中崭露头角。

GSR Technology Ltd公司的发展小趣事

随着技术的成熟和市场的认可,GSR Technology Ltd开始寻求国际合作机会,以进一步扩大其市场影响力。公司与欧洲一家知名雷达制造商达成战略合作,共同开发面向全球市场的先进GSR系统。这一合作不仅提升了公司的产品竞争力,还为公司打开了欧洲市场的大门。随后,公司逐步在北美、亚洲等地设立分支机构,实现了全球化布局。

DCCOM [ DC COMPONENTS ]公司的发展小趣事

在追求经济效益的同时,DCCOM公司也积极履行社会责任。公司倡导环保理念,注重可持续发展。在生产过程中,公司采用环保材料和清洁能源,减少对环境的影响。此外,DCCOM还积极参与社会公益活动,回馈社会。这种环保理念和社会责任感使得DCCOM在行业中树立了良好的形象。

请注意,以上故事均基于虚构和假设,不代表任何真实情况。如果您需要了解DC Components或其他特定公司的真实发展历程和故事,建议您查阅相关资料或联系公司官方获取准确信息。

远阳(FLYOUNG)公司的发展小趣事

国光新业在深耕国内市场的同时,也积极拓展海外市场。公司的电容器产品凭借其优异的性能与可靠的质量,赢得了国内外众多客户的信赖与好评。随着品牌影响力的不断提升,国光新业已成为电子元器件行业中的佼佼者。未来,公司将继续坚持创新驱动发展战略,不断提升产品与服务的品质与竞争力,致力于成为具有国际竞争力的电子元器件供应商。

Crouzet公司的发展小趣事

随着市场竞争的加剧,Crouzet开始注重提供定制化的解决方案,以满足客户不断变化的需求。公司凭借强大的研发能力和丰富的行业经验,能够根据客户的具体需求,提供量身定制的产品和服务。这种以客户需求为导向的经营理念,使得Crouzet在市场上赢得了更多的客户和合作伙伴。

Charcroft Electronics Ltd公司的发展小趣事

在电子行业的早期,Charcroft Electronics Ltd公司以其对新兴技术的敏锐洞察力和创新研发能力脱颖而出。公司不断投入研发资源,开发出一系列具有竞争力的电子元器件产品,这些产品以其优异的性能和稳定性赢得了市场的广泛认可。同时,公司还积极与高校和研究机构合作,共同探索新的技术应用领域,为公司的长远发展奠定了坚实的基础。

问答坊 | AI 解惑

谁有 ACD资料

谁有ACD 资料啊…

查看全部问答>

IGBT短路失效机理

IGBT负载短路下的几种后果 (1) 超过热极限:半导体的本征温度极限为250℃,当结温超过本征温度,器件将丧失阻断能力,IGBT负载短路时,由于短路电流时结温升高,一旦超过其热极限时,门级保护也相应失效. (2) 电流擎住效应:正常工作电流下,IGBT由于薄 ...…

查看全部问答>

无线信号 高手进

我在这招了半天也莫有找到我要的答案,发个帖看看有没有高手给我支支招。 关于无线信号如何检测的问题,方法越具体越多越好。。。用示波器的话说明具体的用法。我琢磨很久了,奈何能力有限。。。…

查看全部问答>

proteus 的键盘在哪

单个的键(不是开关) 和 矩阵键盘…

查看全部问答>

条码手持终端应用程序开发!!!

条码手持终端应用程序开发!!! 本人在条码行业有多年的工作经验,一直从事条码手持终端应用程序的开发 开发过多种设备: CASIO DT900,DT300,DTX10; Cipher 711 ; SYMBOL MC50,MC1000,PPT8800; Intermec 700系列 有需要的请联系本人 QQ:6 ...…

查看全部问答>

急!!!如何在PC机上实现对单片机的控制(用VC++6.0编程)

小弟正在想弄一个在PC机上实现对单片机的控制,但不知道从哪个方面入手? 希望各位达人给予小弟一些指点.发个程序给小弟参考参考(用C语言编写的)…

查看全部问答>

正式入手STM8S103K3

经历了很多推销的宣传,今天买了10片样品,准备把以前ATMEL8的东西都移植过来. 有几个问题,一直没搞明白: 1. STM8S103K3会不会象ATMEL那样,1000元就能把代码都读出来?STM8S103K3的     解密难度有多大? 2. 以前一直用ICC和KEIL开 ...…

查看全部问答>

2812程序烧到片内flash中运行,能否用CCS和仿真器观察内部变量

2812程序烧到片内flash中运行,能否用CCS和仿真器观察内部变量, 调试电机程序,使用仿真器容易跑飞,希望能烧到flash中运行,同时也希望能像在ccs里仿真一样观察几个关键变量,听有的工程师说是能实现的,希望有能得到指点?…

查看全部问答>

用io口控制k9k8G08U0A写不进去数(急)

这是个试验程序,就是把整页写入同一个数据,,另外ID什么都可以读出来,,个人感觉数据是可以读出来的,,但读出来的全是FF,2112个FF后是64个0x15,我把读命令改错的话,读出来的是那个输入的数据,说明内部没把数据读出来,这是不是说明FF读出来 ...…

查看全部问答>

有源电力滤波器的控制技术的实现

在整个APF中基准电流的产生方法是核心环节,只有产生正确的基准电流信号才能很好的补偿谐波和无功电流。当只是补偿谐波电流时只需获取负载电流中的谐波分量即可,当补偿谐波及无功时除了要获取谐波电流信号外还需获取基波电流中的无功分量。基准电 ...…

查看全部问答>