STC单片机11.0592晶振实现115200波特率串口通信

本文介绍了如何在STC12C5A60S2单片机上轻松实现115200波特率的串口通信,通过设置波特率发生器和相关寄存器,使得高速通信变得简单。

在8051系列单片机如:89S51、89C51 这些单片机上,用11.0592M晶振实现115200波特率通信,几乎是不可能的。

如果换了STC单片机,例如在STC12C5A60S2实现115200的高速通信就相当简单了。

因为,STC12单片机有独立的波特率发生器。

#include "STC12C5A60S2.H"
#include "stdio.h"

void init_uart()
{

PCON &= 0x7f;//波特率不倍速
SCON = 0x50;//8位数据,可变波特率
BRT = 0xFD; //设定独立波特率发生器重装值
AUXR |= 0x04;//独立波特率发生器时钟为Fosc,即1T
AUXR |= 0x01;//串口1选择独立波特率发生器为波特率发生器
AUXR |= 0x10;//启动独立波特率发生器
}

char putchar (unsigned char i)
{

ES = 0; //关串口中断
TI = 0; //清零串口发送完成中断请求标志
SBUF = i;
while(TI ==0); //等待发送完成
TI = 0; //清零串口发送完成中断请求标志
ES = 1; //允许串口中断

return SBUF;
}

记得头文件加上 stdio.h,然后在代码里实现 putchar 函数,这样你就可以很方便的用 printf函数进行串口输出了。

例如

int hh=0,mm=0,ss=0;

printf("现在的时间:%d:%d:%d\r\n", hh,mm,ss);

是不是串口输出变简单多了。

<think>嗯,用户想在51单片机上使用11.0592MHz晶振进行串口通信,并设置波特率为4800。我得先回顾一下相关的知识,确保给出的配置和代码正确。 首先,根据引用资料,51单片机使用11.0592MHz晶振主要是为了波特率准确。比如,当需要高波特率时,如9600,11.0592MHz能避免误差,而12MHz会有问题。那用户需要的是4800波特率,可能同样需要精确配置。 接下来,波特率的计算方式。根据引用[4],波特率的计算涉及定时器T1的溢出率和SMOD位。公式是:波特率 = (2^SMOD / 32) × (晶振频率 / (12 × (256 - TH1)))。这里用户需要的是4800,所以得代入数值计算TH1的初始值。 假设用户使用方式1或3,这两种方式下波特率由定时器T1控制。通常定时器T1设置为模式2,即8位自动重装。这时候需要计算TH1的值。代入公式: 4800 = (2^SMOD / 32) × (11.0592MHz / (12 × (256 - TH1))) 先考虑SMOD位的设置。通常SMOD置1可以增加波特率,但可能这里需要看看哪种情况下能得到整数解。假设SMOD=0,计算: 4800 = (1/32) × (11059200 / (12 × (256 - TH1))) 两边乘以32,得到4800*32 = 11059200/(12*(256-TH1)) 计算左边:4800*32=153600 右边:11059200/12=921600,所以921600/(256-TH1)=153600 解方程:(256-TH1)=921600/153600=6 → TH1=256-6=250=0xFA 这时候TH1=0xFA,也就是十进制的250。那这样算的话,当SMOD=0时,TH1=250,就能得到准确的4800波特率。那这样是否正确? 不过根据引用[4]的例子,当使用11.0592MHz时,9600波特率对应的TH1是0xFD(253),SMOD可能设为1。那在4800的情况下,是否可以通过调整SMOD来得到不同的分频? 假设SMOD=1,那么公式变为: 4800 = (2^1 /32) × (11.0592e6/(12*(256-TH1))) 即:4800 = (2/32) × (11059200/(12*(256-TH1))) 简化右边:2/32=1/16,所以: 4800 = (11059200)/(16*12*(256-TH1)) → 4800 = 11059200/(192*(256-TH1)) 计算右边分母:192*(256-TH1) = 11059200/4800 = 2304 → 256-TH1=2304/192=12 → TH1=256-12=244=0xF4 这时,TH1=0xF4,SMOD=1。那这时候得到的波特率是否准确?因为11.0592MHz的晶振是否能整除? 这时候计算一下: 晶振频率是11.0592MHz,除以12得到定时器的时钟频率,即921600Hz。定时器T1的溢出率是921600/(256-TH1)。当TH1=244,256-244=12,所以溢出率是921600/12=76800Hz。然后波特率是溢出率乘以2^SMOD /32。当SMOD=1时,2^1=2,所以波特率=76800 * 2 /32 =76800*0.0625=4800。是的,这样计算是对的。所以当SMOD=1时,TH1=0xF4,得到4800波特率。 不过,用户可能用的是传统的配置方式,比如是否通常将SMOD置为1?或者是否有其他考虑? 另外,根据引用[3],方式1和3的波特率由定时器T1产生,所以需要配置T1为模式2(自动重装)。所以定时器T1的模式需要设置为2,即8位自动重装模式。 所以,步骤应该是: 1. 设置串口工作模式(方式1或3),这里假设是方式1。 2. 配置定时器T1为模式2(自动重载)。 3. 计算TH1的值,这里根据上面两种情况,SMOD=0时TH1=0xFA,SMOD=1时TH1=0xF4。但是哪种更常用? 比如,在引用[2]中提到,使用9600波特率时,晶振11.0592MHz,所以可能SMOD被设置为1,这样TH1=0xFD,如引用[4]的例子。同样的,对于4800波特率,可能有两种配置方式:SMOD=1时TH1=0xF4,或者SMOD=0时TH1=0xFA。 现在需要确定哪种更合适。假设用户希望波特率误差最小,应该选择正确的SMOD和TH1的组合。例如,当SMOD=1,TH1=0xF4,这样计算得到的波特率正好是4800,无误差。而如果SMOD=0,TH1=0xFA,是否也准确? 代入SMOD=0的情况: 波特率 = (1/32) * (11059200/(12*(256-250))) = (1/32)*(11059200/(12*6)) = (1/32)*(11059200/72) = (1/32)*153600= 4800。同样准确。所以两种方式都可以得到准确的波特率,但需要SMOD位不同,TH1值不同。 这时候应该选择哪种配置?可能取决于具体的单片机设置。例如,PCON寄存器中的SMOD位,默认是0。如果用户想要更高的波特率,可能需要设置SMOD=1。但对于4800来说,两种方式都可行,但不同的TH1值。 这个时候可能需要看常见的配置方式。例如,当波特率较低时,可能更倾向于使用SMOD=0,这样TH1的值较大,可能更常见。或者需要根据具体的单片机手册推荐的方式。 不过,根据引用[4]中的例子,当SMOD=1时,使用11.0592MHz晶振可以得到准确的9600波特率。同样的,在4800的情况下,通过不同的SMOD设置也可以得到准确的值。所以用户可以选择其中一种配置方式。例如,如果用户希望代码更简洁,可能选择SMOD=0,这样不需要修改PCON寄存器中的SMOD位(默认是0),只需要配置TH1为0xFA即可。 但根据计算,两种情况都能得到准确的波特率。所以需要明确说明两种情况,并给出示例代码。 接下来,代码实现部分。需要初始化串口和定时器T1。步骤包括: - 设置串口工作模式:SCON寄存器。方式1是8位UART,波特率可变,所以SCON应设为0x50(即SM0=0,SM1=1,REN=1允许接收)。 - 定时器T1设为模式2:TMOD寄存器,高四位用于定时器1,所以需要将TMOD的高四位设置为0010(即模式2),而低四位可能用于定时器0,假设不影响,所以TMOD=0x20。 - 设置TH1的值,根据之前的情况,比如0xFA或0xF4,取决于SMOD的设置。 - 设置PCON中的SMOD位:如果使用SMOD=1,则PCON |= 0x80;否则保持默认0x00。 - 启动定时器T1:TR1=1。 所以,代码的大致结构是: void UART_Init() { SCON = 0x50; // 方式1,允许接收 TMOD = 0x20; // 定时器1模式2 TH1 = 0xFA; // 波特率4800,SMOD=0 // PCON &= 0x7F; // SMOD=0(默认) TR1 = 1; // 启动定时器1 } 或者当SMOD=1时: void UART_Init() { SCON = 0x50; // 方式1,允许接收 TMOD = 0x20; // 定时器1模式2 TH1 = 0xF4; // 波特率4800,SMOD=1 PCON |= 0x80; // SMOD=1 TR1 = 1; // 启动定时器1 } 这两种方式都能得到准确的4800波特率。用户可以根据需要选择其中一种配置。 需要检查引用资料是否正确支持这些计算。例如,引用[4]中的例子显示,当晶振11.0592MHz时,TH1=0xFD(253)和SMOD=1可以得到准确的9600波特率。同样的逻辑适用于4800波特率。 另外,引用[3]提到,方式1和3的波特率由定时器T1的溢出率决定,所以必须配置T1为模式2,即自动重装模式,这与上面的配置一致。 所以,用户的问题可以回答为两种配置方式,并提供相应的代码示例。需要注意是否需要设置SMOD位,并说明两种方法的可行性。 最后,生成相关问题,比如关于误差分析、其他波特率的配置、或者不同晶振的影响等。</think>### 51单片机使用11.0592MHz晶振实现串口通信波特率4800)配置教程 #### 一、配置原理 1. **晶振选择**:11.0592MHz晶振可精准生成标准波特率(如4800、9600),避免通信误差[^1]。 2. **波特率公式**: 波特率计算公式为: $$ \text{波特率} = \frac{2^{\text{SMOD}}}{32} \times \frac{f_{\text{osc}}}{12 \times (256 - \text{TH1})} $$ 其中: - $f_{\text{osc}}$ = 11.0592MHz - $\text{TH1}$为定时器T1的初值 - $\text{SMOD}$为波特率倍速位(位于PCON寄存器)[^4]。 3. **TH1计算**: 对于4800波特率,选择$\text{SMOD}=0$或$\text{SMOD}=1$均可实现零误差: - **$\text{SMOD}=0$时**:$\text{TH1} = 250$(0xFA) - **$\text{SMOD}=1$时**:$\text{TH1} = 244$(0xF4)[^4]。 --- #### 二、配置步骤 1. **设置串口模式**:选择**工作方式1**(8位UART,波特率可变),对应`SCON = 0x50`。 2. **配置定时器T1**: - 模式选择:**模式2**(8位自动重装),对应`TMOD = 0x20`。 - 初值加载:根据$\text{SMOD}$选择$\text{TH1}$值。 3. **设置SMOD位**:通过`PCON`寄存器控制,默认$\text{SMOD}=0$,若需$\text{SMOD}=1$则需手动置位。 4. **启动定时器**:执行`TR1 = 1`启动T1。 --- #### 三、示例代码(C语言) ##### 方案1:SMOD=0(默认配置) ```c #include <reg52.h> void UART_Init() { SCON = 0x50; // 方式1,允许接收(REN=1) TMOD = 0x20; // 定时器T1设为模式2(自动重装) TH1 = 0xFA; // 波特率4800(SMOD=0) PCON &= 0x7F; // 确保SMOD=0(默认值,可省略) TR1 = 1; // 启动定时器T1 } void main() { UART_Init(); while(1); } ``` ##### 方案2:SMOD=1(倍速模式) ```c #include <reg52.h> void UART_Init() { SCON = 0x50; // 方式1,允许接收(REN=1) TMOD = 0x20; // 定时器T1设为模式2 TH1 = 0xF4; // 波特率4800(SMOD=1) PCON |= 0x80; // SMOD=1(波特率倍速) TR1 = 1; // 启动定时器T1 } void main() { UART_Init(); while(1); } ``` --- #### 四、验证说明 - **误差分析**:两种方案均基于公式推导,波特率误差为0。 - **适用范围**:适用于51单片机(如STC89C52)的UART通信,如与PC串口助手、传感器模块交互等[^2][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值