51单片机入门实验代码——动态数码管显示

实验一:控制动态数码管从左至右显示0—7:

学习视频:11.5-动态数码管实验--软件编程_哔哩哔哩_bilibili

#include "reg51.h" 
#include "intrins.h" 

typedef unsigned int u16;
typedef unsigned char u8;

#define SMG_A_DP_PORT P0            // 宏定义 SMG_A_DP_PORT 代表 P0

sbit LSA = P2^2;                    // 译码器 位控制器 详情见解析1.2
sbit LSB = P2^3;                    // 译码器 位控制器 
sbit LSC = P2^4;                    // 译码器 位控制器

u8 gsmg_code[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,    
									0x77,0x7c,0x39,0x5e,0x79,0x71};
// 用smg_code数组来存储数值和字母,第一排:0,1,2,3,4,5,6,7,8,9,  第二排:A,b,C,d,E,F,  详情见解析1.1
																		
void delay10us(u16 ten_us)         // 延时程序
{
	while(ten_us--);
}
									
void smg_display()
{
	u8 i = 0;
	for(i=0;i<8;i++)              // 在for循环中 依次设置位控制来选择显示的数码管
	{
		switch(i)
		{
			case 0: LSC = 1;LSB = 1;LSA = 1;  break;  //当i=0时P2.4 P2.3 P2.2为111对应LED8  
			case 1: LSC = 1;LSB = 1;LSA = 0;  break;  //当i=1时P2.4 P2.3 P2.2为110对应LED7
			case 2: LSC = 1;LSB = 0;LSA = 1;  break;  //当i=2时P2.4 P2.3 P2.2为101对应LED6 
			case 3: LSC = 1;LSB = 0;LSA = 0;  break;  //当i=3时P2.4 P2.3 P2.2为100对应LED5 
			case 4: LSC = 0;LSB = 1;LSA = 1;  break;  //当i=4时P2.4 P2.3 P2.2为011对应LED4 
			case 5: LSC = 0;LSB = 1;LSA = 0;  break;  //当i=5时P2.4 P2.3 P2.2为010对应LED3 
			case 6: LSC = 0;LSB = 0;LSA = 1;  break;  //当i=6时P2.4 P2.3 P2.2为001对应LED2 
			case 7: LSC = 0;LSB = 0;LSA = 0;  break;  //当i=7时P2.4 P2.3 P2.2为000对应LED1 
		}
		SMG_A_DP_PORT = gsmg_code[i];  // 对应LED后,显示数字0-7 正好与i对应,所以直接用i在数组中的位置,i=0对应gsmg_code[0]也为0
		delay10us(100);                // 延时1000us = 1ms 肉眼观察不到是依次显示
		SMG_A_DP_PORT = 0x00;          // 消除上一个同一位置的显示光影
	}
}

void main()
{

	while(1)
	{
		smg_display();        
	}
}

解析1.1:

需要了解数码管的构造:51单片机数码管是共阴极,顾名思义,共阴极数码管有个共同的阴极,即 有共同一端是接地的,如图所示。因此,当数码管引脚为高电平(为1)的时候,就会被点亮。

        如图所示:当需要在数码管显示——数字 4 ,需要将B、C、F、G赋1值,于是要将P0赋值为二进制0110 0110 ,即16进制P0=0x66。
由上可得,一个数码管需要8位数据线来显形,那多个数码管就需要很多数据线或者I/O口来操作,显然很笨,于是需要引入控制线来控制哪个数码管被当前操作。

解析1.2:

74HC138译码器,通过P2.4、P2.3、P2.2来控制这8个LED灯的选择。 

P2.4、P2.3、P2.2 有3个二进制位:

000 = Y0 ---> LED1

001 = Y1 ---> LED2

010 = Y2 ---> LED3

011 = Y3 ---> LED4

100 = Y4 ---> LED5

101 = Y5 ---> LED6

110 = Y6 ---> LED7

111 = Y7 ---> LED8

 实验二:控制动态数码管从左至右显示 自己输入的数:

学习视频:07.多位数码管扫描显示_哔哩哔哩_bilibili

#include "reg51.h" 
#include "intrins.h" 

typedef unsigned int u16;
typedef unsigned char u8;

#define SMG_A_DP_PORT P0              // 宏定义 SMG代表数码管

u8 gsmg_code[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
									0x77,0x7c,0x39,0x5e,0x79,0x71};

u8 date_code[8] = {7,0,8,0,4,2,0,2};  // 自己输入,笔者这里输入的是日期:20240807 从低到高

void delay10us(u16 ten_us)            // 延时程序
{
	while(ten_us--);
}
									
void main()
{
	u8 i=0;
	while(1)
	{
		for(i=0;i<8;i++)            
		{
			P2 = i<<2;               // 直接P2赋值 i是几就点亮第几位LED 笔者也不知道原因
			SMG_A_DP_PORT=gsmg_code[date_code[i]];   // 对P0赋值
			delay10us(50);           // 延时短一点,人眼看到时连续的
		}
	}
}

 实验三:控制动态数码管显示 自己输入的一个三位数:

学习视频:07.多位数码管扫描显示_哔哩哔哩_bilibili

#include "reg51.h" 
#include "intrins.h" 

typedef unsigned int u16;
typedef unsigned char u8;

#define SMG_A_DP_PORT P0                    // 宏定义P0

u8 gsmg_code[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
									0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
// 数组gsmg_code保存数字 0-9,A-F,外加一个0x00(空)
u8 date_code[8] = {0,0,0,16,16,16,16,16};	// 构建一个数组来保存要输入的三位数,	gsmg_code[16] =	0x00;表示LED高位都是不显示

u16 shuzi_code = 456;                       // 输入一个三位数字,因为456 > 255(1+2+4+8+16+32+64+128) 所以要用u16来定义类型                    

void delay10us(u16 ten_us)                  // 延时程序
{
	while(ten_us--);
}
									
void main()
{
	u8 i=0;
	while(1)
	{
		for(i=0;i<8;i++)                                // for循环来选择要显示的LED位
		{
			date_code[0]=shuzi_code%10;                 // 取出三位数的个位放到LED最低位
			date_code[1]=shuzi_code/10%10;              // 取出三位数的十位放到LED最二位
			date_code[2]=shuzi_code/100;                // 取出三位数的百位放到LED最三位
			P2 = i<<2;                                  // i是几,LED的显示位就是几
			SMG_A_DP_PORT = gsmg_code[date_code[i]];    // LED显示数
			delay10us(50);                              // 延时到眼睛看不到依次循环显示残影
			SMG_A_DP_PORT = 0x00;                       // 把LED每一位都为空,消除每一次循环上一次显示的残影
		}
	}
}

以上内容,学习参考所用。如有侵权,Call我必删。

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值