?? 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 + -