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

📄 lesson9_c.c

📁 8051串口收发。主机要使用IBM汇编。
💻 C
字号:

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

/*功能描述:串口接收PC机发送的数据,并显示*/
/*其他说明:*/
/*版本号:*/
/*************************************************/
#include "reg52.h"
#include "stdio.h"
#include "absacc.h"
#include "intrins.h"

#define uchar unsigned char
#define uint 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 time1_init(void);
void serial_interrupt(void);

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

void delay(uchar m, uchar n);

data unsigned char g_uc_sec_cnt,g_uc_min_cnt,g_uc_hr_cnt;//g_uc_ms_cnt;
data uint g_ui_ram_addr;
data uchar g_uc_recv_serial_cnt;
data unsigned char g_uc_key_number,g_uc_disp_cnt =7;/*uc_disp_cnt显示位计数器*/
code unsigned char g_uc_key_number_all[12]={0xF3,0xEB,0xDB,0xBB,0xF5,0xED,0xDD,0xBD,0xF6,0xEE,0xDE,0xBE};

sbit beep = P1^7;

main()
{
	time1_init();

	g_uc_sec_cnt = 0xAA;
	g_uc_min_cnt = 0xAA;
	g_uc_hr_cnt = 0x1F;
	
	g_uc_recv_serial_cnt = 0;
	g_ui_ram_addr = 0x7800;//first addr

	TR1 = 1;//start the timer1, not enable T1 interrupt
	ES = 1;//enable serial interrupt

	display_led();//display "1",ready for receive the serial data
	while(g_uc_recv_serial_cnt < 11)//waiting for 11 times serial interrupt
	{
		_nop_();
	}
	ES = 0;//mask the serial interrupt
	EA = 0;//mask all interrupt

	g_uc_sec_cnt = 0xA3;
	g_uc_min_cnt = 0xAA;
	g_uc_hr_cnt = 0xA2;
	display_led();

	while(1)
	{
		keypad_scan();
	}

}


/*************************************************/
/*time1_init*///设置串行通信的波特率
/*************************************************/
void time1_init(void)
{
	TMOD = 0x20;
	IE = 0x80;
	TH1 = 0xF3;//baud rate:2400
	TL1 = 0xF3;
	SCON = 0x50;//mode 1
	PCON = 0x80;

}

/*************************************************/
/*
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(2,255);
		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*/
		{
			g_uc_key_number = ACC;/*get the row number*/

			P1 = 0X07;

			ACC = P1;
			ACC &= 0X07;
			if(!(ACC == 0X07))
			{
				delay(2,255);
				P1 = 0X07;
				ACC = P1;
				ACC &= 0X07;/*contains the column number*/
				if(!(ACC == 0X07))
				{
					g_uc_key_number |= ACC;/*combine to the key number*/
					keypad_response(g_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 == g_uc_key_number_all[k])
			  break;
		}
		switch(k)
		{
			case 10:/*A*/
					g_uc_sec_cnt = 0xFF;//熄灭数码管,A~F不能显示
					g_uc_min_cnt = 0xFF;
					g_uc_hr_cnt = 0xFF;

					display_led();/*显示时钟CD4511不能显示A~F*/

					g_uc_disp_cnt = 0;
				break;
			case 11:/*B*/
					g_uc_min_cnt ++;
					g_ui_ram_addr ++;
					g_uc_sec_cnt = XBYTE[g_ui_ram_addr];

					display_led();
					break;
			default:/*k = 0~9*/

					g_uc_disp_cnt++;
					switch(g_uc_disp_cnt)
					{
						case 1:/*hr high*/
								g_uc_hr_cnt = k <<4;
								g_hr_disp = g_uc_hr_cnt;/*using OR can't mask the hr_low,so hr equal to 0*/
							break;
						case 2:/*hr low*/
								g_uc_hr_cnt += k;
								g_hr_disp = g_uc_hr_cnt;
							break;
						case 3:/*min high*/
								g_uc_min_cnt = k <<4;
								g_min_disp = g_uc_min_cnt;
							break;
						case 4:/*min low*/
								g_uc_min_cnt += k;
								g_min_disp = g_uc_min_cnt;

								g_ui_ram_addr = g_uc_hr_cnt;
								g_ui_ram_addr = g_ui_ram_addr << 8;
								g_ui_ram_addr += g_uc_min_cnt;

								g_sec_disp = XBYTE[g_ui_ram_addr];//display the content of thd addr
							break;
						default:

							break;
					}
				break;
		}
	}
	else/*not release the key; continue wait*/
	{
		delay(2,255);
		goto lab;
	}

}
/*************************************************/
/*
name:display_led
function:display the number
*/
/*************************************************/
void display_led(void)
{
	g_sec_disp = g_uc_sec_cnt;
	g_min_disp = g_uc_min_cnt;
	g_hr_disp = g_uc_hr_cnt;
}
/*************************************************/
/*
name:delay
function:
*/
/*************************************************/
void delay(uchar m, uchar n)
{
	unsigned char i, j;
	for(i=0;i<m;i++)
	{
		for(j=0;j<n;j++);
	}
}

/*************************************************/
/*serial_interrupt*/
/*************************************************/
void serial_interrupt(void) interrupt 4 using 2
{
	EA = 0;
	RI = 0;

	g_uc_recv_serial_cnt ++;

	beep = 0;
	delay(30,55);
	beep = 1;

	if(g_uc_recv_serial_cnt < 11)
	{
		ACC = SBUF;
		XBYTE[g_ui_ram_addr] = ACC;
		g_ui_ram_addr ++;

		//delay(5,200);
		//delay(5,10);
		//delay(5,0);//添加了延时后,无法在PC上显示出字符
		SBUF = ACC;//back to IBM, check the TI
	}
	else
	{
		ACC = 0x2A;//ASCII 0x21:!
		SBUF = ACC;
	}

	while(TI == 0)
	{
		delay(3,255);
	}
	TI = 0;

	EA = 1;

}

⌨️ 快捷键说明

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