📄 keyboard.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 + -