单片机波特率自适应

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机从机的波特率自适应设置

一、硬件原理图

说明:DB9接到PC机的串口上。晶体震荡器可以用诸如11.0592MHz,14.7456MHz,对本文的介绍没有影响等等。这里,单片机为机为,PC机为主机。

二、自动设置理论原理

AT89C52的串行口有4种工作方式,方式1、3最常用。T2的波特率发生方式类似于常数自动重装入方式。用X16代替(RCAP2H,RCAP2L),则串行口方式1、3的波特率公式为:

波特率=fosc/[32 x (65536-X16 )]..……………………..……..…(A)

由(A)可得,单片机每接收1bit需要的时间为

接受1bit的时间=[32 x (65536- X16 )]/ fosc……………………(B)

单片机A T89C52为12分频指令系统,所以其机器周期为:

机器周期= 12/fosc……………………………………….….….……(C )

我们可以很容易得到单片机接收1bit所需要的机器周期,假定为NUM,则由(B),(C)得NUM x 12/ fosc=[32 x (65536- X16)]/ fosc…………………………...(D)

由(D)可得,波特率定时时间常数为:

X16=NUM x 3/8……………………………….…………………….….(E)

由此,关键需要得到单片机接受1 bit的机器周期数NUM。

三、自动检测主机信息的方法

不失一般性,假定串行通讯的字符协议为1起始位,8数据位,无奇偶校验位,1停止位,如下(图2)所示,

由定时器2工作原理(图3)知道,C/T2=0,TR2=0,则其加1计数,其计数速率为fosc/12,每加1需要的时间等于12/fosc,刚好就是一个机器周期。所以,只要我们在传输数据的某位开始处启动定时器,在传输该位结束时停止计数器,然后获取该范围的计数值,就是我们上面公式(E)中的NUM。

(定时器2工作原理,图3)

由图2知,如果主机(PC机)发给单片机01H(十六进制),则单片机P3.0接收数据如下波形(图4)。起始位开始时,启动定时器T2,当高电平来到时,关闭定时器T2,则计数值就等于NUM。

四、软件实现

1.流程图

这里给出获取定时常数的流程图,按主机发0x01来设计的

获取8bit数据的定时计数值(图5)计算定时时间常数(图6)

2.实现该方法的软件源代码

说明:本软件包括C51和汇编两部分

字符协议:1起始位,8数据位,无奇偶校验位,1停止位;//-----汇编部分

;//-----文件名:Yasm.asm

;//------日期:2002.12.1

public GetBitPara

proc segment code

rseg proc

TR2 BIT 0CAH

T2CON EQU 0C8H

RCAP2H EQU 0CBH

RCAP2L EQU 0CAH

TH2 EQU 0CDH

TL2 EQU 0CCH

GetBitPara:

CLR TR2 ; 停止定时器T2

MOV SCON,#00h

MOV IE,#00H

CLR TR2

MOV T2CON,#00h

MOV TH2,#0 ;设置定时器初始值

MOV TL2,#0

MOV RCAP2H,#0

MOV RCAP2L,#0

SETB RXD

JB RXD,$ ;等待起始位

SETB TR2 ;开启定时器T2

JNB RXD,$ ;等待第1bit到来

CLR TR2 ;停止定时器T2

MOV R6,TH2 ;返回计数值

MOV R7,TL2 ;

RET

END

////////////////////////////////////////////////////////////////////////////////////// //-----C51部分

//-----文件名:AutoTest.c

//------日期:2002.12.1

//------要求:PC机器发给单片机的信息数据M必须满足:M & 0x01==0x01,

// 即保证其最低位为1,这样,从开始位到第一位之间就等于1bit的间隔。

#include

extern unsigned int GetBitPara();

/////////////////////////////////////////////////////////////////////////////////// // (BitPara)*12/晶振频率=BitTime....................(!)

// 波特率= 晶振频率/(32*(65536 - [RCAP2H,RCAP2L]))

// (32*(65536 - [RCAP2H,RCAP2L]))/晶振频率=BitTime...(!!)

// (!),(!!)=====>

// 32*(65536 - [RCAP2H,RCAP2L])=BitPara*12

// [RCAP2H,RCAP2L]=65536-BitPara*12/32

// [RCAP2H,RCAP2L]=65536-BitPara*3/8

unsigned int GetT2Const()

{

unsigned int BitPara=0;

unsigned long temp1=0,temp2=0;

BitPara=GetBitPara();

temp1=(BitPara)*3;

temp2=(unsigned int)(temp1>>3);

if(temp1-(temp2<<2)>=4)temp2++;//四舍五入

return (65536-temp2);

}

相关文档
最新文档