51单片机点亮4位8段数码管实验

10/8/2023 10:20:35 PM
672
0

一、物料

  1. 共阳极4位8段数码管x1  
  2. 1k电阻x4
  3. 杜邦线若干

二、接线

  1. 数码管的a、b、c、d、e、f、g、dp引脚连接到Arduino的数字引脚  13、2、3、4、5、6、7、8
  2. 数码管d1 d2 d3 d4 接 Arduino的数字引脚 9、10、11、12

数码管图示

三、源码

说明

在51单片机中,通常使用的时钟频率为12MHz。每个机器指令的执行时间为1个机器周期,而一个机器周期通常需要12个时钟周期。

因此,执行一个语句的时间需要12个时钟周期。

假设每个时钟周期为1/12MHz=83.3ns,则执行一个语句的时间为12 * 83.3ns = 999.6ns,约等于1us。

需要注意的是,这个时间只是大致估计,在实际情况下还会受到其他因素的影响,如指令的复杂性、编译器优化等。

因此在本次示例代码中,点亮数码管部分的代码对每个数字要进行50轮,相当于1s中每个数码管闪烁50次,因此频率为50Hz。

计算分析

  1. 内循环每次循环要经历 i<4 ~ i++  共计8个语句大概共用7.997us,其中 delay_ms(5)  用5000次循环共计4,998us ,一个小循环累计使用5005.997us。
  2. 内循环共4次,也就是一轮外循环要使用 20,023.988us,既:20ms。
  3. 因此外层循环次数  1000/20=50 ,因此外循环要50次会使用1s时长。
#include <reg51.h>

typedef unsigned char	u8;
typedef unsigned int	u16;

//注意本例用的是共阳极数码管,共阴极数码管不用取反
unsigned char code	wei[4] = { ~0xfe, ~0xfd, ~0xfb, ~0xf7 };
unsigned char code	duan[16] = { ~0x3F, ~0x06, ~0x5B, ~0x4F, ~0x66, ~0x6D, ~0x7D, ~0x07, ~0x7F, ~0x6F, ~0x77, ~0x7C, ~0x39, ~0x5E, ~0x79, ~0x71 };


void delay_ms( u16 n )
{
	u8 i;
	while ( n-- )
	{
		i = 111;
		while ( i-- )
			;
	}
}

void  setNum(u16 number )
{

	int w=0;
	for (w = 0; w < 50; w++ )         /* ???????????????????? */
	{
		int tempNum = number;
		int  i=0;
		int digit;
		for (i = 0; i < 4; i++ )
		{
			digit = tempNum % 10;  /* ?? */
		 
			P0	= wei[i];
			P2	= duan[digit];
			delay_ms( 5 );
			P2	= 0x00;
			tempNum = tempNum /10; /* ?? */
		}
	}
}


void main( void )
{
	unsigned char a = 0;  //有bug,  char 最大 255
	while ( a <= 9999 )
	{
		setNum(a);
		a++;
	}
}

四、演示

https://www.bilibili.com/video/BV1Mz4y157s9/

全部评论



提问