历史上的今天
返回首页

历史上的今天

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

正在发生

2021年11月10日 | 51单片机实现两片联级74HC595多任务并行处理两路跑马灯

2021-11-10 来源:eefocus

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

二、编写程序


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

---- @Project: LED-74HC595

---- @File: main.c

---- @Edit: ZHQ

---- @Version: V1.0

---- @CreationTime: 20200528

---- @ModifiedTime: 20200528

---- @Description: 第一路独立运行的任务是:第1个至第8个LED灯,先依次逐个亮,再依次逐个灭。

---- 第二路独立运行的任务是:第9个至第16个LED灯,依次逐个亮灯并且每次只能亮一个灯。第1至第8个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  

#define const_time_level_09_16  600   

 

 

/*——————变量函数定义及声明——————*/

/*定义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 ucLedStep_09_16 = 0; /*第9个至第16个LED跑马灯的步骤变量*/

unsigned int  uiTimeCnt_09_16 = 0; /*第9个至第16个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;

推荐阅读

史海拾趣

Enable Semiconductor Corp公司的发展小趣事

在半导体产业链中,Enable Semiconductor Corp公司注重与上下游企业的合作。公司与多家芯片设计公司、封装测试企业建立了紧密的合作关系,共同开发新产品、新技术。这种合作模式不仅降低了公司的研发成本,也加快了产品上市的速度。同时,通过与合作伙伴的资源共享和优势互补,Enable Semiconductor Corp公司在市场上形成了强大的竞争力。

Elektron公司的发展小趣事

随着技术的不断进步和市场需求的不断变化,Elektron公司不断进行技术创新和产品升级。公司成功开发出适用于船上使用的单点和多点焊接整流器以及弧光灯的电影整流器等产品,进一步扩大了市场份额。同时,Elektron还注重产品质量和性能的提升,通过引进先进的生产设备和工艺,不断提高产品的可靠性和耐用性。

Bellin Dynamic Systems公司的发展小趣事

在追求经济效益的同时,Bellin Dynamic Systems也积极履行社会责任,致力于可持续发展。公司注重环保和节能技术的研发和应用,努力降低生产过程中的能耗和排放。此外,公司还积极参与社会公益事业,通过捐款、资助等方式回馈社会。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

以上是我为您模拟构建的关于Bellin Dynamic Systems在电子行业中发展起来的几个可能故事。请注意,这些故事是基于一般性的行业趋势和公司发展路径构建的,并非真实发生的事件。如果您需要更具体的信息,建议直接查阅Bellin Dynamic Systems的官方资料或相关新闻报道。

Baneasa SA公司的发展小趣事

在快速发展的同时,Baneasa SA始终注重技术创新和可持续发展。公司不断投入研发资金,开发新的电子元器件产品和技术,以满足市场的不断变化和客户的需求。同时,公司也注重环保和节能减排,采用环保材料和节能技术,致力于实现可持续发展。

这些故事虽然基于假设和虚构,但尽量遵循了电子行业企业发展的一般规律和趋势。它们旨在展示Baneasa SA在电子行业中的可能发展历程和成就,而不涉及任何主观评价或褒贬。请注意,这些故事并非真实事件,仅用于说明公司在电子行业发展的可能性和方向。

BELLING LEE公司的发展小趣事

随着电子市场的不断发展和消费者需求的多样化,BELLING LEE公司意识到单一的产品线已无法满足市场需求。于是,公司开始积极拓展产品线,推出了包括智能手机、平板电脑、智能家居设备等一系列新产品。这些新产品不仅满足了消费者的多样化需求,也进一步巩固了公司在电子市场的领先地位。

Adafruit公司的发展小趣事

面对不断变化的市场环境和日益激烈的竞争压力,BELLING LEE公司始终保持着创新的精神和敏锐的市场洞察力。公司不断推出具有创新性和前瞻性的新产品和技术,引领着电子行业的发展趋势。同时,公司还加强了对新兴技术的研究和投入,为未来市场的竞争做好了充分准备。


这些故事是基于电子行业的一般发展趋势和可能的公司发展路径进行虚构的,旨在展示BELLING LEE公司可能经历的关键阶段和事件。请注意,这些故事并非基于实际事实,也不代表BELLING LEE公司的真实发展历程。在实际写作中,如果需要描述真实公司的发展故事,应基于可靠的历史资料和公开信息进行编写。

问答坊 | AI 解惑

大家有没有“温室智能控制系统”毕业设计

大家有没有“温室智能控制系统”毕业设计 共享一下 控制量(温度,湿度,光照,co2控制,土壤,水分)…

查看全部问答>

PROTEL 99se 中走线的问题

大家好:我的protel 99se中画pcb走线时可以走15度,30度等等好像是任意角度,我不想这样改怎么设置? 正常的是可以走45度,90度,135度 谢谢大家哦!…

查看全部问答>

关于端口复用的问题(ds1302和1602)

想用ds1302和1602做一个实时时钟,但ds1302的3个口接在P1,而1602的8位数据输入也用的是P1,请问能这样能做到吗?谢谢…

查看全部问答>

简单问题:如何获取进程空间虚拟地址的实际的物理地址?

反之,如果把一个物理地址映射到进程空间虚拟地址?不是MMU那个虚拟地址…

查看全部问答>

有电力项目方面经验的朋友请进!

哪位有电力方面课题或是中小型的项目,可以谈谈想法,现成的项目也可以,我公司需要购买或者开发。希望我们能合作。我的QQ号31721739 …

查看全部问答>

高分求高手相助, 无法连通电信WAP网关

{                 }else                 {                         ConnMgrSetCon…

查看全部问答>

各位同仁,我还要继续下去吗

本人是做单片机工作的,08年金融危机被公司CUT了…

查看全部问答>

关于系统初始化

系统初始化时,怎么根据实际使用振荡器?如内部振荡器1和2。…

查看全部问答>

Verilog+HDL数字设计与综合(第二版)

设计前端的设计很不错的一本书…

查看全部问答>

你对LED恒流芯片了解多少?三代非隔离LED恒流芯片介绍

第一代LED恒流芯片:此类芯片主要的技术特点是基于固定频率的PWM芯片(如UC384X等),通过降低电感纹波电流,固定电感峰值电流来实现恒流。但由于开关频率固定,为避免次谐振荡,它的最大占空比只能用到50%,其应用范围就很受限了;再者由于电感纹 ...…

查看全部问答>