历史上的今天
返回首页

历史上的今天

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

正在发生

2021年11月10日 | 51单片机实现在主函数while循环中驱动数码管的动态扫描程序

2021-11-10 来源:eefocus

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

二、编写程序


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

---- @Project: LED-74HC595

---- @File: main.c

---- @Edit: ZHQ

---- @Version: V1.0

---- @CreationTime: 20200604

---- @ModifiedTime: 20200604

---- @Description: 用两片74HC595动态驱动八位共阴数码管。

---- 开机后显示  8765.4321  的内容,注意,其中有一个小数点。

---- 单片机:AT89C52

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

#include "reg52.h"

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

#define FOSC 11059200L

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

 

 

#define const_voice_short 40 /*蜂鸣器短叫的持续时间*/

 

 

#define const_key_time1 20 /*按键去抖动延时的时间*/

 

#define const_sensor 20 /*开关感应器去抖动延时的时间*/

 

#define const_1s 500 /*开关感应器去抖动延时的时间*/

 

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

/*定义数码管的74HC595*/

sbit Dig_Hc595_Sh = P2^0;

sbit Dig_Hc595_St = P2^1;

sbit Dig_Hc595_Ds = P2^2;

 

/*定义蜂鸣器*/

sbit Beep = P2^7;

 

/*作为中途暂停指示灯 亮的时候表示中途暂停*/

sbit LED = P3^5;

 

 

unsigned char ucDigShow8;   /*第8位数码管要显示的内容*/

unsigned char ucDigShow7;   /*第7位数码管要显示的内容*/

unsigned char ucDigShow6;   /*第6位数码管要显示的内容*/

unsigned char ucDigShow5;   /*第5位数码管要显示的内容*/

unsigned char ucDigShow4;   /*第4位数码管要显示的内容*/

unsigned char ucDigShow3;   /*第3位数码管要显示的内容*/

unsigned char ucDigShow2;   /*第2位数码管要显示的内容*/

unsigned char ucDigShow1;   /*第1位数码管要显示的内容*/

 

unsigned char ucDigDot8;   /*数码管8的小数点是否显示的标志*/

unsigned char ucDigDot7;   /*数码管7的小数点是否显示的标志*/

unsigned char ucDigDot6;   /*数码管6的小数点是否显示的标志*/

unsigned char ucDigDot5;   /*数码管5的小数点是否显示的标志*/

unsigned char ucDigDot4;   /*数码管4的小数点是否显示的标志*/

unsigned char ucDigDot3;   /*数码管3的小数点是否显示的标志*/

unsigned char ucDigDot2;   /*数码管2的小数点是否显示的标志*/

unsigned char ucDigDot1;   /*数码管1的小数点是否显示的标志*/

 

unsigned char ucDigShowTemp = 0; /*临时中间变量*/

unsigned char ucDisplayDriveStep = 1; /*动态扫描数码管的步骤变量*/

 

unsigned char ucDisplayUpdate = 1; /*更新显示标志*/

 

unsigned int uiVoiceCnt = 0; /*蜂鸣器鸣叫的持续时间计数器*/

 

void Dig_Hc595_Drive(unsigned char, unsigned char);

 

/*根据原理图得出的共阴数码管字模表*/

code unsigned char Dig_Table[] =

{

0x3f,  /*0       序号0*/

0x06,  /*1       序号1*/

0x5b,  /*2       序号2*/

0x4f,  /*3       序号3*/

0x66,  /*4       序号4*/

0x6d,  /*5       序号5*/

0x7d,  /*6       序号6*/

0x07,  /*7       序号7*/

0x7f,  /*8       序号8*/

0x6f,  /*9       序号9*/

0x00,  /*不显示  序号10*/

};

 

 

/**

* @brief  外围初始化函数

* @param  无

* @retval 初始化外围

* 让数码管显示的内容转移到以下几个变量接口上,方便以后编写更上一层的窗口程序。

* 只要更改以下对应变量的内容,就可以显示你想显示的数字。

**/

void Init_Peripheral(void)

{

ucDigShow8 = 8;   /*第8位数码管要显示的内容*/

ucDigShow7 = 7;   /*第7位数码管要显示的内容*/

ucDigShow6 = 6;   /*第6位数码管要显示的内容*/

ucDigShow5 = 5;   /*第5位数码管要显示的内容*/

ucDigShow4 = 4;   /*第4位数码管要显示的内容*/

ucDigShow3 = 3;   /*第3位数码管要显示的内容*/

ucDigShow2 = 2;   /*第2位数码管要显示的内容*/

ucDigShow1 = 1;   /*第1位数码管要显示的内容*/

 

ucDigDot8 = 0;  

ucDigDot7 = 0; 

ucDigDot6 = 0; 

ucDigDot5 = 1;   /*数码管5的小数点显示*/

ucDigDot4 = 0;

ucDigDot3 = 0;   

ucDigDot2 = 0;  

ucDigDot1 = 0;   

}

 

/**

* @brief  初始化函数

* @param  无

* @retval 初始化单片机

**/

void Init(void)

{

LED = 0;

Beep = 1;

Dig_Hc595_Drive(0x00, 0x00); /*关闭所有经过另外两个74HC595驱动的LED灯*/

}

/**

* @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  显示数码管字模的驱动函数

* @param  无

* @retval 动态驱动数码管的原理

* 在八位数码管中,在任何一个瞬间,每次只显示其中一位数码管,另外的七个数码管

* 通过设置其公共位com为高电平来关闭显示,只要切换画面的速度足够快,人的视觉就分辨不出来,感觉八个数码管

* 是同时亮的。以下dig_hc595_drive(xx,yy)函数,其中第一个形参xx是驱动数码管段seg的引脚,第二个形参yy是驱动

* 数码管公共位com的引脚。

**/

void Display_Drive(void)

{

switch(ucDisplayDriveStep)

{

case 1: /*显示第1位*/

ucDigShowTemp = Dig_Table[ucDigShow1];

if(ucDigDot1 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0xfe);

break;

case 2: /*显示第2位*/

ucDigShowTemp = Dig_Table[ucDigShow2];

if(ucDigDot2 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0xfd);

break;

case 3: /*显示第3位*/

ucDigShowTemp = Dig_Table[ucDigShow3];

if(ucDigDot3 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0xfb);

break;

case 4: /*显示第4位*/

ucDigShowTemp = Dig_Table[ucDigShow4];

if(ucDigDot4 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0xf7);

break;

case 5: /*显示第5位*/

ucDigShowTemp = Dig_Table[ucDigShow5];

if(ucDigDot5 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0xef);

break;

case 6: /*显示第6位*/

ucDigShowTemp = Dig_Table[ucDigShow6];

if(ucDigDot6 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0xdf);

break;

case 7: /*显示第7位*/

ucDigShowTemp = Dig_Table[ucDigShow7];

if(ucDigDot7 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0xbf);

break;

case 8: /*显示第8位*/

ucDigShowTemp = Dig_Table[ucDigShow8];

if(ucDigDot8 == 1)

{

ucDigShowTemp = ucDigShowTemp | 0x80; /*显示小数点*/

}

Dig_Hc595_Drive(ucDigShowTemp, 0x7f);

break;

}

ucDisplayDriveStep ++; /*逐位显示*/

if(ucDisplayDriveStep > 8) /*扫描完8个数码管后,重新从第一个开始扫描*/

{

ucDisplayDriveStep = 1;

}

}

/**

* @brief  数码管的595驱动函数

* @param  无

* @retval 

* 如果直接是单片机的IO口引脚驱动的数码管,由于驱动的速度太快,此处应该适当增加一点delay延时或者

* 用计数延时的方式来延时,目的是在八位数码管中切换到每位数码管显示的时候,都能停留一会再切换到其它

* 位的数码管界面,这样可以增加显示的效果。但是,由于是间接经过74HC595驱动数码管的,

* 在单片机驱动74HC595的时候,dig_hc595_drive函数本身内部需要执行很多指令,已经相当于delay延时了,

* 因此这里不再需要加delay延时函数或者计数延时。

**/

void Dig_HC595_Drive(unsigned char ucDigStatusTemp16_09, unsigned char ucDigStatusTemp08_01)

{

unsigned char i;

unsigned char ucTempData;

Dig_Hc595_Sh = 0;

Dig_Hc595_St = 0;

ucTempData = ucDigStatusTemp16_09; /*先送高8位*/

for(i = 0; i < 8; i ++)

{

if(ucTempData >= 0x80)

{

Dig_Hc595_Ds = 1;

}

else

{

Dig_Hc595_Ds = 0;

}

/*注意,此处的延时delay_short必须尽可能小,否则动态扫描数码管的速度就不够。*/

Dig_Hc595_Sh = 0; /*SH引脚的上升沿把数据送入寄存器*/

Delay_Short(1); 

Dig_Hc595_Sh = 1;

Delay_Short(1);

ucTempData = ucTempData <<1;

}

ucTempData = ucDigStatusTemp08_01; /*再先送低8位*/

for(i = 0; i < 8; i ++)

{

if(ucTempData >= 0x80)

{

Dig_Hc595_Ds = 1;

}

else

{

Dig_Hc595_Ds = 0;

}

Dig_Hc595_Sh = 0; /*SH引脚的上升沿把数据送入寄存器*/

Delay_Short(1); 

Dig_Hc595_Sh = 1;

Delay_Short(1);

ucTempData = ucTempData <<1;

}

Dig_Hc595_St = 0; /*ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来*/

Delay_Short(1);

Dig_Hc595_St = 1;

Delay_Short(1);

Dig_Hc595_Sh = 0; /*拉低,抗干扰就增强*/

Dig_Hc595_St = 0;

Dig_Hc595_Ds = 0;

}

 

/*——————主函数——————*/

/**

* @brief  主函数

* @param  无

* @retval 实现LED灯闪烁

**/

void main()

{

/*单片机初始化*/

Init();

/*延时,延时时间一般是0.3秒到2秒之间,等待外围芯片和模块上电稳定*/

Delay_Long(100);

/*单片机外围初始化*/

Init_Peripheral();

while(1)

{

/*显示数码管字模的驱动函数*/

Display_Drive(); 

}

}

 

三、仿真实现


推荐阅读

史海拾趣

ACEINNA公司的发展小趣事

ACEINNA是一家专注于研发和生产惯性传感器和解决方案的公司,以下是该公司发展的五个相关故事:

  1. 公司成立和起步阶段: ACEINNA公司成立于2017年,总部位于美国马萨诸塞州。公司由来自微机电系统(MEMS)领域的资深专家和工程师共同创立,致力于开发高性能的惯性传感器和智能控制系统。起步阶段,ACEINNA主要专注于磁性惯性测量单元(IMU)和导航解决方案的研发。

  2. 技术创新和产品拓展: 随着技术的不断进步和市场需求的增长,ACEINNA不断进行技术创新,并逐步拓展产品线。公司推出了包括惯性测量单元(IMU)、惯性导航系统(INS)、车载导航系统等在内的多种惯性传感器和解决方案,广泛应用于汽车、工业、军事等领域。

  3. 市场拓展和国际合作: ACEINNA积极拓展国内外市场,并与全球各地的客户建立了合作关系。公司的产品被广泛应用于车辆动态控制、无人驾驶、精准农业等领域,赢得了客户的认可。同时,ACEINNA还与国际知名汽车制造商、工业企业展开合作,共同推动技术进步和市场发展。

  4. 持续投入研发和创新: ACEINNA不断加大研发投入,致力于技术创新和产品升级。公司设立了专门的研发团队和实验室,拥有一系列专利技术,致力于开发新产品和解决方案,满足客户不断变化的需求。

  5. 未来发展展望: ACEINNA将继续致力于惯性传感器和智能控制系统的研发和应用,不断推出更先进、更可靠的产品和解决方案,满足客户在各个领域的需求。公司将加强国际市场拓展,提升自身在全球市场的竞争力,为行业的发展做出更大的贡献。

Aearo Technologies公司的发展小趣事

在发展过程中,Aearo Technologies经历了一次重要的收购事件。3M公司看中了Aearo在能量控制领域的领先地位和技术实力,于XXXX年将其收购。收购后,Aearo Technologies成为了3M旗下的一家子公司,继续保留其品牌和技术优势。通过业务整合和资源共享,Aearo Technologies在3M的支持下实现了更快速的发展。

B&F Fastener Supply公司的发展小趣事

随着电子产品的日益小型化和复杂化,对紧固件的要求也越来越高。B&F Fastener Supply公司紧跟行业趋势,投入大量资源进行技术创新。公司成功研发出一系列适用于微型电子设备的紧固件产品,不仅满足了市场的迫切需求,还凭借出色的性能和稳定的品质赢得了客户的广泛认可。

Greenray Industries Inc公司的发展小趣事

为了加速绿色技术的推广和应用,GreenTech积极寻求与全球知名企业的战略合作。例如,公司与一家国际领先的电动汽车制造商达成合作协议,共同研发用于电动汽车的高效电池管理系统。通过这一合作,GreenTech不仅提升了自身在电池技术领域的竞争力,还成功将绿色技术应用于实际产品中,推动了电动汽车行业的绿色发展。

FSP [FSP TECHNOLOGY INC.]公司的发展小趣事

随着公司实力的不断增强,GreenTech开始积极拓展国际市场。公司首先在东南亚地区设立了分支机构,通过本地化运营和服务,成功打入当地市场。随后,GreenTech又陆续在欧洲、北美等地区设立了办事处,与当地企业建立了广泛的合作关系。在国际市场的拓展过程中,GreenTech始终坚持绿色发展的理念,不断推出符合当地市场需求的绿色产品和解决方案,赢得了国际客户的广泛赞誉。

以上五个故事展示了GreenTech在电子行业中绿色解决方案领域的发展历程和成就。公司凭借持续的技术创新、与全球企业的战略合作以及国际市场的不断拓展,逐步成长为绿色技术领域的领军企业。

Cliff Electronic Components公司的发展小趣事

随着公司实力的不断增强,GreenTech开始积极拓展国际市场。公司首先在东南亚地区设立了分支机构,通过本地化运营和服务,成功打入当地市场。随后,GreenTech又陆续在欧洲、北美等地区设立了办事处,与当地企业建立了广泛的合作关系。在国际市场的拓展过程中,GreenTech始终坚持绿色发展的理念,不断推出符合当地市场需求的绿色产品和解决方案,赢得了国际客户的广泛赞誉。

以上五个故事展示了GreenTech在电子行业中绿色解决方案领域的发展历程和成就。公司凭借持续的技术创新、与全球企业的战略合作以及国际市场的不断拓展,逐步成长为绿色技术领域的领军企业。

问答坊 | AI 解惑

请教:接入电池后有些IC不能正常工作

本信息来自合作QQ群:电子工程师技术交流(12425841)   群主在坛子ID:Kata ------------------------------------------------------------------------------------------------ 请教大家一个问题 就是接入电池后有些IC不能正常工作& ...…

查看全部问答>

请教:sc32410的DMA的nXDREQ0和nXDREQ1两个外部源的问题

各位:      我在关于DMA驱动的事情。在ARM外接一块FPGA进行DMA数据传输。想用nXDREQ0为DMA请求源。在datasheet上面写道DREQ与DACK与HCLK同步。我不大理解什么意思?nXDREQ0是在FPGA端发起的,请问nXDREQ0这个在FPGA应该怎么 ...…

查看全部问答>

evc下获取汉字内码后取字模

Hi,各位,请教一下: 1.在evc下是如何获取汉字的内码的?假设汉字为“房”,其内码为623F,在GB2312则为2331,如果知道GB2312下的内码怎样转换成Unicode下的内码? 2.在CE4.2下,系统的字库文件应该是simsum.ac3(如果我没错的话),那么如何根据 ...…

查看全部问答>

谁用过CDU呀?

请问谁使用或是配置或是自己公司内部使用--美国ServerTech公司的CDU呀,这是一种数据中心内部放置Server的Rack用的电源,可以连接到网络里面,在Local PC上监视环境(什么温度湿度电量)之类的,说白了,一个高档次的公牛插排,呵呵。 我现在正在配 ...…

查看全部问答>

求一段VHDL语言控制液晶显示器的程序

最近学VHDL,可是硬件上的NS12864J液晶显示器控制不来,哪位专家能给我个例子学习学习吗…

查看全部问答>

HY57V64

很多HY57V64数据手册都只有十几页。 谁有完整的HY57V64数据手册? 3Q!…

查看全部问答>

生成SOPC时遇到错误

用demo程序重新生成SOPC时遇到下面的错误提示: Error: Failed to refresh PTF fileInfo: Finished elaborating PTF file.Executing: C:/altera/91/quartus//sopc_builder/bin/sopc_builder --classic --generate D:/DE3_NET_340_GMII_NET0/DE3_SO ...…

查看全部问答>

MSP430F2013的16位AD有效位数是多少?

想用集成了16位ADC的MSP430F2013替代我们现有的16位AD,不知道F2013的有效位数是多少位?…

查看全部问答>

MSP430 控制的4轴飞行器

MSP430  控制的4轴飞行器 eZ430-RF2500 development kit 做的,看看给点启发!!…

查看全部问答>