/***************************************************************
* 模拟接收程序,这个程序的作用从模拟串口接收数据,然后将这些数据发送到实际串口
* 在单片机上模拟了一个串口,使用P3.2作为发送和接收端
* 以P3.2模拟串口接收端,从模拟串口接收数据发至串口
***************************************************************/
#include<reg51.h>
#include<stdio.h>
#include<string.h>
typedef unsigned char uchar ;
uchar tmpbuf2[64]={0};
//用来作为模拟串口接收数据的缓存
struct
{
uchar recv :6;//tmpbuf2数组下标,用来将模拟串口接收到的数据存放到tmpbuf2中
uchar send :6 ;//tmpbuf2数组下标,用来将tmpbuf2中的数据发送到串口
}
tmpbuf2_point={0,0};
sbit newRXD=P3^2 ;//模拟串口的接收端设为P3.2
void UartInit()
{
SCON=0x50 ;// SCON: serail mode 1, 8-bit UART
TMOD|=0x21 ;// TMOD: timer 1, mode 2, 8-bit reload,自动装载预置数(自动将TH1送到TL1);T0工作在方式1,十六位定时
PCON|=0x00 ;// SMOD=0
TH1=0xFD ;// Baud:9600 fosc=11.0592MHz 9600bps为从串口接收数据的速率
TL1=0xFD ;// 计数器初始值,fosc=11.0592MHz 因为TH1一直往TL1送,所以这个初值的意义不大
TH0=0xFF ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz
TL0=0xA0 ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz
IE|=0x81 ;// 中断允许总控制位EA=1;使能外部中断0
TF0=0 ;
IT0=1 ;// 设置外部中断0为边沿触发方式
TR1=1 ;// 启动TIMER1,用于产生波特率
}
void WaitTF0(void)
{
while(!TF0);
TF0=0 ;
TH0=0xFF ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
TL0=0xA0 ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
}
//接收一个字符
uchar RByte()
{
uchar Output=0 ;
uchar i=8 ;
TR0=1 ; //启动Timer0
TH0=0xFF ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
TL0=0xA0 ;// 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz
TF0=0 ;
WaitTF0();//等过起始位
//接收8位数据位
while(i--)
{
Output>>=1 ;
if(newRXD)Output|=0x80 ;//先收低位
WaitTF0();//位间延时
}
TR0=0 ;//停止Timer0
return Output ;
}
//向COM1发送一个字符
void SendChar(uchar byteToSend)
{
SBUF=byteToSend ;
while(!TI);
TI=0 ;
}
void main()
{
UartInit();
while(1)
{
if(tmpbuf2_point.recv!=tmpbuf2_point.send)//差值表示模拟串口接收数据缓存中还有多少个字节的数据未被处理(发送至串口)
{
SendChar(tmpbuf2[tmpbuf2_point.send++]);
}
}
}
//外部中断0,说明模拟串口的起始位到来了
void Simulated_Serial_Start()interrupt 0
{
EX0=0 ; //屏蔽外部中断0
tmpbuf2[tmpbuf2_point.recv++]=RByte(); //从模拟串口读取数据,存放到tmpbuf2数组中
IE0=0 ; //防止外部中断响应2次,防止外部中断函数执行2次
EX0=1 ; //打开外部中断0
}
用以上的程序模拟P3.2作为接收串口,用两个开发板,一个用来发数据,一个用来接收(用模拟的3.2口),接收的这个和电脑相连,数据可以显示,但都是发送数据的2倍,,大家看看哪里程序出问题了?
此帖出自
小平头技术问答
[ 本帖最后由 skyflysgs 于 2011-8-11 19:24 编辑 ]
//接收8位数据位
while(i--)
{
Output>>=1 ;
if(newRXD)Output|=0x80 ;//先收低位
WaitTF0();//位间延时
}
这里应该先收低位再移位(Output>>=1 ; )吧?
if(newRXD)Output|=0x80 ;//先收低位
这是什么意思》?如果newrxd=1,Output|=0x80 ....怎么就先接低位了呢?这是网上找了个程序改的,这一句看不懂啊!
试了一下,果然对了,,,谢谢你
一周热门 更多>