我的矩阵键盘。。为什么我P1口被强制为1了
时间:10-02
整理:3721RD
点击:
#include<reg51.h>//头文件
#define uchar unsigned char//把 unsigned char 宏定义为 uchar 以后只要写uchar 就是unsigned char 的意思
#define benji 0x01//本机地址0x02
uchar idata RBUF;
uchar idata TBUF;
uchar idata st,bb;
uchar nroom=benji;
uchar benji_data;
uchar lamp=0,board=0,key;
int f;
bit f0;
bit tready;//定义发送
bit rready;//定义接收
//sfr P0=0x80;
//sfr P1=0x90;
//sfr P2=0xa0;
//sfr P3=0xb0;
//sfr SBUF=0x99;//数据发送缓冲区
sbit rd=P3^7;
bit get_data=0;//本机选中标志
//*********************************************************
void delay(unsigned int time)//延迟程序,time=1ms
{unsigned char k;
unsigned int i;
for(i=time*2;i>0;i--)
for(k=248;k>0;k--);}//算法一层循环248*2=二层循环(496+3)*2=1ms
unsigned char kbscan()//扫描程序
{unsigned char sccode,recode;//定义两个数
P1=0xf0;//定义P1口初值
if((P1&0xf0)!=0xf0)//判断P1口不等于初值的时候,有键按下
{delay(10); //延迟消除键位抖动
if((P1&0xf0)!=0xf0) //再判断
{sccode=0xfe;
while((sccode&0x10)!=0) //循环只有当构号内的值不等于0时 ,进行下一步操作
{P1=sccode;
if((P1&0xf0)!=0xf0) //将数值付给P1与初值相与,不等于初值时
{recode=(P1&0xf0)|0x0f; //这时候,定义的第二个数值取值
P1=0xf0; //将第二个数值付给P1口
return((~sccode)+(~recode)); //两个数值分别取反后,想加后返回
}
else {
sccode=(sccode<<1)|0x01; //不成立的话(按键)左移
}}
}}
return(0);}
void keyvalue()//确定键盘值
{switch(key)
{
case 0x11 :lamp=0x01 ;break;
case 0x21 :lamp=0x02 ;break;
case 0x41 :lamp=0x04 ;break;
case 0x81 :lamp=0x08 ;break;
case 0x12 :lamp=0x10 ;break;
case 0x22 :lamp=0x20 ;break;
case 0x42 :lamp=0x40 ;break;
case 0x82 :lamp=0x80 ;break;
case 0x14 :board=0x01 ;break;
case 0x24 :board=0x02 ;break;
case 0x44 :board=0x04 ;break;
case 0x84 :board=0x08 ;break;
case 0x18 :board=0x10 ;break;
case 0x28 :board=0x20 ;break;
case 0x48 :board=0x40 ;break;
case 0x88 :board=0x80 ;break;}
}
//*************************************//
void Read_room(uchar addr) //读房间状态
{
uchar bendata;
if(addr==benji)
{
bendata=P2;
RBUF=bendata;
return;
}
ES=0;
SM2=0;
TB8=1;
rd=1;
delay(50);
SBUF=addr;
while(TI!=1);
delay(10);
TI=0;
delay(50);
TB8=0;
rd=1;
delay(50);
SBUF=0x02; //发送读命令
while(TI!=1);
delay(10);
TI=0;
delay(50);
rd=0;
while(RI!=1); //接收状态
delay(10);
RI=0;
delay(50);
RBUF=SBUF;
//TB8=1;
SM2=1;
ES=1;
}
void room() //room 选择
{
nroom=board;
Read_room(nroom);
P0=RBUF;
board=0;
}
//************************//
void zhuan_room(uchar addr,uchar tn)
{
if(addr==benji)
{
P2=tn;
return;
}
while(1)
{
ES=0;
SM2=0;
TB8=1;
rd=1;
delay(50);
SBUF=addr; //发地址
while(TI!=1);
delay(10);
TI=0;
delay(50);
TB8=0;
delay(50);
SBUF=0x01; //发命令
while(TI!=1);
delay(10);
TI=0;
delay(50);
TBUF=tn;
delay(50);
SBUF=TBUF; //发数据
while(TI!=1);
delay(10);
TI=0;
delay(50);
rd=0;
delay(10);
//TB8=1;
SM2=1;
ES=1;
return;}
}
void judge()
{
uchar sp1,sp2;
sp1=~lamp;
sp2=P0;
sp2&=sp1;
P0=sp2;
zhuan_room(nroom,sp2);
lamp=0;}
//*******************************************//
void str(void) //发送函数
{tready=0;
st=P2;
rd=1;
delay(50);
SBUF=st;
while(TI!=1);
delay(10);
TI=0;
delay(50);
SM2=1;
rd=0;
delay(10);
get_data=0;
ES=1;
}
void sre(void) //接收函数
{
rready=0;
rd=0;
delay(10);
while(RI!=1);
delay(50);
RI=0;
RBUF=SBUF;
SM2=1;
get_data=0;
ES=1;}
void str_sre()
{
uchar b;
ES=0;
SM2=0;
rd=0;
while(RI!=1);
delay(10);
RI=0;
delay(50);
b=SBUF;
if(b==0x01)
{
sre();
P2=RBUF;
}
else
{if(b==0x02)
{str();}}}
//*************************************************//
void UART_init(void)
{
TMOD=0x21;//定时器1设置与工作方式2.将定时器0设置成工作方式1.
TL1=0xFD;
TH1=0xFD;//置初值,波特率9600,晶振
IE=0x97;
IP=0x15;
TCON=0x00;
TR1=1;//启动定时器
SCON=0xF0;//串行口方式3
PCON=0x00;//倍频为0
P0=0x00;
P2=0x00;
rd=0;}
//*************************************//
void main(viod)//主函数
{
UART_init();
while(1)
{tready=1;
rready=1;//假定准备好发送和接收
key=kbscan();
delay(10);
if(key!=0)
{
keyvalue();
if(lamp!=0) judge();
if(board!=0) room();
if(get_data==1)str_sre();
} } }
void serial_int(void) interrupt 4 using 1
{
RI=0;
ES=0;
if(SBUF==benji)
{get_data=1;}
ES=1;}
#define uchar unsigned char//把 unsigned char 宏定义为 uchar 以后只要写uchar 就是unsigned char 的意思
#define benji 0x01//本机地址0x02
uchar idata RBUF;
uchar idata TBUF;
uchar idata st,bb;
uchar nroom=benji;
uchar benji_data;
uchar lamp=0,board=0,key;
int f;
bit f0;
bit tready;//定义发送
bit rready;//定义接收
//sfr P0=0x80;
//sfr P1=0x90;
//sfr P2=0xa0;
//sfr P3=0xb0;
//sfr SBUF=0x99;//数据发送缓冲区
sbit rd=P3^7;
bit get_data=0;//本机选中标志
//*********************************************************
void delay(unsigned int time)//延迟程序,time=1ms
{unsigned char k;
unsigned int i;
for(i=time*2;i>0;i--)
for(k=248;k>0;k--);}//算法一层循环248*2=二层循环(496+3)*2=1ms
unsigned char kbscan()//扫描程序
{unsigned char sccode,recode;//定义两个数
P1=0xf0;//定义P1口初值
if((P1&0xf0)!=0xf0)//判断P1口不等于初值的时候,有键按下
{delay(10); //延迟消除键位抖动
if((P1&0xf0)!=0xf0) //再判断
{sccode=0xfe;
while((sccode&0x10)!=0) //循环只有当构号内的值不等于0时 ,进行下一步操作
{P1=sccode;
if((P1&0xf0)!=0xf0) //将数值付给P1与初值相与,不等于初值时
{recode=(P1&0xf0)|0x0f; //这时候,定义的第二个数值取值
P1=0xf0; //将第二个数值付给P1口
return((~sccode)+(~recode)); //两个数值分别取反后,想加后返回
}
else {
sccode=(sccode<<1)|0x01; //不成立的话(按键)左移
}}
}}
return(0);}
void keyvalue()//确定键盘值
{switch(key)
{
case 0x11 :lamp=0x01 ;break;
case 0x21 :lamp=0x02 ;break;
case 0x41 :lamp=0x04 ;break;
case 0x81 :lamp=0x08 ;break;
case 0x12 :lamp=0x10 ;break;
case 0x22 :lamp=0x20 ;break;
case 0x42 :lamp=0x40 ;break;
case 0x82 :lamp=0x80 ;break;
case 0x14 :board=0x01 ;break;
case 0x24 :board=0x02 ;break;
case 0x44 :board=0x04 ;break;
case 0x84 :board=0x08 ;break;
case 0x18 :board=0x10 ;break;
case 0x28 :board=0x20 ;break;
case 0x48 :board=0x40 ;break;
case 0x88 :board=0x80 ;break;}
}
//*************************************//
void Read_room(uchar addr) //读房间状态
{
uchar bendata;
if(addr==benji)
{
bendata=P2;
RBUF=bendata;
return;
}
ES=0;
SM2=0;
TB8=1;
rd=1;
delay(50);
SBUF=addr;
while(TI!=1);
delay(10);
TI=0;
delay(50);
TB8=0;
rd=1;
delay(50);
SBUF=0x02; //发送读命令
while(TI!=1);
delay(10);
TI=0;
delay(50);
rd=0;
while(RI!=1); //接收状态
delay(10);
RI=0;
delay(50);
RBUF=SBUF;
//TB8=1;
SM2=1;
ES=1;
}
void room() //room 选择
{
nroom=board;
Read_room(nroom);
P0=RBUF;
board=0;
}
//************************//
void zhuan_room(uchar addr,uchar tn)
{
if(addr==benji)
{
P2=tn;
return;
}
while(1)
{
ES=0;
SM2=0;
TB8=1;
rd=1;
delay(50);
SBUF=addr; //发地址
while(TI!=1);
delay(10);
TI=0;
delay(50);
TB8=0;
delay(50);
SBUF=0x01; //发命令
while(TI!=1);
delay(10);
TI=0;
delay(50);
TBUF=tn;
delay(50);
SBUF=TBUF; //发数据
while(TI!=1);
delay(10);
TI=0;
delay(50);
rd=0;
delay(10);
//TB8=1;
SM2=1;
ES=1;
return;}
}
void judge()
{
uchar sp1,sp2;
sp1=~lamp;
sp2=P0;
sp2&=sp1;
P0=sp2;
zhuan_room(nroom,sp2);
lamp=0;}
//*******************************************//
void str(void) //发送函数
{tready=0;
st=P2;
rd=1;
delay(50);
SBUF=st;
while(TI!=1);
delay(10);
TI=0;
delay(50);
SM2=1;
rd=0;
delay(10);
get_data=0;
ES=1;
}
void sre(void) //接收函数
{
rready=0;
rd=0;
delay(10);
while(RI!=1);
delay(50);
RI=0;
RBUF=SBUF;
SM2=1;
get_data=0;
ES=1;}
void str_sre()
{
uchar b;
ES=0;
SM2=0;
rd=0;
while(RI!=1);
delay(10);
RI=0;
delay(50);
b=SBUF;
if(b==0x01)
{
sre();
P2=RBUF;
}
else
{if(b==0x02)
{str();}}}
//*************************************************//
void UART_init(void)
{
TMOD=0x21;//定时器1设置与工作方式2.将定时器0设置成工作方式1.
TL1=0xFD;
TH1=0xFD;//置初值,波特率9600,晶振
IE=0x97;
IP=0x15;
TCON=0x00;
TR1=1;//启动定时器
SCON=0xF0;//串行口方式3
PCON=0x00;//倍频为0
P0=0x00;
P2=0x00;
rd=0;}
//*************************************//
void main(viod)//主函数
{
UART_init();
while(1)
{tready=1;
rready=1;//假定准备好发送和接收
key=kbscan();
delay(10);
if(key!=0)
{
keyvalue();
if(lamp!=0) judge();
if(board!=0) room();
if(get_data==1)str_sre();
} } }
void serial_int(void) interrupt 4 using 1
{
RI=0;
ES=0;
if(SBUF==benji)
{get_data=1;}
ES=1;}
我知道就是最后的中断程序的问题。该怎么改啊 啊啊啊啊