51 单片机模拟串口的问题 目前发送数据没有问题,接收数据时只能接收前两位,如发送010203 只能接收到01

我想实现通过I/O串口连续的接收发送,请指教我的问题出在哪里我用的芯片是STC12C5A60S2,波特率9600/****************************... 我想实现通过I/O串口连续的接收发送,请指教我的问题出在哪里
我用的芯片是STC12C5A60S2,波特率 9600
/***************************************************************
* 在单片机上模拟了一个串口,使用P2.1作为发送端
* 把单片机中存放的数据通过P2.1作为串口TXD发送出去
***************************************************************/
#include <reg51.h>
#include <stdio.h>
#include <string.h>

typedef unsigned char uchar;

int i;
uchar tmpbuf2[64] = {0};//模拟串口接收数据的缓存
sbit newTXD = P2^1;//模拟串口的发送端设为P2.1
sbit newRXD = P3^2;//模拟串口的发送端设为P3.2

struct
{
uchar recv :6 ;//tmpbuf2数组下标,用来将模拟串口接收到的数据存放到tmpbuf2中
uchar send :6 ;//tmpbuf2数组下标,用来将tmpbuf2中的数据发送到串口
}tmpbuf2_point={0,0};

void UartInit()
{
SCON = 0x50; // SCON: serail mode 1, 8-bit UART
TMOD |= 0x21; // T0工作在方式1,十六位定时
PCON |= 0x80; // SMOD=1;

TH0 = 0xff;
TL0 = 0xa0;
IE |= 0x81;
TF0 = 0;
IT0 = 1;
}

void WaitTF0(void)
{

TF0=0;

TH0 = 0xff;
TL0 = 0xa0;

while(!TF0);
TF0 = 0;
}

void WByte(uchar input)
{
//发送启始位
uchar j=8;
TR0=1;
newTXD=(bit)0;
WaitTF0();
//发送8位数据位
while(j--)
{
newTXD=(bit)(input&0x01); //先传低位
WaitTF0();
input=input>>1;
}

//发送校验位(无)

//发送结束位
newTXD=(bit)1;
WaitTF0();

}

uchar RByte()
{
uchar Output=0 ;
uchar i=8 ;
TR0=1 ; //启动Timer0

WaitTF0();//等过起始位
//接收8位数据位
while(i--)
{
Output>>=1 ;
if(newRXD)Output|=0x80 ;//先收低位
WaitTF0();//位间延时
}

// TR0=0 ;//停止Timer0
return Output ;
WaitTF0();
}

void main()
{

UartInit();
while(1)
{

if(tmpbuf2_point.recv!=tmpbuf2_point.send)//差值表示模拟串口接收数据缓存中还有多少个字节的数据未被处理(发送至串口)
{
WByte(tmpbuf2[tmpbuf2_point.send++]);
}
}
}
//外部中断0,说明模拟串口的起始位到来了
void Simulated_Serial_Start()interrupt 0
{
EX0=0 ; //屏蔽外部中断0
tmpbuf2[tmpbuf2_point.recv++]=RByte(); //从模拟串口读取数据,存放到tmpbuf2数组中

//Sendata();
IE0=0 ; //防止外部中断响应2次,防止外部中断函数执行2次
EX0=1 ; //打开外部中断0
}
展开
 我来答
亿亿裬D4e2f
2011-08-10 · 超过11用户采纳过TA的回答
知道答主
回答量:24
采纳率:0%
帮助的人:21.3万
展开全部
我前几天也做模拟串口程序,也遇到了与你类似的问题,不过现在解决了。
数据格式由一个起始位,八个数据位,一个或两个结束位组成。在数据发送是结束位是不能省。
但在数据接收时,程序中就没有必要等待结束位了,因为在等待结束位的过程中,把下一个数据的起始中断也等待过去了。
把函数uchar RByte()中的最后一个WaitTF0();删除,程序就能连续接收数据了。
下面是我的程序,你看一下就明白了。
/*
模拟串口收发程序
改程序发送口采用任一IO口,接收口采用外部中断0口,实现了9600bit/s的串口通信
信号产生与接收采用定时器定时溢出标志来进行控制
注意问题:
1、中断的中断标志要保证状态正确
2、定时器定时要精确
*/

#include<reg52.h>
sbit txd=P3^1;
sbit rxd=P3^2;
sbit en=P1^7;
sbit clk=P3^7;

#define uchar unsigned char

uchar number,flag;
uchar num[10]={0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

void wait(uchar i);
void send(uchar aa);

void main()
{
uchar i;
IE=0;EA=1;
TMOD=0x12;
TR0=0;EX0=1;
IT0=1;en=0;
while(1)
{
if(num[0]==0x49&&num[1]==0x85&&num[2]==0x54&&num[3]==0x31&&num[4]==0x59&&num[5]==0x87&&num[6]==0x91&&num[7]==0x25&&num[8]==0x34&&num[9]==0x62)
{
en=1;
number=0;
for(i=0;i<10;i++)
{send(num[i]);num[i]=0x00;}
en=0;
}
}
}

void send(uchar aa)
{
uchar i;
txd=0;
wait(0xb9);
for(i=0;i<8;i++)
{txd=aa&0x01;aa>>=1;wait(0xb9);}
txd=1;
wait(0xb9);
flag=0;
}

void int0() interrupt 0
{
uchar i;
EX0=0;clk=!clk;
wait(0xad);
for(i=0;i<7;i++)
{
number>>=1;clk=!clk;
if(rxd)number=0x80|number;
else number=0x00|number;
wait(0xb9);
}

number>>=1;clk=!clk;
if(rxd)number=0x80|number;
else number=0x00|number;
wait(0xd9);

num[flag]=number;
flag++;clk=!clk;
IE0=0;EX0=1;
if(flag>=10)flag=0;
}

void wait(uchar i)
{
TF0=0;
TH0=i;TL0=i;
TR0=1;
while(TF0==0);
TF0=0;TR0=0;
}
fishmin2005
2011-08-10 · TA获得超过529个赞
知道小有建树答主
回答量:498
采纳率:0%
帮助的人:425万
展开全部
这个可能还是需要你自己调试。您可以试试一个一个的发,能否全部收到,然后两个两个的发,是否全部收到,然后再三个三个的发,问题可能出在中断上或者数据保存上。您多调试一下吧。希望对你有帮助 by fishmin2005
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2011-08-10
展开全部
建议 去 我的领地 5d6d 的 proteus 论坛看看

那里有很多 单片机仿真实例,包括proteus 仿真图 和 源码
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2011-08-10
展开全部
麻.烦`采纳.··.·`··.
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 3条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式