📄 key.c
字号:
#include <reg51.h>
#include <absacc.h>
#include <intrins.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define O 'O'
#define K 'K'
#define E 'E'
#define R 'R'
//--------------------------------------------------------
#define Wait_ti while(TI==0);TI=0 /*等待一帧发送完毕*/
#define Wait_ri while(RI==0);RI=0 /*等待一帧接收完毕*/
/**************************************
-------------芯片管脚定义--------------
***************************************/
sbit PowerLed=P1^4;
sbit SHIFTLED=P1^5;
sbit TestLED=P1^6;
sbit Beep=P1^7;
sbit KeyIn=P3^3;
sbit KeyOut=P3^4; //0:有键按下
//=====================================
#define OK 0
#define ER 1
//=====================================
/**********************************************
-------------与主机通信命令名柄定义----------
**********************************************/
#define GetKey 0x90 //有键直接返回键值
#define OpenBeep 0X91 //打开蜂鸣器,嘟... 嘟....,无返回值
#define TestKey 0x94 //检测主板与键盘板IC的通信,回送主板Finish命令句柄
#define OpenMoneyBox 0x9a //开钱箱命令句柄
#define CloseCat 0x9c //关机
#define English 0x9d //英文字母命令
#define Number 0x9e //数字命令
//=====================================
bit err_rxd_flag; //串口接收数据错误
bit rxd_flag;
uchar uc0;
uchar rs232buf[30]; //接收数据缓存
//=====================================
void rxd_order_232(); /*接收命令、数据*/
//=====================================
void ssio0(void) interrupt 4 using 1 //*串行中断0接收程序*
{
ES=0; //*关串行中断*
rxd_order_232();
rxd_flag=1;
ES=1;
}
//=====================================
void delayms(uint ti) //*延时程序~0.1ms,*
{ //延时时间=[ti(100)+1]*1.08us~=ti*0.108ms
uint i;
uchar t;
for (i=0;i<ti;i++)
{
t=99;
do{
t--;
}while(t!=0);
}
}
/*******************************************
---------- 初始化串行口来多机通信 ---------
*******************************************/
void InitSBUF(void)
{
TMOD=0x21; /* T/C1定义为方式2 */
TL1=0xfd; /* 9600时TH1,TL1=0xfd,1200时TH1,TL1=0XE8 */
TH1=0xfd;
PCON=0x00;
SCON=0x50; /* 串行口为方式1,SM2=1,TB8=0,RB8=0 */
/* SM0=0;*/
TR1=1; ES=0; /*ET0=1; ES=1; TR0=1;*/
/* SM2=1; PS=1;*/
RI=0; TI=0; EA=1;
}
//===================================
void sbuwork(uchar d) /*发送一数据:c*/
{
uchar c;
SBUF=d; /*发送数据*/
Wait_ti; /*等待一帧发送完毕*/
for(c=0;c<=0x05;c++);
}
//===================================================
/*void buzzer(uchar num,uchar on,uchar off)//蜂鸣器驱动
{ //unm:次数;on:鸣时间;off:停时间
uchar n;
if((num==0)|(on==0)){return;}
for(n=0;n<(num-1);n++)
{
Beep=0;
delayms(on);
Beep=1;
delayms(off);
}
Beep=0;
delayms(on);
Beep=1;
}*/
//=================================================
//
// key 键盘操作程序
//
//==================================================
uchar key_press() //按键扫描程序
{
uchar key_num;
uchar n;
uchar key_x;
uchar keybuf[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
key_num=0xff;
if(P0==0xff){goto AD;} //没键按下退出
delayms(20);
if(P0==0xff){goto AD;} //没键按下
KeyOut=1; //消除按键标志
Beep=0;
for(n=0;n<8;n++)
{
P2=keybuf[n];
if(P0<0xff){key_x=P0;key_num=n;goto AA;}
}
key_num=0xff;goto AD;//退出
AA:
for(n=0;n<8;n++)
{
if(key_x==keybuf[n])
{
key_num=key_num*8;
key_num=key_num+n;
while(P0<0xff)//等待抬手
{
delayms(20);
}
// buzzer(1,120,2);
goto AD;
}
}
AD:
P0=0xff;
P2=0x00;
Beep=1;
return key_num;
}
/********************************************************/
void rxd_by_232() /*从232接收一个数据,并保存到uc0变量中*/
{
uchar counter;
counter=0xfe;
do{
if(counter==0x00)
{RI=0;err_rxd_flag=1;return;}
else{counter--;}
}while(RI==0);
RI=0;
uc0=SBUF;
err_rxd_flag=0;
}
//===============================
//--------------------------------------------------------------
/*命令格式:0x1b+0x10+命令句柄+数据包序号+命令长度+(命令参数)+CS*/
void rxd_order_232() /*接收命令、数据*/
{
uchar k,n;
uchar length;
RI=0;
rs232buf[0]=SBUF; /*接收包头:0x1b*/
rxd_by_232(); /*接收包头:0x10*/
if(err_rxd_flag==1){goto END;}
else{rs232buf[1]=uc0;}
rxd_by_232(); /*接收命令句柄*/
if(err_rxd_flag==1){goto END;}
else{rs232buf[2]=uc0;}
rxd_by_232(); /*接收数据包序号*/
if(err_rxd_flag==1){goto END;}
else{rs232buf[3]=uc0;}
rxd_by_232(); /*接收数据长度*/
if(err_rxd_flag==1){goto END;}
else{rs232buf[4]=uc0;}
length=uc0;
if(length<5){n=length=5;}//goto AA;
else{_nop_();}
for(k=5;k<(length+2);k++)
{
rxd_by_232(); /*接收数据*/
if(err_rxd_flag==1){goto END;}
else{rs232buf[k]=uc0; }
}
END:
TestLED=~TestLED;
}
//=============================================================
/* CRC-16的C程序. *ptr指向发送数据块的首地址, len是数据块以字节为单位的长度.*/
/* 按位计算CRC虽然代码简单,所占用的内存比较少,
但其最大的缺点就是一位一位地计算会占用很多的处理器处理时间,*/
uint cal_crc(uchar len,uchar *ptr) //crc16计算
{
uchar i;
uint crc=0;
while(len--!=0)
{
for(i=0x80; i!=0; i/=2)
{
if((crc&0x8000)!=0) {crc*=2; crc^=0x8005;} //* 余式CRC乘以2再求CRC *
else{crc*=2;}
if((*ptr&i)!=0){crc^=0x8005;} //* 再加上本位的CRC *
}
ptr++;
}
return(crc);
}
//===========================================
void return_OK(uchar d)
{
uchar n;
uint crc;
rs232buf[0]=0x4f;
rs232buf[1]=0x4b; //OK
rs232buf[2]=0x00; //包序号
rs232buf[3]=0x05; //命令长度
rs232buf[4]=d; //命令长度
crc=cal_crc(5,rs232buf);//crc_16校验
rs232buf[5]=crc>>8;
rs232buf[6]=crc;
for(n=0;n<7;n++){sbuwork(rs232buf[n]);}//发送数据
}
//===========================================
void main(void)
{
uchar n;
uchar handle;
uchar key_num;
uchar key_d;
uchar KeyNum[20];
ulong coun;
InitSBUF();
P0=0xff;
P2=0x00;
for(n=0;n<20;n++)
{KeyNum[n]=0xff;}
key_num=0xff;
ES=1; //开串行中断
coun=0;
rxd_flag=0;
while(1)
{
SHIFTLED=KeyOut;
// if(coun==0x0ff){coun=0;TestLED=~TestLED;}
coun++;
key_d=key_press();
if(key_d<0xff)
{key_num=key_d;}
/*if(key_d<0xff) //有键值
{
for(n=0;n<16;n++)
{
if(KeyNum[n]==0xff)
{
KeyNum[n]=key_d;
}
}
}
if(KeyNum[15]<0xff){KeyNum[15]=0xff;}
if((KeyNum[0]<0xff)&&(key_num==0xff))
{
key_num=KeyNum[0];
for(n=0;n<15;n++)
{
KeyNum[n]=KeyNum[n+1];
}
}*/
if(key_num==0xff){KeyOut=1;}
else{KeyOut=0;} //消除按键标志
if(rxd_flag==1)
{
rxd_flag=0;
ES=0;
return_OK(key_num);
handle=rs232buf[2];//命今字
//for(n=0;n<12;n++){sbuwork(rs232buf[n]);}//发送数据
/* //return_OK(key_num);
switch(handle)
{
case GetKey: //返回键值
{
return_OK(key_num);
break;
}
case OpenBeep: //开蜂鸣器
{
buzzer(rs232buf[5],120,120);
return_OK(key_num);
break;
}
case TestKey:
{
return_OK(key_num);
break;
}
case OpenMoneyBox:
{
return_OK(key_num);
break;
}
case CloseCat:
{
return_OK(key_num);
break;
}
case English:
{
return_OK(key_num);
break;
}
case Number:
{
return_OK(key_num);
break;
}
default:{break;}
}
key_num=0xff;
ES=1;
for(n=0;n<30;n++){rs232buf[n]=0;}//发送数据*/
key_num=0xff;
ES=1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -