⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lesson5_c.c

📁 6位共阴数码管
💻 C
字号:

/************************************************/
/*单位名称:华南理工大学电信学院*/
/*模块:1位共阴数码管,CD4511驱动,使用反极法的键盘*/
/*创建人:景永年   日期:2006年5月25日*/
/*修改人:*/

/*功能描述:带置位功能的6个LED数码管数字时钟*/
/*其他说明:当时钟的时针大于50后,不能准确的调整*/
/*版本号:*/
/*************************************************/
#include "reg52.h"
#include "stdio.h"
#define uchar unsigned char

unsigned char volatile xdata g_sec_disp _at_ 0xFFFF;
unsigned char volatile xdata g_min_disp _at_ 0xEFFF;
unsigned char volatile xdata g_hr_disp  _at_ 0xDFFF;

void time0_init(void);

void keypad_scan(void);
void keypad_response(uchar key_number);
void display_led(void);

void delay(void);

data unsigned char uc_sec_cnt,uc_min_cnt,uc_hr_cnt,uc_ms_cnt;
data unsigned char uc_key_number,uc_disp_cnt =7;/*uc_disp_cnt显示位计数器*/
code unsigned char uc_key_number_all[12]={0xF3,0xEB,0xDB,0xBB,0xF5,0xED,0xDD,0xBD,0xF6,0xEE,0xDE,0xBE};

main()
{
	
	
	time0_init();
	
	uc_sec_cnt = 0;
	uc_min_cnt = 0;
	uc_hr_cnt = 0;
	uc_ms_cnt = 0;
	
	//SP = 0x60	;//no need to Initiate stack
	ET0 = 1;//start the timer0
	TR0 = 1;
	
	while(1)
	{
		keypad_scan();
	}
	
}


/*************************************************/
/*time0_init*/
/*************************************************/
void time0_init(void)
{
	TMOD = 0x01 ;//定时中断的初始化,定时器0工作在定时器模式
	IE = 0x80   ;//开总中断;由TR0启停,16bit(模式1)
	TH0 = 0x3C   ;//初值15536
	TL0 = 0xB0   ;//100ms=0.1s
	
}

/*************************************************/
/*
name:keypad_scan()
function: scan the keypad, get the key number
使用反极法检测键值
output:uc_key_number
*/
/*************************************************/
void keypad_scan(void)
{
	P1 = 0XF8;
	
	ACC = P1;
	ACC &= 0XF8;
	if(!(ACC == 0XF8))
	{
		delay();
		P1 = 0XF8;
		ACC = P1;
		ACC &= 0XF8;
		if(!(ACC == 0XF8))/*note:if(ACC != 0XF8) ACC XOR 0xF8;if(!(ACC == 0XF8)) the value of the ACC don't change*/
		{
			uc_key_number = ACC;/*get the row number*/

			P1 = 0X07;
			
			ACC = P1;
			ACC &= 0X07;
			if(!(ACC == 0X07))
			{
				delay();
				P1 = 0X07;
				ACC = P1;
				ACC &= 0X07;/*contains the column number*/
				if(!(ACC == 0X07))
				{
					uc_key_number |= ACC;/*combine to the key number*/
					keypad_response(uc_key_number);
				}
			}
		}
	}
}

/*************************************************/
/*
name:keypad_response()
function:response to the key number 
input:uc_key_number
*/
/*************************************************/
void keypad_response(uchar key_number)
{
	uchar k;
lab:P1 = 0X07;/*release the key or not?*/
	ACC = P1;
	ACC &= 0X07;

	if((ACC == 0X07))/*release the key*/
	{
		for(k=0;k<=11;k++)
		{
			if(key_number == uc_key_number_all[k])
			  break;
		}
		switch(k)
		{
			case 10:/*A*/
					ET0 = 0;//停止timer0
					TR0 = 0;
					uc_sec_cnt = 0xFF;//熄灭数码管,A~F不能显示
					uc_min_cnt = 0xFF;
					uc_hr_cnt = 0xFF;

					display_led();/*显示时钟CD4511不能显示A~F*/
					
					uc_disp_cnt = 0;
				break;
			case 11:/*B*/
					TH0 = 0x3C;//重新装载数据
					TL0 = 0xB0;
					ET0 = 1;//启动timer0
					TR0 = 1;
					if(uc_disp_cnt == 0)/*取消时钟设置*/
					{
						display_led();/*显示时钟原来的值*/
												
					}
					uc_disp_cnt = 7;/*avoid setting incorrectly,the maximal number is 6*/
				break;

			default:/*k = 0~9*/
					
					uc_disp_cnt++;
					switch(uc_disp_cnt)
					{
						case 1:/*hr high*/
								uc_hr_cnt = k <<4;
								g_hr_disp = uc_hr_cnt;/*using OR can't mask the hr_low,so hr equal to 0*/						
							break;
						case 2:/*hr low*/
								uc_hr_cnt += k;
								uc_hr_cnt %= 0x24;//adjust the hr
								g_hr_disp = uc_hr_cnt;
							break;
						case 3:/*min high*/
								uc_min_cnt = k <<4;
								g_min_disp = uc_min_cnt;
							break;
						case 4:/*min low*/
								uc_min_cnt += k;
								uc_min_cnt %= 0x60;//adjust the min
								g_min_disp = uc_min_cnt;
							break;
						case 5:/*sec high*/
								uc_sec_cnt = k<<4;
								g_sec_disp = uc_sec_cnt;
							break;
						case 6:/*sec low*/
								uc_sec_cnt += k;
								uc_sec_cnt %= 0x60;//adjust the sec
								g_sec_disp = uc_sec_cnt;

								uc_disp_cnt = 7;/*avoid setting incorrectly*/
							break;
						default:
								
							break;
					}
				break;
		}
	}
	else/*not release the key; continue wait*/
	{
		delay();
		goto lab;
	}

}
/*************************************************/
/*
name:display_led
function:display the number
*/
/*************************************************/
void display_led(void)
{
	g_sec_disp = uc_sec_cnt;
	g_min_disp = uc_min_cnt;
	g_hr_disp = uc_hr_cnt;
}
/*************************************************/
/*
name:delay
function: 
*/
/*************************************************/
void delay(void)
{
	unsigned char i, j;
	for(i=0;i<2;i++)
	{
		for(j=0;j<255;j++);
	}
}

/*************************************************/
/*time0_interrupt*/
/*************************************************/
void time0_interrupt(void) interrupt 1 using 3
{
	TH0 =0x3C   ;//重新装入初值15536
	TL0 =0xB0   ;//100ms=0.1s
	
	uc_ms_cnt++;
	if(uc_ms_cnt==10)
	{
		uc_ms_cnt = 0;		
		uc_sec_cnt++;
		if((uc_sec_cnt&0x0F)>9)	/*变量uc_sec_cnt为16进制数,显示应该为10进制*/
		{
			uc_sec_cnt += 6;	/*(uc_sec_cnt&0x0F)按位与运算*/
		}						/*若没有if语句,则只能是到9以后,继续数到F才进位*/		
		display_led();/*显示时钟*/
		
	
		if((uc_sec_cnt)>=0x60)
		{
			uc_sec_cnt = 0;
			uc_min_cnt++;
			if((uc_min_cnt&0x0F)>9)		/*变量uc_min_cnt为16进制数,显示应该为10进制*/
			{
				uc_min_cnt += 6;		/*(uc_min_cnt&0x0F)按位与运算*/
			}							/*若没有if语句,则只能是到9以后,继续数到F才进位*/	
			display_led();

			if((uc_sec_cnt)>=0x60)
			{
				uc_min_cnt = 0;
				uc_hr_cnt++;

				if((uc_hr_cnt&0x0F)>9)		/*变量uc_hr_cnt为16进制数,显示应该为10进制*/
				{
					uc_hr_cnt += 6;			/*(uc_hr_cnt&0x0F)按位与运算*/
				}							/*若没有if语句,则只能是到9以后,继续数到F才进位*/

				display_led();
				
				if((uc_hr_cnt)>=0x24)
				{
					uc_hr_cnt = 0;
				}
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -