单片机波特率自适应
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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);
}