51微控制器入門:數碼管(3)

Arciab發表於2024-11-27

數碼管簡介

image-20241127175917258

數碼管每段其本質就是個LED燈,只需要控制特定的LED燈亮就能顯示資料。普中開發版所使用的是兩個並在一起共陰極連線的“4位數碼管”,可以同時顯示8個數字。數碼管的顯示可以分成靜態顯示和動態顯示,這裡先介紹最簡單的靜態顯示。

image-20241127180727836

數碼管分為共陰極連線和共陽極連線,顧名思義共陰極就是把所有的數碼管陰極連線在一起,共陽極就是把數碼管所有的陽極連線在一起,之所以這麼做是為了節省微控制器I/O口。

圖(a)是數碼管段選點陣圖,以普中51微控制器開發版為例,它的數碼管採用共陰極(低電平0)連線,所以如果我們想讓一個數碼管顯示數字6,就應當在相應段選位設定為高電平(1),其餘設定為低電平(0),如圖所示:

image-20241127184928608

下圖是共陰極數碼管顯示0-F對應的編碼(表中省略了dp段0):

image-20241127185200447

74HC138譯碼器簡介

作用:節省微控制器I/O口

image-20241127185807057

//這裡結合兩張圖片一起介紹
// P2_4 = 1;P2_3 = 1;P2_2 = 1;  控制LED8 
// P2_4 = 1;P2_3 = 1;P2_2 = 0;  控制LED7 
// P2_4 = 1;P2_3 = 0;P2_2 = 1;  控制LED6 
// P2_4 = 1;P2_3 = 0;P2_2 = 0;  控制LED5 
// P2_4 = 0;P2_3 = 1;P2_2 = 1;  控制LED4 
// P2_4 = 0;P2_3 = 1;P2_2 = 0;  控制LED3 
// P2_4 = 0;P2_3 = 0;P2_2 = 1;  控制LED2 
// P2_4 = 0;P2_3 = 0;P2_2 = 0;  控制LED1 

image-20241127190621212

到此知識準備結束,現在可以編寫第一個程式了。

靜態數碼管顯示

#include<regx52.h>

unsigned char Table[] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F}; // 陣列,定義數字0~9段選

void SMG(unsigned char Location,Number) // 定義函式,引數Location是位選,Number段選控制顯示的數字。
{
	switch(Location) // 位選
	{
		case 1 : P2_4 = 1;P2_3 = 1;P2_2 = 1;break;
		case 2 : P2_4 = 1;P2_3 = 1;P2_2 = 0;break;
		case 3 : P2_4 = 1;P2_3 = 0;P2_2 = 1;break;
		case 4 : P2_4 = 1;P2_3 = 0;P2_2 = 0;break;
		case 5 : P2_4 = 0;P2_3 = 1;P2_2 = 1;break;
		case 6 : P2_4 = 0;P2_3 = 1;P2_2 = 0;break;
		case 7 : P2_4 = 0;P2_3 = 0;P2_2 = 1;break;
		case 8 : P2_4 = 0;P2_3 = 0;P2_2 = 0;break;
	}
	P0 = Table[Number]; // 段選
}

void main()
{
//	P2_2 = 1;  // 這是我做的小實驗,不要過多關注
//	P2_3 = 1;
//	P2_4 = 0;
//	P0 = 0X7D; // 這塊板子共陰極數碼管,38譯碼器和SMG都是從下往上數	
	while(1)
	{
	  SMG(5,6); // 第五位顯示數字6
	}
}

實驗現象:(Proteus模擬中P0埠要有個上拉電阻,這裡沒截到)

image-20241127202746210

動態數碼管顯示

原理:快速掃描逐個顯示,利用人眼的餘輝效應顯示多個數碼管,實際上在一個時刻內只有一個數碼管點亮。

#include<regx52.h>

unsigned char Table[] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};

void Delay(unsigned int n)  // 延時函式
{
	unsigned char j;
	while(n--)
	{
		for(j = 0; j< 113; j++);
	}
}

void SMG(unsigned char Location,Number)
{
	switch(Location) // 段選
	{
		case 1 : P2_4 = 1;P2_3 = 1;P2_2 = 1;break;
		case 2 : P2_4 = 1;P2_3 = 1;P2_2 = 0;break;
		case 3 : P2_4 = 1;P2_3 = 0;P2_2 = 1;break;
		case 4 : P2_4 = 1;P2_3 = 0;P2_2 = 0;break;
		case 5 : P2_4 = 0;P2_3 = 1;P2_2 = 1;break;
		case 6 : P2_4 = 0;P2_3 = 1;P2_2 = 0;break;
		case 7 : P2_4 = 0;P2_3 = 0;P2_2 = 1;break;
		case 8 : P2_4 = 0;P2_3 = 0;P2_2 = 0;break;
	}
	P0 = Table[Number];				// 位選
	Delay(1);					// 數碼管顯示1ms後關閉
	P0 = 0X00;					// 消影清零,防止上次的資料竄位重影
}
void main()
{
	while(1)
	{
		SMG(1,1); // 位選 段選
		SMG(2,2);
	        SMG(3,3);
	}
}

實驗現象:

動畫

相關文章