(声明:本程序是以网上下载程序为根底,并根据需求做了恰当修正得来的)
在用单片机开发各种嵌入式使用体系中,因为异步串行通讯衔接简略,因此成为常常用到的一种通讯形式,许多使用中还要求完结多路异步串行通讯。为了进步体系的性能价格比,就要求规划工程师用软件添加完结一路或多路异步串行通讯。本文便是对模仿串口的波特率做出的一点剖析。
首要简略的介绍一下串行异步通讯的数据格局界说,发送或接纳一个完好的字节信息,必须有“开始位”、“若干数据位”、“奇偶校验位”和“中止位”;界说每位信息的时刻宽度——每秒发送的信息位个数,即为“波特率”。本文顺便的模仿串口源程序选用数据帧的格局为 1位开始位(低电平),8位数据位(先低位在高位),1位中止位(高电平),且在线路闲暇状况时总是坚持为高电平。当在11M晶振时钟频率下,选用波特率为9600或19200时。该模仿串口都能够无差错的进行传输,具体剖析后边进行。
参照源程序,咱们知道,在这个模仿串口规划中,模仿的是单片机串行异步通讯方法1,由P1^0做接纳端,P1^1做发送端,经过守时器1守时溢出中止来确认每位数据的时刻,由StartBitOn()函数不断查询接纳端的状况,当呈现低电平(即开始位)的时分,调用接纳程序,接纳发送的数据。
针对以下顺便的源程序剖析知,PGetChar(),PSendChar()都是经过移位方法来接纳数据,每接纳一位数据,需求守时器溢出发生中止一次,故要得到一帧的数据,就必须经过10个数据位的时刻才干完结,相同的,在模仿串口的发送端,要完好的发送一帧数据也要经过10个数据位的时刻。因此在如下衔接时,引出了以下的问题。
当RS232单次发送一个字符时,能够正常接纳和发送回RS232。
当RS232接连发送一串字符时,经过模仿串口回来给RS232的字符只要本来的一半。如发送1234567890这样一个字符串时,接纳的字符为13579。
那为什么在独自发送一个字符是不会丢掉,而接连发送时就只要本来的一半了呢!
__________________________________________
||||
||||
| PC|———->| PGetChar()|
|RS232|||MCU|
|||V|
||<----------| PSendChar()|
——————————————–
源程序:
/**********************************************
IO 口模仿232串行异步通讯程序
**********************************************/
#include
sbit BT_SND =P1^1;
sbit BT_REC =P1^0;
#define F_TM F0//自界说标志位,作为中止标志位
#define TIMER0_ENABLETL0=TH0; TR0=1;//TR0 = 1,发动T
#define TIMER0_DISABLE TR0=0;
// 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;
}
//发送一个字符
//数据格局一个发动位(0),8数据位,一个中止位(1)
void PSendChar(unsignedCHARGetch)
{
ACC=Getch;
F_TM=0;
BT_SND=0; //发动位
TIMER0_ENABLE; //记数器0发动
while(!F_TM) ;
BT_SND=ACC0; //先送出低位
F_TM=0;
while(!F_TM) ;
BT_SND=ACC1;
F_TM=0;
while(!F_TM);
BT_SND=ACC2;
F_TM=0;
while(!F_TM);
BT_SND=ACC3;
F_TM=0;
while(!F_TM);
BT_SND=ACC4;
F_TM=0;
while(!F_TM);
BT_SND=ACC5;
F_TM=0;
while(!F_TM);
BT_SND=ACC6;
F_TM=0;
while(!F_TM);
BT_SND=ACC7;
F_TM=0;
while(!F_TM);
BT_SND=1;
F_TM=0;
while(!F_TM);
TIMER0_DISABLE; //中止timer
}
//接纳一个字符
unsignedCHARPGetChar()
{
unsignedCHARrch,ii;
TIMER0_ENABLE;
F_TM=0;
ii=0;
rch=0;
while(!F_TM); //等过开始位
while(ii<8)
{
rch>>=1;
if(BT_REC)
{
rch|=0x80;
}
ii++;
F_TM=0;
while(!F_TM);
}
F_TM=0;
while(!F_TM)
{
if(BT_REC)
{
break;
}
}
TIMER0_DISABLE; //中止timer
return rch;
}
//查看是不是有开始位
bit StartBitOn()
{
return(BT_REC==0);
}
void main()
{
unsignedCHARGetch;
TMOD=0x22; /*守时器1为作业形式2(8位主动重装),0为形式2(8位
主动重装) */
PCON=00;
TR0=0; //在发送或接纳才开始使用
TF0=0;
TH0=(256-96); //9600bps 便是 1000000/9600=104.167微秒 履行的
//时刻是104.167*11.0592/12= 96
TL0=TH0;
ET0=1;//守时器/记数器T0的溢出中止答应位,ET,允 许中止
EA=1;
while(1)
{
if(StartBitOn())
{
Getch=PGetChar();
PSendChar(Getch);
}
}
}
试验环境:
串口调试帮手软件
AT89S51单片机及相应的硬件设备