51单片机(十一)—— 8位数码管-四位累加

一、原理介绍

        关于数码管的控制电路,在《51单片机(八)》中有详细的介绍,硬件电路如下图所示。

        在这个实验中,我们用数码管的前4位设计一个累加器。在进行实验时,需要将单片机的P00~P07引脚与J44相连。接口的对应关系是(P00—D0),……,(P07—D7)。将单片机的P10和P11引脚与J45相连,P10与J45上的DM对应,P11与WM对应。

二、实例介绍

      这个实验的代码如下所示。

#include<reg52.h> //包含头文件,一般情况不需要改动

#define DATA P0 //定义数据端口 程序中遇到DATA 则用P0口 替换
sbit DM = P1^0;  //定义锁存使能端口 段锁存
sbit WM = P1^1;  //定义锁存使能端口 位锁存

unsigned char BJTY_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示段码值0123456789
unsigned char BJTY_WeiMa[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsigned int m=0,Num=0;
unsigned char showdata[8];    //数码管上显示的数据

/********************************************************************/
/*                            延时函数                              */
/*               延时时间的计算对应单片机12MHz的晶振                */
/*            x为延时的ms数,例:x为10时,延时时间约为10ms          */
/********************************************************************/
void delay1ms(unsigned int x)
{
	unsigned int i,j;
	for(j=0;j<x;j++)
		for(i=0;i<123;i++);
}

/*******************************************************************/
/*                      8位数码管显示函数                          */
/*                     First为显示的第一位                         */
/*               如赋值2表示从第三个数码管开始显示                 */
/*                     Number为需要显示的位数                      */
/*                 如赋值2表示共显示两位数码管                     */
/*******************************************************************/
void show_led(unsigned char First,unsigned char Number) 
{
    unsigned char y;
	  
    for(y=0;y<Number;y++)
    { 
        DATA=0;           //清空显示以防重影
        DM=1;             //段锁存
        DM=0;

        DATA=BJTY_WeiMa[y+First]; //取位码 
        WM=1;           //位锁存
        WM=0;

        DATA=showdata[y]; //取显示数据,段码
        DM=1;          //段锁存
        DM=0;
        delay1ms(2);
    }
}


/********************************************************************/
/*                              主函数                              */
/********************************************************************/
void main(void) 
{
	for(;;) 
	{
		m++;
		if(m>=100)       //当前数值显示了一小段时间
		{
			m=0;
			Num++;       //显示的数值加1,实现数值动态变化
			if(Num>=10000)  //Num如果大于等于10000,则令Num=0
			Num=0;
			showdata[0]=BJTY_DuanMa[Num/1000];        //提取Num数值的千位的段码			
			showdata[1]=BJTY_DuanMa[(Num%1000)/100];  //提取Num数值的百位的段码
			showdata[2]=BJTY_DuanMa[(Num%100)/10];    //提取Num数值的十位的段码
			showdata[3]=BJTY_DuanMa[Num%10];          //提取Num数值的个位的段码
		}
		
		show_led(0,4);  //显示数码管,由第一位开始显示,显示四位
	} 
}

将程序烧写到单片机中,可以看到8位数码管的第一位、第二位、第三位和第四位由0001开始累加,加到9999之后再返回0000,之后继续累加,循环往复。

        在这个实验中,我们在代码中创建了一个函数void show_led (unsigned char First,unsigned char Number);,这个函数的作用是用来显示数码管。通过设置形参,可以显示不同的内容和不同的位数。First为显示的第一位,Number为需要显示的位数,需要显示的数据的段码存放在数组showdata[8]中。大家在进行之后的实验中,如果需要显示数码管,可以直接将需要显示的数值的段码存放到showdata[8]中,showdata[0]对应的是需要显示的第一个数据,而不是数码管第一位的数据。调用show_led函数,可以将数据在数码管上显示。

        在这个实验的代码中使用算术运算符除(/)和求余(%)来提取Num各位的数值。

计算方法如下:

千位=Num/1000;

百位=(Num%1000)/100;

十位=(Num%100)/10;

个位=Num%10;

    例如:Num=123;时,千位上,Num/1000=0;百位上,Num%1000=123,再计算123/100=1;十位上,Num%100=23;再用23/10=2; 个位Num%10=3。

发布了78 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bhniunan/article/details/104346655