模拟串口函数,发正常,收只能收到一半
#include <reg52.h>
#define uchar unsigned char
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
sbit A1 = P2^0;
#define RXD P1_0
#define TXD P1_1
#define WRDYN 44 //写延时
#define RDDYN 43 //读延时
void Delay2cp(unsigned char i);
void WaitTF0( void );
void SPI2int();
void WByte(uchar);
void RByte(uchar);
void SendStr(unsigned char *s)
#define TM0_FLAG P1_2 //设传输标志位
//计数器及中断初始化
void SPI2int(void)
{
TMOD |=0x02; //计数器0,方式2
TH0=0xA0; //预值为256-96=140,十六进制A0
TL0=TH0;
TR0=0; //在发送或接收才开始使用
TF0=0;
ET0=1; //允许定时器0中断
EA=1; //中断允许总开关
}
//发送一个字符
void WByte(uchar input)
{
//发送启始位
uchar i=8;
TR0=1;
TXD=(bit)0;
WaitTF0();
//发送8位数据位
while(i--)
{
TXD=(bit)(input&0x01); //先传低位
WaitTF0();
input=input>>1;
}
//发送校验位(无)
//发送结束位
TXD=(bit)1;
WaitTF0();
TR0=0;
}
//接收一个字符
uchar RByte()
{
uchar Output=0;
uchar i=8;
TR0=1; //启动Timer0
TL0=TH0;
WaitTF0(); //等过起始位
//发送8位数据位
while(i--)
{
Output >>=1;
if(RXD)
Output |=0x80; //先收低位
WaitTF0(); //位间延时
}
while(!TM0_FLAG) if(RXD) break;
TR0=0; //停止Timer0
return Output;
}
//中断1处理程序
void IntTimer0() interrupt 1
{
TM0_FLAG=1; //设置标志位。
}
//查询传输标志位
void WaitTF0( void )
{
while(!TM0_FLAG);
TM0_FLAG=0; //清标志
}
//检查是不是有起始位
bit StartBitOn()
{
return (RXD==0);
}
void main()
{
uchar ccc;
SPI2int();
TM0_FLAG=0;
//测试1
/*
WByte(0x03);
WByte(0x01);
WByte(0x02);
WByte(0x03);
WByte(0x04);
WByte(0x05);
while(1){;}
*/
//测试2
WByte(0x03);
while(1)
{
if(StartBitOn())
{
ccc=RByte();
WByte(ccc);
}
}
//测试3
/*
while(1)
{
if(StartBitOn())
{
ccc=RByte();
WByte(ccc);
}
}
*/
}
//毫秒级延时函数
void Delay_ms( unsigned char x_ms )
{
unsigned int i,j;
for(i=x_ms;i>0;i--)
for(j=110;j>0;j--);
}
//发送字符串
void SendStr(unsigned char *s)
{
while(*s != '\0') //检测是否字符串末尾, '\0'表示字符串结束标志,
{
WByte(*s);
s++;
}
}
发送正常,收的话,就只能收到一半数据,比如我用串口精灵发送1234567,就只能收到1357.发送123456就只能收到135。。
[解决办法]
原因很简单啦,因为你的程序不是全双工的(full duplex),而你又加了收到字符回送功能,程序每收到一个字符就忙着回送了,自然顾不上接收下一个了。改成能同时收发比较麻烦,不如简单点先存在缓冲区,加一个结束字符比如'\0',当收到结束字符时再回送
[解决办法]
\0一般用作字符串结尾,通常在程序中不会发送。你要想实现,就在加一个计数,一定时间内没有新数据送到,就去发送