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

📄 key.c

📁 CH451专用键盘扫描
💻 C
字号:
#include <intrins.h>
#include <absacc.h>
#include "main.h"
#include "mcs51.h"
#include "io_define.h"
#include "ch451.h"

void deal_menu(uchar type,uchar num2);
void deal_device_num(void);
void write_menu_word(uchar n);
void display_main_menu(void);
void deal_enable(uchar num);
void display_second_menu(uchar type);
void init_CPU();
void putchar(unsigned char ch);
void putchar1(unsigned char ch);

bit rcv_bit=0;
bit key_bit=0;
bit led_time_over_bit=0;
bit dat_changed_bit=0;
uchar key_buff[3];
uchar key_times=0;
uchar bdata keyset_enable;
uchar key;
uchar rcv_byte=0x00;

uchar idata t50ms=0,t50ms1=0;
uchar idata t1s1=0,t1s2=0,t1s3=0;
uchar idata t1m1=0,t1m2=0,t1m3=0,t1h1=0,times;

uchar xdata ppout[2]={33,44};
uchar xdata att[2]={15,16};
uchar xdata gate[6]={55,55,66,66,66,66};
uchar xdata	device_num[4]={9,5,1,9};

uchar code	led_num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code	num_bit[9]={0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};


void main(void)
{
	uchar temp=0xff;
	uchar hh=0;
	
	init_CPU();
	init_ch451();
	AUXR=0X00;
	
	display_led(2,0x11);
	
	display_led(7,0xff);
	display_led(6,0xff);
	display_led(5,0xff);
	display_led(4,0xff);
	display_led(3,0xff);

	putchar('f');
	
	while(t1s3<2);
	clear_led();
	
	putchar('B');
	
	while(1)
	{	
		//putchar('c');
		
		temp=get_key();
		if(temp>=0x40)
		{	key=temp;
			key_bit=1;
		}
		else key_bit=0;
			
		if(key_bit)	// 按键处理.added.06-03-18
		{
			putchar(0x59);
			putchar(key);
			key_bit=0;
			do{temp= get_key();}while((temp&0x40)!=0x00);	// 等待按键松开.
			putchar('w');
			
			if(key==KEY_ENTER)
			{
				display_main_menu();	//进入菜单处理.
				clear_led();	// 数码管清 0 .
				putchar('x');
			}
			key_bit=0;	// added by gao.06-03-22
			led_time_over_bit=0;
			putchar(0x88);
		}
	}
}

void T0_INT() interrupt 1  // using 2
{
	TR0=0;
	TH0=TH0+0x4c; //TL0=0xe0; // T0=5ms
	t50ms++;
	t50ms1++;

	if(t50ms>=20)
	{	t50ms=0;
		t1s1++;
		t1s2++;
		t1s3++;
		
		/*putchar(0x22);
		putchar(0x33);
		putchar(t1s1);*/
	}

	if(t1s2>=60)
	{	t1m1++;
		t1m2++;
		t1m3++;
		t1s2=0;
	}

	if(t1m2>=60)
	{	t1m2=0;
		t1h1++;
	}
	TR0=1;
}

void init_CPU()
{
	//WDTC=100;	// 需要针对 STC89C58RD+ 作修改.

	SCON=0x50;
	TMOD=0x21; // T1:baut,T0:Time 16bit
	TCON=0x50; // TR0,TR1=1
	TH1=0xfd;TL1=0xfd;PCON=0; // Uart Baut=9600
    TH0=0x4c;TL0=0x00;  // T0=50ms
	IE=0x92; //开全局中断,定时器0。串口中断。
	IP=0x10; // UART高
	AUXR=0x02;//内部XRAM,ALE为1/6FOSC,AUXR=0x02外部XRAM
}

void deal_device_num(void)
{
	uchar i;
	uchar check_key;
	uchar right_key=0;	// 选择位,初始为第一位.
	uchar num[4];

	display_led(7,LED_N|0x80);

	// 读出本机编号显示.
	
	for(i=0;i<4;i++)
	{
		num[i]=device_num[i];
		display_led(6-i,led_num[num[i]]);
	}
	
	display_led(6,led_num[num[0]]|0x80);	// 默认进入时选择最高位,显示小数点.
	
	////EX0=1;
	t1s1=0;	// 显示以后再开始计时.
	//while((key_bit==0)&&(t1s1<=30));
	while(1)
	{
		if(t1s1>=30)	// 超时退出.
		{	t1s1=0;
			led_time_over_bit=1;
			break;
		}
		
		check_key=get_key();
		if(check_key>=0x40)
		{
			key=check_key;
			key_bit=1;
		}
		else key_bit=0;
		
    	if(key_bit)	// 对按键处理.
    	{
    		do{check_key=get_key();}while((check_key&0X40)!=0X00);	// 等待按键松开.
    		key_bit=0;
    		t1s1=0;

    		if(key==KEY_UP)
    		{
    			if(num[right_key]>0)
    				num[right_key]--;
    			display_led(6-right_key,0x80|led_num[num[right_key]]);
    		}

    		else if(key==KEY_DOWN)
    		{
    			if(num[right_key]<9)
    				num[right_key]++;
    			display_led(6-right_key,0x80|led_num[num[right_key]]);

    		}

    		else if(key==KEY_RIGHT)
    		{	display_led(6-right_key,led_num[num[right_key]]);	// 去掉原来表示选择该位的点显示.
    			right_key++;
				if(right_key>=4)
					right_key=0;
				display_led(6-right_key,0x80|led_num[num[right_key]]);
    		}

    		else if(key==KEY_ENTER)	// 本机编号显示,修改单独处理.
    		{
    			for(i=0;i<4;i++)
    			{
    				device_num[i]=num[i];
					putchar(num[i]);
				}
				////EX0=1;
    			break;
    		}

    		else if(key==KEY_ESC)
    		{	////EX0=1;
    			break;
    		}
    		
    		////EX0=1;		// 本次按键处理完毕开中断.
    	}
    }
}


void write_menu_word(uchar n)	// 写菜单固定内容.
{
	switch(n)
	{
		case 1:display_led(7,LED_T);display_led(6,LED_T);break;
		case 2:display_led(7,LED_E);display_led(6,LED_A);break;
		case 3:display_led(7,LED_G);display_led(6,LED_A);break;
		case 4:display_led(7,LED_S);display_led(6,LED_P);break;
		case 5:display_led(7,LED_P);display_led(6,LED_A);break;
		case 6:display_led(7,LED_N);display_led(6,LED_b);break;
		default:break;
	}
}

void display_main_menu(void)	// 显示一级菜单.
{
	uchar temp=1;
	uchar check_key;

	write_menu_word(temp);

	t1s1=0;

	while(1)
	{
		putchar(0x55);
		putchar(IE);
		putchar(TCON);
		putchar(t1s1);
		
		if(t1s1>=30)	// 超时退出.
		{	t1s1=0;
			led_time_over_bit=1;
			break;
		}
		
		check_key=get_key();
		if(check_key>=0x40)
		{
			key=check_key;
			key_bit=1;
		}
		else key_bit=0;
		
    	if(key_bit)	// 对按键处理.
    	{
    		do{check_key=get_key();}while((check_key&0X40)!=0X00);	// 等待按键松开.
    		key_bit=0;
    		t1s1=0;

    		if(key==KEY_UP)
    		{	if(temp>1)
    				temp--;
    			write_menu_word(temp);
    		}

    		else if(key==KEY_DOWN)
    		{	if(temp<6)
    				temp++;
    			write_menu_word(temp);
    		}

    		else if(key==KEY_ENTER)
    		{
    			if(temp==6)		// 本机编号显示,修改单独处理.
    				deal_device_num();
    			else display_second_menu(temp);

    			if(led_time_over_bit)	// 下层菜单超时退出.	
    				break;
    			
    			if(temp==6)
    			{
    				display_led(7,LED_N);
    				display_led(6,LED_b);
    			}

    			display_led(5,LED_NONE);
    			display_led(4,LED_NONE);
    			display_led(3,LED_NONE);
    		}

    		else if(key==KEY_ESC)
    			break;
    	}
    }
}

void deal_enable(uchar num)	// 键盘设置模块使能.
{
	bit status_bit;
	uchar check_key;
	
	status_bit=(bit)(keyset_enable&num_bit[num]);

	display_led(5,led_num[num]|0x80);
	display_led(4,LED_O);
	if(status_bit)
		display_led(3,LED_N);
	else display_led(3,LED_F);  //

	t1s1=0;
	////EX0=1;
	//while((key_bit==0)&&(t1s1<=30));
	while(1)
	{
		if(t1s1>=30)	// 超时退出.
		{	t1s1=0;
			led_time_over_bit=1;
			break;
		}
		
		check_key=get_key();
		if(check_key>=0x40)
		{
			key=check_key;
			key_bit=1;
		}
		else key_bit=0;
		
    	if(key_bit)	// 对按键处理.
    	{	
    		do{check_key=get_key();}while((check_key&0X40)!=0X00);	// 等待按键松开.
    		key_bit=0;
    		t1s1=0;

    		if((key==KEY_UP)||(key==KEY_DOWN))
    		{	status_bit=~status_bit;
    			if(status_bit)
					display_led(3,LED_N);
				else display_led(3,LED_F);
				////EX0=1;
    		}
    		else if(key==KEY_ENTER)
    		{	if(status_bit)
    			{ 	keyset_enable|=num_bit[num];
    				putchar(keyset_enable);
    			}
				else
				{	keyset_enable&=(~num_bit[num]);
					putchar(keyset_enable);
				}
				dat_changed_bit=1;
				////EX0=1;
    			break;
    		}
    		else if(key==KEY_ESC)	
    		{
    			////EX0=1;
    			break;
    		}
    	}
    }
}

void display_second_menu(uchar type) // type:输入的一级菜单编号.
{
	uchar temp=1;
	uchar check_key;
	
	display_led(5,led_num[temp]);
	t1s1=0;
	////EX0=1;

	//while((key_bit==0)&&(t1s1<=30));
	while(1)
	{
		if(t1s1>=30)	// 超时退出.
		{	t1s1=0;
			led_time_over_bit=1;
			break;
		}
		
		check_key=get_key();
		if(check_key>=0x40)
		{
			key=check_key;
			key_bit=1;
		}
		else key_bit=0;
		
    	if(key_bit)	// 对按键处理.
    	{	
    		do{check_key=get_key();}while((check_key&0X40)!=0X00);	// 等待按键松开.
    		key_bit=0;
    		t1s1=0;

    		if((key==KEY_UP)&&(temp>1))
    		{
    			temp--;
    			display_led(5,led_num[temp]);
    		}
    		else if(key==KEY_DOWN)
    		{	switch(type)
    			{	case 1:if(temp!=2)temp++;break;
    				case 2:if(temp!=6)temp++;break;
    				case 3:if(temp!=6)temp++;break;
    				case 4:if(temp!=6)temp++;break;	// 选频菜单.
    				case 5:if(temp!=2)temp++;break;
    				default:break;
    			}
    			display_led(5,led_num[temp]);
    		}
    		else if(key==KEY_ENTER)
    		{	if(type==2)	// 模块使能控制.
    				deal_enable(temp);
    			else deal_menu(type,temp); // type :一级菜单编号, temp :二级菜单编号.

    			if(led_time_over_bit)	// 下层菜单超时退出.
    			{	////EX0=1;
    				break;
    			}
    			display_led(5,led_num[temp]);
    			display_led(4,LED_NONE);
    			display_led(3,LED_NONE);
    		}
    		
    		else if(key==KEY_ESC)	// 此处向右键没有用到.
    		{   ////EX0=1;
    			break;
    		}   		
    		////EX0=1;
    	}
    }
}

// type :一级菜单编号, num2 :二级菜单编号.
void deal_menu(uchar type,uchar num2)
{
	uchar temp;
	uchar content;
	uchar check_key;

	display_led(5,led_num[num2]|0x80);
	switch(type)
	{
		case 1:	// 查看,设置ATT,
		{
			content=att[num2-1];// num2=1;读出下行衰减值, num2=2,读出上行衰减值,
			temp=content/10;
			display_led(4,led_num[temp]);
			temp=content%10;
			display_led(3,led_num[temp]);
		}break;
		case 3:	// GA.
		{
			content=gate[num2-1];
			temp=content/10;
			display_led(4,led_num[temp]);
			temp=content%10;
			display_led(3,led_num[temp]);
		}break;
		case 4:	// SP.有待修改.
		{
			content=gate[num2-1];
			temp=content/10;
			display_led(4,led_num[temp]);
			temp=content%10;
			display_led(3,led_num[temp]);
		}break;
		case 5:	// PA.
		{
			content=ppout[num2-1];
			temp=content/10;
			display_led(4,led_num[temp]);
			temp=content%10;
			display_led(3,led_num[temp]);
		}break;
		default:break;

	}

	t1s1=0;
	////EX0=1;

	//while((key_bit==0)&&(t1s1<=30));
	while(1)
	{
		if(t1s1>=30)	// 超时退出.
		{	t1s1=0;
			led_time_over_bit=1;
			break;
		}
		
		check_key=get_key();
		if(check_key>=0x40)
		{
			key=check_key;
			key_bit=1;
		}
		else key_bit=0;
		
    	if(key_bit)	// 对按键处理.
    	{	
    		do{check_key=get_key();}while((check_key&0X40)!=0X00);	// 等待按键松开.
    		key_bit=0;
    		t1s1=0;

    		if((key==KEY_UP)&&(content>0)&&(type!=5))
    		{
    			content--;
    			temp=content/10;
				display_led(4,led_num[temp]);
				temp=content%10;
				display_led(3,led_num[temp]);
    		}
    		else if((key==KEY_DOWN)&&(type!=5))
    		{
    			switch(type)
    				{	case 1:if(content<31)content++;break;
    					case 3:if(content<99)content++;break;
    					case 4:if(content<4)content++;break;	// 选频菜单.
    					default:break;
    				}
    			temp=content/10;
				display_led(4,led_num[temp]);
				temp=content%10;
				display_led(3,led_num[temp]);
    		}
    		else if((key==KEY_ENTER)&&(type!=5))
    		{	switch(type)
    				{	case 1:att[num2-1]=content;putchar(content);break;
    					case 3:gate[num2-1]=content;putchar(content);break;
    					case 4:gate[num2-1]=content;putchar(content);break;	// 选频菜单.
    					default:break;
    				} // type :一级菜单编号, temp :二级菜单编号.
    			////EX0=1;
    			break;
    		}
    		else if(key==KEY_ESC)	// 此处向右键没有用到.
    		{	////EX0=1;
    			break;
    		}
   			////EX0=1;
    	}
    }
}



void putchar(unsigned char ch)
{
    SBUF=ch;
    while(!TI);
	TI=0;
}

void UART() interrupt 4 //using 3
{
	if(RI) RI=0;

}

⌨️ 快捷键说明

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