找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

AT89S52中如何用P1^1端口既发送数据又接收数据

[复制链接]
admin 发表于 2012-9-2 09:26:43 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
我的发送和接收只能用P1^1来模拟(硬件已经定型了,无法改变),我的程序是这样的:
#include "my_s52.h"
#include <at89s52.h>

sbit ESPU_RST=P1^0;
sbit ESPU_DATA=P1^1;
bit ESPU_DATAIN;

// Acc 累加器做发送的移位寄存器
sbit ACC0= ACC^0;
sbit ACC1= ACC^1;
sbit ACC2= ACC^2;
sbit ACC3= ACC^3;
sbit ACC4= ACC^4;
sbit ACC5= ACC^5;
sbit ACC6= ACC^6;
sbit ACC7= ACC^7;

//定时器计数器0的中断
void IntTimer0() interrupt 1
{
F_TM=1;
}


//***************** 延时x毫秒函数 ***********
void Delay(int count)
{
int i;
int j;
for(i=0;i<count;i++)
{
for(j=0;j<230;j++);
{
;
}
}
}


void init_ESPU(void)
{ ////计数器0,方式2
TMOD=0x02; //定器1为工作模式2(8位自动重装),0为模式2(8位自动重装)

PCON=00; //为电源控制
//定时器 、寄存器工作
TR0=1; //在发送或接收才开始使用
TF0=0; //定时器0从1开始计数,当数据溢出时,由TF0通知S52中断
/*
TH0=(256-96); //9600bps 就是 1000000/9600=104.167微秒 执行的

// timer是104.167*11.0592/12= 96

TL0=TH0;
设置周期为 1/9600 ,单片机晶振为 12M,则,根据计算有 :
(2^16-x)*(12/单片机晶振频率)=((10^6)/9600)
这里ESPU的波特率正好也为9600HZ,与此相对应
*/
TH0=0xFF;
TL0=0x98;
ET0=1; //允许定时器0中断
EA=1; //中断允许总开关
}

//ESPU复位
//端口1为输入,0为输出 ,默认为输出
void ESPU_Rst(void)
{
ESPU_RST=1;
Delay(100);

ESPU_RST=0;
Delay(100);

ESPU_RST=1;
Delay(100);
}

//设置为输出
void PSend(void)
{
ESPU_DATA=0;
}

//设置为输入
void PRev(void)
{
P1_1=1;
ESPU_DATAIN=P1_1;
P1_1=0;
}

/*
异步通讯一般都是0为起始位,1为结束位
*/
//发送一个字符
void PSendChar(Uint8 inch)
{
ACC=inch;
F_TM=0;

PSend(); //start bit,设置为输出

TIMER0_ENABLE; //启动
while(!F_TM);
ESPU_DATA=ACC0; //先送出低位

F_TM=0;
while(!F_TM);
ESPU_DATA=ACC1;

F_TM=0;
while(!F_TM);
ESPU_DATA=ACC2;

F_TM=0;
while(!F_TM);
ESPU_DATA=ACC3;

F_TM=0;
while(!F_TM);
ESPU_DATA=ACC4;

F_TM=0;
while(!F_TM);

ESPU_DATA=ACC5;
F_TM=0;
while(!F_TM);

ESPU_DATA=ACC6;
F_TM=0;
while(!F_TM);
ESPU_DATA=ACC7;

F_TM=0;
while(!F_TM);
ESPU_DATA=1;//结束

F_TM=0;
while(!F_TM);

TIMER0_DISABLE; //停止timer
}

//发送多个字符节序
void PSendNum(Uint8 *ptemp,Uint8 num)
{
int i;
for(i=0;i<num;i++)
{
PSendChar((Uint8)0xff&(*(ptemp+i)));
}
}

//接收单个字节
Uint8 PGetChar()
{
TIMER0_ENABLE;

F_TM=0;
while(!F_TM); //等过起始位
ACC0=ESPU_DATAIN;
TL0=TH0;

F_TM=0;
while(!F_TM);
ACC1=ESPU_DATAIN;

F_TM=0;
while(!F_TM);
ACC2=ESPU_DATAIN;

F_TM=0;
while(!F_TM);
ACC3=ESPU_DATAIN;

F_TM=0;
while(!F_TM);

ACC4=ESPU_DATAIN;
F_TM=0;
while(!F_TM);

ACC5=ESPU_DATAIN;
F_TM=0;
while(!F_TM);

ACC6=ESPU_DATAIN;
F_TM=0;
while(!F_TM);

ACC7=ESPU_DATAIN;
F_TM=0;
while(!F_TM)
{
if(ESPU_DATAIN)
{
break;
}
}

TIMER0_DISABLE; //停止timer
return ACC;
}

//检查是不是有起始位
bit StartBitOn()
{
return (ESPU_DATAIN==0);

}
//多个字节的接收
void PRevNum(Uint8 *ptemp,Uint8 num)
{
int i;
PRev();//输入端设置
for(i=0;i<num;i++)
{
while(StartBitOn()!=0); //检测起始位
*(ptemp+i)=(Uint8)PGetChar();
}
}

我的硬件只能用P1^1口来发送和接收。测试发现发送没问题,但接收的数据都是0xFF,希望高手能帮我找找原因,谢谢!
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-24 12:49 , Processed in 0.057408 second(s), 10 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表