📄 main.c
字号:
//通用AT89C51试验板驱动
//包括串口通信,键盘输入,三线串行通信
//P1口接4X4键盘。P1.0接键盘最右边插头。
//驱动程序包括:按键后串口发送键号0-F;三线接收;三线和串口接收后串口发送补码
//最后修改2004-12-18
//控制芯片AT89C51
#include <AT89X51.H>
//3线串行通信
sbit CTRL=P3^2; //INT0
sbit CLK=P3^4;
sbit DATA=P3^5;
//4X4键盘扫描
sbit SCAN1=P1^4;
sbit SCAN2=P1^5;
sbit SCAN3=P1^6;
sbit SCAN4=P1^7;
//键盘定义
#define KEY1 0x0008
#define KEY2 0x0080
#define KEY3 0x0800
#define KEY4 0x8000
#define KEY5 0x0004
#define KEY6 0x0040
#define KEY7 0x0400
#define KEY8 0x4000
#define KEY9 0x0002
#define KEY0 0x0020
#define KEYA 0x0200
#define KEYB 0x2000
#define KEYC 0x0001
#define KEYD 0x0010
#define KEYE 0x0100
#define KEYF 0x1000
//UART变量
bit flag_uart_busy;
unsigned char uartread,uartwrite; //已读取和已写入的指针
unsigned char uartbuf[8];//接收缓冲
unsigned char urvcmd;//接收的指令
//三线串行通信,与UART共用接收缓冲和指针
unsigned char ctrlsend,ctrlwrite;//发送指针
unsigned char ctrlbuf[8];//发送缓冲
//时基 1280Hz
#define RELOAD_HIGH 253
#define RELOAD_LOW 70
unsigned char tmrhigh,tmrlow;
//键盘输入
unsigned int nk;
bit flag_keyscan_en;
//其他变量
unsigned char delay1,delay2;
unsigned char ikey;
//按键常量
unsigned int code keys[16]={KEY0,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6,KEY7,KEY8,KEY9,KEYA,KEYB,KEYC,KEYD,KEYE,KEYF};
/*************************
三线串行发送
**************************/
void sendtoctrl(unsigned char cmd){
ctrlbuf[ctrlwrite]=cmd;
if(++ctrlwrite==8) ctrlwrite=0;
}
/**************************
main
***************************/
void main (void){
//启动延时
{unsigned int i;
for(i=0;i<60000;i++){
;}
}
//初始化
//端口
P0=0;
P3=0xFF;
//timer0设置
TMOD|=0x01; //Timer0: 16-bit timer;
TH0=RELOAD_HIGH;
TL0=RELOAD_LOW;
tmrhigh=RELOAD_HIGH;
tmrlow=RELOAD_LOW;
//UART设置
SCON = 0x50; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD|= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
PCON|=0x80;// SMOD=1;speed double
TL1=0xFD; //19200 baud rate
TH1=0xFD; //19200 baud rate reload
TXD=1;
RXD=1;
//INT0中断设置
IT0=1;//边沿触发
//中断设置
EA=1;
ET0=1; //TIMER 0 enabled
ET1=0; //TIMER 1 disabled
ES=1; //UART enabled
EX0=1; //INT0 enabled
//变量初始化
uartread=0;
uartwrite=0;
flag_uart_busy=0;
ctrlsend=0;
ctrlwrite=0;
flag_keyscan_en=1;
//启动定时器
TR0=1;
TR1=1;
while (1) {
//uart communication
//uart received
if(uartread!=uartwrite){//uart cmd received
if(++uartread>7) uartread=0;
urvcmd=uartbuf[uartread];
//add uart process code here
while(flag_uart_busy){
;}
flag_uart_busy=1;
SBUF=255-urvcmd;
} //end of if
//end of uart
//-------------------------feedback code
/*
sendtoctrl(FB_RAD10);
while(flag_uart_busy){
;}
flag_uart_busy=1;
SBUF=FB_RAD10;
}
*/
//key input
if(!flag_keyscan_en){ //new input
if(nk){
//which key pressed
ikey=0;
while (!(nk&keys[ikey])){
ikey++;
}
while(flag_uart_busy){
;}
flag_uart_busy=1;
SBUF=ikey;
}
//f(nk&KEY9){
flag_keyscan_en=1;
}
//end of key
} //end of while(1)
}
/***************************************************
timer 0 interrupt
****************************************************/
void timer0(void) interrupt 1 using 1{
static signed char tick=0;
static unsigned char ctrlcmd=0,ctrlcmdbit=0;//3线串口发送字节,发送比特位置指针
//reload
TR0=0; // stop T0
TH0=tmrhigh;
TL0=tmrlow;
TR0=1; // resume T0
//tick and key
if(--tick<0){ //1/10s
tick=128;
delay1++;
delay2++;
//key input
if(flag_keyscan_en){
unsigned char temp;
nk=0;
P1|=0x0F; // all high
SCAN1=0;
temp=P1&0x0F;
nk=temp;
SCAN1=1;
SCAN2=0;
temp=P1&0x0F;
nk=nk*16+temp;
SCAN2=1;
SCAN3=0;
temp=P1&0x0F;
nk=nk*16+temp;
SCAN3=1;
SCAN4=0;
temp=P1&0x0F;
nk=nk*16+temp;
SCAN4=1;
nk=~nk; //key pressed=bit set to 1
flag_keyscan_en=0;
}//end of key scan
} //end of tick
//send cmd to controller
if(ctrlcmdbit){ //is sending
CLK=1;
ctrlcmd>>=1;
if(ctrlcmd&0x01) DATA=1;
else DATA=0;
if(++ctrlcmdbit==9){ //last(MSB) bit+1
CTRL=1;
CLK=0;
ctrlcmdbit=0;
if(++ctrlsend==8) ctrlsend=0;
EX0=1; //INT0 enabled
DATA=1;
CLK=1;
}
else CLK=0;
}
else if(ctrlsend!=ctrlwrite){ //cmd to be sent, bit=0;
CLK=1;
if(CLK==1) {//is not receiving
EX0=0; //INT0 disabled
CTRL=0;
ctrlcmd=ctrlbuf[ctrlsend];
ctrlcmdbit++;
if(ctrlcmd&0x01) DATA=1;
else DATA=0;
CLK=0;
}
}
}
/***************************************************
uart interrupt
****************************************************/
void uart(void) interrupt 4 using 2{
if( TI){
TI=0;
}
if (RI){
if(++uartwrite>7) uartwrite=0;
uartbuf[uartwrite]=SBUF;
RI=0;
}
flag_uart_busy=0;
}
/***************************************************
INT0 interrupt
receive cmd from driver
****************************************************/
void int0(void) interrupt 0 using 3{
static unsigned char ctrlcmd=0;
if(CLK==1) { //end of byte
if(++uartwrite>7) uartwrite=0;
uartbuf[uartwrite]=ctrlcmd;
ctrlcmd=0;
}
else{
ctrlcmd>>=1;
if(DATA==1) ctrlcmd+=128;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -