中斷與數碼管動態顯示程式碼

EricsT發表於2024-11-08

數碼管從0-999999且高位0顯示


#include <reg52.h>

sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

unsigned char code LedChar[] = //數碼管顯示字元轉換表
{
	0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
	0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

unsigned char LedBuff[] = //數碼管顯示緩衝區,初值為0xFF確保啟動時都不亮
{
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

unsigned char i = 0;//動態掃描的索引
unsigned int cnt = 0;//記錄T0中斷次數
unsigned char isFlag = 0;//1s標誌位

void main(void)
{
	unsigned long sec = 0;//記錄經過的秒數

	ENLED = 0;//使能U3,選擇控制數碼管
	ADDR3 = 1;//因為需要動態改變ADDR0-2的值,所以不需要再初始化了
	TMOD = 0x01;//設定T0為模式1
	TH0 = 0xFC;//設定T0賦初值為0xFC67,定時1ms
	TL0 = 0x67;
	TR0 = 1;//啟動T0

	EA = 1;//使能總中斷
	ET0 = 1;//使能T0中斷

	while (1)
	{
		if (1 == isFlag)//判斷1秒定時標誌
		{
			isFlag = 0;//1秒定時標誌清零
			if (999999 == sec)
				sec = 0;
			else
				sec++;//秒計數加1

			//以下程式碼將sec按十進位制位從低到高依次提取並轉為數碼管顯示字元
			LedBuff[0] = LedChar[sec % 10];
			LedBuff[1] = LedChar[sec / 10 % 10];
			LedBuff[2] = LedChar[sec / 100 % 10];
			LedBuff[3] = LedChar[sec / 1000 % 10];
			LedBuff[4] = LedChar[sec / 10000 % 10];
			LedBuff[5] = LedChar[sec / 100000 % 10];
		}
	}
}

/* 定時器中斷服務函式 */
void interrupt0 (void) interrupt 1//T0中斷
{
	TH0 = 0xFC;//重新賦初值
	TL0 = 0x67;
	cnt++;//計數值加1

	if (cnt > 1000)
	{
		cnt = 0;//清零計數值以重新開始下一秒計時
		isFlag = 1;	   //設定1秒定時標誌位1
	}

	P0 = 0xFF;//顯示消隱

	//以下程式碼完成數碼管動態掃描重新整理
	switch (i)
	{
	case 0: ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;i++;P0 = LedBuff[0];break;
	case 1: ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;i++;P0 = LedBuff[1];break;
	case 2: ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;i++;P0 = LedBuff[2];break;
	case 3: ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;i++;P0 = LedBuff[3];break;
	case 4: ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;i++;P0 = LedBuff[4];break;
	case 5: ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;i = 0;P0 = LedBuff[5];break;
	default:break;
	}
}

數碼管從0-999999且高位0不顯示


#include <reg52.h>

sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

unsigned char code LedChar[] = //數碼管顯示字元轉換表
{
	0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
	0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

unsigned char LedBuff[] = //數碼管顯示緩衝區,初值為0xFF確保啟動時都不亮
{
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

unsigned char i = 0;//動態掃描的索引
unsigned int cnt = 0;//記錄T0中斷次數
unsigned char isFlag = 0;//1s標誌位
unsigned long sec = 0;//記錄經過的秒數

void main(void)
{
	ENLED = 0;//使能U3,選擇控制數碼管
	ADDR3 = 1;//因為需要動態改變ADDR0-2的值,所以不需要再初始化了
	TMOD = 0x01;//設定T0為模式1
	TH0 = 0xFC;//設定T0賦初值為0xFC67,定時1ms
	TL0 = 0x67;
	TR0 = 1;//啟動T0

	EA = 1;//使能總中斷
	ET0 = 1;//使能T0中斷

	while (1)
	{
		if (1 == isFlag)//判斷1秒定時標誌
		{
			isFlag = 0;//1秒定時標誌清零
			if (999999 == sec)
				sec = 0;
			else
				sec++;//秒計數加1

			//以下程式碼將sec按十進位制位從低到高依次提取並轉為數碼管顯示字元
			LedBuff[0] = LedChar[sec % 10];
			LedBuff[1] = LedChar[sec / 10 % 10];
			LedBuff[2] = LedChar[sec / 100 % 10];
			LedBuff[3] = LedChar[sec / 1000 % 10];
			LedBuff[4] = LedChar[sec / 10000 % 10];
			LedBuff[5] = LedChar[sec / 100000 % 10];
		}
	}
}

/* 定時器中斷服務函式 */
void interrupt0 (void) interrupt 1//T0中斷
{
	TH0 = 0xFC;//重新賦初值
	TL0 = 0x67;
	cnt++;//計數值加1

	if (cnt > 1000)
	{
		cnt = 0;//清零計數值以重新開始下一秒計時
		isFlag = 1;	   //設定1秒定時標誌位1
	}

	P0 = 0xFF;//顯示消隱

	//以下程式碼完成數碼管動態掃描重新整理
	switch (i)
	{
	case 0: if (sec >= 0){ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;P0 = LedBuff[0];}i++;break;
	case 1: if (sec >= 10){ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;P0 = LedBuff[1];}i++;break;
	case 2: if (sec >= 100){ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;P0 = LedBuff[2];}i++;break;
	case 3: if (sec >= 1000){ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;P0 = LedBuff[3];}i++;break;
	case 4: if (sec >= 10000){ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;P0 = LedBuff[4];}i++;break;
	case 5: if (sec >= 100000){ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;P0 = LedBuff[5];}i = 0;break;
	default:break;
	}
}

數碼管從999999-0且高位0顯示


#include <reg52.h>

sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

unsigned char code LedChar[] = //數碼管顯示字元轉換表
{
	0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
	0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

unsigned char LedBuff[] = //數碼管顯示緩衝區,初值為0xFF確保啟動時都不亮
{
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

unsigned char i = 0;//動態掃描的索引
unsigned int cnt = 0;//記錄T0中斷次數
unsigned char isFlag = 0;//1s標誌位

void main(void)
{
	unsigned long sec = 999999;//秒數

	ENLED = 0;//使能U3,選擇控制數碼管
	ADDR3 = 1;//因為需要動態改變ADDR0-2的值,所以不需要再初始化了
	TMOD = 0x01;//設定T0為模式1
	TH0 = 0xFC;//設定T0賦初值為0xFC67,定時1ms
	TL0 = 0x67;
	TR0 = 1;//啟動T0

	EA = 1;//使能總中斷
	ET0 = 1;//使能T0中斷

	while (1)
	{
		if (1 == isFlag)//判斷1秒定時標誌
		{
			isFlag = 0;//1秒定時標誌清零

			if (0 == sec)
				sec = 999999;
			else
				sec--;//秒計數減1

			//以下程式碼將sec按十進位制位從低到高依次提取並轉為數碼管顯示字元
			LedBuff[0] = LedChar[sec % 10];
			LedBuff[1] = LedChar[sec / 10 % 10];
			LedBuff[2] = LedChar[sec / 100 % 10];
			LedBuff[3] = LedChar[sec / 1000 % 10];
			LedBuff[4] = LedChar[sec / 10000 % 10];
			LedBuff[5] = LedChar[sec / 100000 % 10];
		}
	}
}

/* 定時器中斷服務函式 */
void interrupt0 (void) interrupt 1//T0中斷
{
	TH0 = 0xFC;//重新賦初值
	TL0 = 0x67;
	cnt++;//計數值加1

	if (cnt > 1000)
	{
		cnt = 0;//清零計數值以重新開始下一秒計時
		isFlag = 1;	   //設定1秒定時標誌位1
	}

	P0 = 0xFF;//顯示消隱

	//以下程式碼完成數碼管動態掃描重新整理
	switch (i)
	{
	case 0: ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;i++;P0 = LedBuff[0];break;
	case 1: ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;i++;P0 = LedBuff[1];break;
	case 2: ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;i++;P0 = LedBuff[2];break;
	case 3: ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;i++;P0 = LedBuff[3];break;
	case 4: ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;i++;P0 = LedBuff[4];break;
	case 5: ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;i = 0;P0 = LedBuff[5];break;
	default:break;
	}
}

數碼管從999999-0且高位0不顯示


#include <reg52.h>

sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

unsigned char code LedChar[] = //數碼管顯示字元轉換表
{
	0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
	0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

unsigned char LedBuff[] = //數碼管顯示緩衝區,初值為0xFF確保啟動時都不亮
{
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

unsigned char i = 0;//動態掃描的索引
unsigned int cnt = 0;//記錄T0中斷次數
unsigned char isFlag = 0;//1s標誌位
unsigned long sec = 999999;//秒數

void main(void)
{
	

	ENLED = 0;//使能U3,選擇控制數碼管
	ADDR3 = 1;//因為需要動態改變ADDR0-2的值,所以不需要再初始化了
	TMOD = 0x01;//設定T0為模式1
	TH0 = 0xFC;//設定T0賦初值為0xFC67,定時1ms
	TL0 = 0x67;
	TR0 = 1;//啟動T0

	EA = 1;//使能總中斷
	ET0 = 1;//使能T0中斷

	while (1)
	{
		if (1 == isFlag)//判斷1秒定時標誌
		{
			isFlag = 0;//1秒定時標誌清零

			if (0 == sec)
				sec = 999999;
			else
				sec--;//秒計數減1

			//以下程式碼將sec按十進位制位從低到高依次提取並轉為數碼管顯示字元
			LedBuff[0] = LedChar[sec % 10];
			LedBuff[1] = LedChar[sec / 10 % 10];
			LedBuff[2] = LedChar[sec / 100 % 10];
			LedBuff[3] = LedChar[sec / 1000 % 10];
			LedBuff[4] = LedChar[sec / 10000 % 10];
			LedBuff[5] = LedChar[sec / 100000 % 10];
		}
	}
}

/* 定時器中斷服務函式 */
void interrupt0 (void) interrupt 1//T0中斷
{
	TH0 = 0xFC;//重新賦初值
	TL0 = 0x67;
	cnt++;//計數值加1

	if (cnt > 1000)
	{
		cnt = 0;//清零計數值以重新開始下一秒計時
		isFlag = 1;	   //設定1秒定時標誌位1
	}

	P0 = 0xFF;//顯示消隱

	//以下程式碼完成數碼管動態掃描重新整理
	switch (i)
	{
	case 0: if (sec >= 0){ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;P0 = LedBuff[0];}i++;break;
	case 1: if (sec >= 10){ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;P0 = LedBuff[1];}i++;break;
	case 2: if (sec >= 100){ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;P0 = LedBuff[2];}i++;break;
	case 3: if (sec >= 1000){ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;P0 = LedBuff[3];}i++;break;
	case 4: if (sec >= 10000){ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;P0 = LedBuff[4];}i++;break;
	case 5: if (sec >= 100000){ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;P0 = LedBuff[5];}i = 0;break;
	default:break;
	}
}

相關文章