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

📄 keyboard.c

📁 实用的空调计费系统
💻 C
字号:
/********************Copyright******************************
			烟台佳园智能数码科技有限公司
名称:KEYBOARD.C
功能:掌上维护器驱动程序
说明:与HICJ5的结合不是很好,虽然能正常跑起来,但是由于相对HICJ5.C有较多功能重复性代码
 	  浪费了一定的内存及代码资源
修改:2004/12/6	增加了取消报警状态功能
 	  2004/12/7 去掉了通信时钟等功能,对于表的类型显示采用了固定值法
************************************************************/
#include "P89C60X2.h"
#include "hicj6.h"
//#include "INTRINS.H"
/**************new define**********************************/
unsigned char idata Key_value;
unsigned char idata House_count;
unsigned char idata Idletime_count;
unsigned char idata Speaker_count;
//unsigned char idata Msb_led_val;
//unsigned char idata Msb_led;			//表字显示的最高位
unsigned char idata Blink_led;
unsigned long idata Blink_led_val;
unsigned long idata Modified_hdd;	//修改后的读数暂存
unsigned char idata Point_position;
unsigned char idata Press_interval;
unsigned char idata Short_rmb;
unsigned char idata Break_rmb;

bit Key_flag=0;
bit Key_modify_flag=0;
bit Led_blink_flag=0;
bit Speaker_flag=0;
bit Disp_flag=0;
bit Key_en=1;
bit Short_flag=0;
bit Break_flag=0;

unsigned char idata Led[16];

/****** HD7279A 指令 ******/
#define CMD_RESET 0xa4
#define CMD_TEST 0xbf
#define DECODE0 0x80
#define DECODE1 0xc8
#define CMD_READ 0x15
#define UNDECODE 0x90
#define RTL_CYCLE 0xa3
#define RTR_CYCLE 0xa2
#define RTL_UNCYL 0xa1
#define RTR_UNCYL 0xa0
#define ACTCTL 0x98
#define SEGON 0xe0
#define SEGOFF 0xc0
#define BLINKCTL 0x88
//******键值定义*******
#define		ASK			58
#define 	RIGHT		59
#define		LEFT		61
#define		INCREASE	60
#define		DECREASE	62
#define		ENTER		57

#define		Pulse_constant	1

extern void write7279(unsigned char, unsigned char,unsigned char);// 发送一个字节	// 写入到HD7279
extern unsigned char read7279(unsigned char,unsigned char);			// 从HD7279读出
extern void send_byte(unsigned char,unsigned char);
extern unsigned char receive_byte();
extern void Write1B(unsigned char,unsigned char,bit);
extern unsigned char Read1B(unsigned char,bit);
extern unsigned char ReadSR();
extern unsigned long Read_hdd_new(unsigned char);
extern void Write_hdd_new(unsigned char);
extern void Key_Pro(void);

void waitNms(unsigned char);
void assign_dispdata(unsigned char);
void disp_reading(void);
void write_dispdata(void);
void disappear_contrl(void);
void alarm_chk(void);

extern unsigned char idata Type_temp;
extern union hdd_long {BYTE Hdd_B[4];unsigned long Hdd_L;} Hdd_Str;
/**********************************************************
*名	   称:init_timer2
*功	   能:初使化定时计数器2
*说	   明:工作方式为16位重装,递增计数,与hicj5.c结合时此函数可省略
*调	   用:无
*入口参数:无
*返 回 值:无
***********************************************************/
/*void init_timer2(void)
{
	TH2    = 0x00;
	TL2    = 0x00;
	RCAP2H = 0x00;
	RCAP2L = 0x00;
	T2CON  = 0x04;
	ET2	   = 1;
	EA	   = 1;
}*/
/**********************************************************
*名	   称:timer2_int
*功	   能:利用中断来实现各种延时
*说	   明:中断一次为62.5ms;结合时将此函数转移到HICJ5.C的TIMER2_INT中
*调	   用:无
*入口参数:无
*返 回 值:无
***********************************************************/
/*void timer2_int(void) interrupt 5 using 1
{
	TF2=0;
	if(Key_flag)					//是否有按键
	{
		Idletime_count++;
		if(Idletime_count==100)		//是否已延时62.5*100次
		{
			Key_flag=0;				//	清除所有标志位
			Disp_flag=0;
			Led_blink_flag=0;
			Key_modify_flag=0;
			House_count=0;
			Idletime_count=0;
			send_byte(CMD_RESET,0);	//数码管全部消隐
			cs1=cs2=1;
			write7279(DECODE0+0,0x0f,1);
			write7279(DECODE0+1,0x0f,1);
			write7279(DECODE0+2,0x0f,1);
			write7279(DECODE0+3,0x0f,1);
		}
	}
	if(Speaker_flag)				//控制SPEAKER鸣200MS
	{
		Speaker_count++;
		if(Speaker_count==3)
		{
			Speaker_count=0;
			Speaker_flag=0;
			Speaker=1;
		}
	}
	if(!Key_en)						//控制两个按键之间的间隔为300ms
	{
		Press_interval++;
		if(Press_interval==4)
		{
			Press_interval=0;
			Key_en=1;
		}
	}
} */

void keyboard(void)
{
//	send_byte(CMD_RESET,1);
//	send_byte(CMD_RESET,0);
//	cs1=cs2=1;

	if((!Key)&Key_en)
    {
		Key_value=read7279(CMD_READ,1);
		switch(Key_value)
		{
		/*	case(ASK):						//查询键只实现循环查徇功能,而不能由此键引起修改
				Key_flag=1;
				Idletime_count=0;			//两次按键间的空闲时间计数(由定时器TIME2完成)
				if(House_count>=40)
				House_count=0;				//房屋号计数,值为1-40对应1-40号房屋
				House_count++;
				assign_dispdata(House_count);	//读出并分配House_count户的数据
				disappear_contrl();
				disp_reading();				//显示读数及房屋号
				Speaker=0;
				Speaker_flag=1;
				Speaker_count=0;
				break;*/
			case(ASK):
				break;
			case(RIGHT):					//向右查询,在些键基础上按ENTER可进行修改
				Disp_flag=1;				//对于键盘,只有RIGHT,LEFT两个键可以引起显示
				Key_flag=1;					//
				Idletime_count=0;
				if(Led_blink_flag)
				{
					if(Blink_led==1)
					Blink_led=128;
					else
					Blink_led=Blink_led>>1;
					write7279(BLINKCTL,~Blink_led,0);	// 闪烁位右移一位
				}
				else
				{
					if(House_count>=40)
					House_count=0;
					House_count++;				//key press count
					assign_dispdata(House_count);	//House_count为0~39对应1-40回路
					disappear_contrl();
					disp_reading();				//显示读数
					alarm_chk();				//显示报警及表具类型
				}
				Speaker=0;
				Speaker_flag=1;
				Speaker_count=0;
				break;
			case(LEFT):
				Disp_flag=1;
				Key_flag=1;
				Idletime_count=0;
				if(Led_blink_flag)
				{
					if(Blink_led==128)
					Blink_led=1;
					else
					Blink_led=Blink_led<<1;
					write7279(BLINKCTL,~Blink_led,0);	// 闪烁位右移一位
				}
				else
				{
					if((House_count==1)|(House_count==0))
					House_count=41;
					House_count--;
					assign_dispdata(House_count);
					disappear_contrl();
					disp_reading();			//显示读数
					alarm_chk();
				}
				Speaker=0;
				Speaker_flag=1;
				Speaker_count=0;
				break;
			case(ENTER):
				if(Disp_flag&!Key_modify_flag&!Short_flag&!Break_flag)					//如果此前只有RIGHT及LEFT按键
				{
					Key_flag=1;
					Idletime_count=0;
					Blink_led=128;
					if(!Led_blink_flag)
					{
						assign_dispdata(House_count);
						disp_reading();
						write7279(BLINKCTL,~Blink_led,0);		//最高们闪烁
						Led_blink_flag=1;
					}
					else
					{
						write7279(BLINKCTL,0xff,0);				//消除闪烁属性
						Led_blink_flag=0;
					}
					Speaker=0;
					Speaker_flag=1;
					Speaker_count=0;
				}
				if(Key_modify_flag)								//如果此前按的是UP,DOWN键
				{
					Key_flag=1;
					Idletime_count=0;
					write_dispdata();
					write7279(BLINKCTL,0xff,0);				//消除闪烁属性
					Led_blink_flag=0;
					Key_modify_flag=0;

					Speaker=0;
					Speaker_flag=1;
					Speaker_count=0;
				}
				if(Short_flag)
				{
					Short_flag=0;
					Short_rmb&=(~(1<<(House_count-1)%8));
					Write1B(Short_rmb,170+(House_count-1)/8,0);
					write7279(UNDECODE+6,0x00|0x01,1);
					Speaker=0;
					Speaker_flag=1;
					Speaker_count=0;
				}
				if(Break_flag)
				{
					Break_flag=0;
					Break_rmb&=(~(1<<(House_count-1)%8));
					Write1B(Break_rmb,175+(House_count-1)/8,0);
					write7279(UNDECODE+6,0x00|0x01,1);
					Speaker=0;
					Speaker_flag=1;
					Speaker_count=0;
				}
				break;
			case(INCREASE):
				if(Led_blink_flag)
				{
					Key_flag=1;
					Idletime_count=0;
					Key_modify_flag=1;
					switch(Blink_led)
					{
						case(1): Blink_led_val=0;break;
						case(2): Blink_led_val=1;break;
						case(4): Blink_led_val=2;break;
						case(8): Blink_led_val=3;break;
						case(16): Blink_led_val=4;break;
						case(32): Blink_led_val=5;break;
						case(64): Blink_led_val=6;break;
						case(128): Blink_led_val=7;break;
						default:break;
					}
					Led[Point_position]&=0x0f;
					if(Led[Blink_led_val]>=9)
							Led[Blink_led_val]=0;
					else	Led[Blink_led_val]++;
					disp_reading();

					Speaker=0;
					Speaker_flag=1;
					Speaker_count=0;
				}
				break;
			case(DECREASE):
				if(Led_blink_flag)
				{
					Key_flag=1;
					Idletime_count=0;
					Key_modify_flag=1;
					switch(Blink_led)
					{
						case(1): Blink_led_val=0;break;
						case(2): Blink_led_val=1;break;
						case(4): Blink_led_val=2;break;
						case(8): Blink_led_val=3;break;
						case(16): Blink_led_val=4;break;
						case(32): Blink_led_val=5;break;
						case(64): Blink_led_val=6;break;
						case(128): Blink_led_val=7;break;
						default:break;
					}
					Led[Point_position]&=0x0f;
					if(Led[Blink_led_val]==0)
							Led[Blink_led_val]=9;
					else	Led[Blink_led_val]--;
					disp_reading();

					Speaker=0;
					Speaker_flag=1;
					Speaker_count=0;
				}
				break;
			default:
				break;
		}
	Key_en=0;
//waitNms(100);
	}
}
/**********************************************************
*名	   称:waitNms
*功	   能:延时N毫秒
*说	   明:i,j需定义为IDATA
*调	   用:无
*入口参数:N
*返 回 值:无
***********************************************************/
/*void waitNms(unsigned char data n)
{
    unsigned char idata i,j;
    for(i=0;i<n;i++)
    for (j=0;j<100;j++)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}*/
/**********************************************************
*名	   称:assign_dispdata
*功	   能:读出并分配要显示的数据,将户号及读数存于LED[i]
*说	   明:无
*调	   用:Read_hdd_new,Read1B,
*入口参数:House(房屋号)
*返 回 值:无
***********************************************************/
void assign_dispdata(unsigned char data House2)
{
	unsigned char idata a,i;
	Read_hdd_new(House2);							//读HOUSE回路读数
	Hdd_Str.Hdd_L=Hdd_Str.Hdd_L/Pulse_constant;	//除以脉冲常数32=3200
	Led[7]= Hdd_Str.Hdd_L/10000000;
    Led[6]=(Hdd_Str.Hdd_L%10000000)/1000000;
    Led[5]=(Hdd_Str.Hdd_L%1000000 )/100000;
    Led[4]=(Hdd_Str.Hdd_L%100000  )/10000;
    Led[3]=(Hdd_Str.Hdd_L%10000   )/1000;
    Led[2]=(Hdd_Str.Hdd_L%1000    )/100;
    Led[1]=(Hdd_Str.Hdd_L%100     )/10;
    Led[0]= Hdd_Str.Hdd_L%10;

	Led[15]=Read1B(House2*3-1,1);				//分配房屋号
    a=Read1B(House2*3-2,1);
    Led[9]=a/0x10;
    Led[8]=a%0x10;
    a=Read1B(House2*3-3,1);
    Led[11]=a/0x10;
    Led[10]=a%0x10;
    for(i=8;i<12;i++)
    {
    	if(Led[i]>9)
		Led[i]=0x0f;
    }

	Point_position=Read1B(200+House2-1,0);	//小数点位置确定
    Point_position=(Point_position>>4)&7;
    if(Point_position)
	Led[Point_position]|=0x80;
}
/**********************************************************
*名	   称:disappear_contrl
*功	   能:控制当最高位为0时将其消隐
*说	   明:最低显示0.00
*调	   用:
*入口参数:无
*返 回 值:无
***********************************************************/
void disappear_contrl(void)
{
	if (Led[7]==0)
	{
		Led[7]=0x0f;
		if(Led[6]==0)
		{
			Led[6]=0x0f;
			if(Led[5]==0)
			{
				Led[5]=0x0f;
				if(Led[4]==0)
				{
					Led[4]=0x0f;
					if(Led[3]==0)
					{
						Led[3]=0x0f;
					}
				}
			}
		}
	}
}
/**********************************************************
*名	   称:disp_reading
*功	   能:显示计量表读数及户号
*说	   明:最低显示0.00
*调	   用:
*入口参数:无
*返 回 值:无
***********************************************************/
void disp_reading(void)
{
	unsigned char idata i;
	Led[Point_position]|=0x80;				 	//小数点位置
	for(i=0;i<8;i++)
	{
		write7279(DECODE0+i,Led[i],0);			//Hdd
	}
	for(i=0;i<4;i++)
    {
       	write7279(DECODE0+i,Led[i+8],1);      	//House Codez
	}
}
/**********************************************************
*名	   称:write_dispdata
*功	   能:将修改后的读数写入存储器
*说	   明:十六进制第5位进位时总是进不上去!!!!!!!!!!
			长整数后加L解决问题
*调	   用:
*入口参数:无
*返 回 值:无
***********************************************************/
void write_dispdata(void)
{
	Led[Point_position]&=0x0f; //消除小数点位置造成的数值错误
	Modified_hdd=Led[0]+Led[1]*10+Led[2]*100+Led[3]*1000
				+Led[4]*10000L+Led[5]*100000L+Led[6]*1000000L
				+Led[7]*10000000L;
	Hdd_Str.Hdd_L=Modified_hdd*Pulse_constant;	//两位小数
	Write_hdd_new(House_count);
}
/**********************************************************
*名	   称:alarm_chk
*功	   能:检查是否有报警状态
*说	   明:指曾发生过的报警,有报警则置位相应的标志位
*调	   用:
*入口参数:无
*返 回 值:无
***********************************************************/
void alarm_chk(void)
{
	Short_flag=Break_flag=0;
	Short_rmb=Read1B(170+(House_count-1)/8,0);
	Break_rmb=Read1B(175+(House_count-1)/8,0);
	if(Short_rmb&(1<<(House_count-1)%8))
	{
		write7279(UNDECODE+6,0x10|0x01,1);
		Short_flag=1;
		if(Break_rmb&(1<<(House_count-1)%8))
		{
			write7279(UNDECODE+6,0x30|0x01,1);
			Break_flag=1;
		}
	}
	else
	{
		if(Break_rmb&(1<<(House_count-1)%8))
		{
			write7279(UNDECODE+6,0x20|0x01,1);
			Break_flag=1;
		}
		else
		write7279(UNDECODE+6,0x00|0x01,1);

	}
}


⌨️ 快捷键说明

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