关于单片机P3口的值对单片机串口通信的影响

我的这个程序功能是从矩阵键盘接受信号后将信号翻译为数字信号发送给计算机,键盘一共16个按钮。

由于硬件要求我必须从P3口接受信号后传给计算机,我写的程序是接受一次信号松手检测完毕后发一个信号给计算机,松手检测是用的循环语句,循环结束后发信息,逻辑上没有问题,但实际上接受一次信号却在循环进行中时发送很多同样的信息给计算机,经排除后我发现是P3口的值对通信的影响(我并没有开中断),于是我开始地毯式排查,挨个实验P3口各位对通信影响。

这里附上P3口的第二功能:

P3口除作为通用I/O口外,还有第二种功能。P3口的第二种功能定义如下:
P3.0 RXD(串行数据输入口)
P3.1 TXD(串行数据输出口)
P3.2 INT0(外部中断0)
P3.3 INT1(外部中断1)
P3.4 T0(定时器/计数器0外部输入)
P3.5 T1(定时器/计数器1外部输入)
P3.6 WR(外部数据存储器写脉冲)
P3.7 RD(外部数据存储器读脉冲)
对于8052,P1口的两个引脚也有第二种功能:
P1.0 T2(定时/计数器2外部输入)
P1.1 T2EX(定时/计数器2捕捉/重装入触发)

程序源代码(测试后正确)(注意标红的语句是错误的原因):

#include<reg52.h>
#define unint unsigned int
#define unchar unsigned char
unchar sig,line,role,num;
unchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x58,0x5e,0x79,0x71,0x00};
sbit dula = P2^6;
sbit wela = P2^7;
void delay(unint z)
{
unint x;
for(;z>0;z--)
for(x = 110;x>0;x--);
}
void init()
{
P3 = 0xff;
num = 0;
P0 = 0x00;
dula = 1;
dula = 0;
P0 = 0xc0;
wela = 1;
wela = 0;
SCON = 0x40;
TMOD = 0x20;
}
void send(unchar num)
{
SBUF = num;
while(!TI);
TI = 0;
// TR1 = 0;
}
void selectnum()
{
P3 = 0xf0;
sig = P3;
if(sig!= 0xf0)
{
delay(5);
if(sig!=0xf0)
{
switch(sig)
{
case 0xe0:line =1; break;
case 0xd0:line =2; break;
case 0xb0:line =3; break;
case 0x70:line =4; break;
default:break;
}
P3 = 0x0f;
sig = P3;
switch(sig)
{
case 0x0e: role = 1;TH1 = 0xe8;TL1 = 0xe8;TR1 = 1;break;
case 0x0d: role = 2;TH1 = 0xf4;TL1 = 0xf4;TR1 = 1;break;
case 0x0b: role = 3;TH1 = 0xfa;TL1 = 0xfa;TR1 = 1; break;
case 0x07: role = 4;TH1 = 0xfd;TL1 = 0xfd;TR1 = 1;break;
default: break;
}
num = line+role*4-5;
P0 = table[num];
dula = 1;
dula = 0;
}
P3 = 0x0f;
sig = P3;
while(sig!=0x0f){sig = P3;}
delay(5);
while(sig!=0x0f){sig = P3;}
send(num);
}

}
void main()
{
init();
while(1)
{
selectnum();
}
}

初值改为0x01时:计算机只收到了开关电源时的00.

改为0x02时:只有一排4个按钮能用。

改为0x03时:竟然有两排能用了。

改为0x04时:不出意料的瘫痪(P3.0与P3.1口一定要置为高电平才能正常通信)

改为0x05:瘫痪

0x06:0x03时34排能用,这次23牌能用,我似乎发现了点什么。

0x07:果然:三排能用了

总结一下,发信号时P3.1必须为高电平

0x0a:时24徘可以用

所以这样看来一位管一排而0x0f也正是正常的。

这究竟是为什么呢

经过研究我发现是矩阵键盘本身的硬件关系,4x4矩阵键盘是没有地的,要想松手检测只有将4位赋值为低且同时另四位为高时才能准确地检测是否松手。

所以要想有准确的松手检测只有0x0f可以做到。

以后有用到此类矩阵键盘的时候请记住不论是检测按下还是松手检测时一定要将P3口赋值为0x0f。

posted @ 2016-08-08 14:09  H.S.Q  阅读(1281)  评论(0)    收藏  举报