需要 STC89C52RC的串口收发程序,波特率9600,时钟22.1184MHz
需要 STC89C52RC的串口收发程序,波特率9600,时钟22.1184MHz<p>手册中给出了常用波特率表格,但22.1184MHz下9600波特率的配置需要计算。让我查一下STC89C52RC的12T/6T模式相关信息,确认默认工作模式。</p>
<p>根据手册中的公式:</p>
<p><strong>模式1、3波特率 = 2<sup>SMOD</sup> / 32 × (定时器1的溢出率)</strong></p>
<p>定时器1工作方式2(8位自动重装),12T模式下:<br />
<strong>溢出率 = SYSclk / (12 × (256 - TH1))</strong></p>
<p>对于 22.1184MHz,目标波特率 9600:</p>
<p>若 SMOD=1(波特率加倍):<br />
9600 = 2¹ / 32 × (22,118,400 / (12 × (256 - TH1)))<br />
9600 = 2 / 32 × (22,118,400 / (12 × (256 - TH1)))<br />
9600 = 1/16 × (22,118,400 / (12 × (256 - TH1)))<br />
9600 = 22,118,400 / (192 × (256 - TH1))<br />
256 - TH1 = 22,118,400 / (192 × 9600) = 22,118,400 / 1,843,200 = 12<br />
TH1 = 256 - 12 = 244 = 0xF4</p>
<p>若 SMOD=0(不加倍):<br />
9600 = 2⁰ / 32 × (22,118,400 / (12 × (256 - TH1)))<br />
9600 = 1/32 × (22,118,400 / (12 × (256 - TH1)))<br />
9600 = 22,118,400 / (384 × (256 - TH1))<br />
256 - TH1 = 22,118,400 / (384 × 9600) = 22,118,400 / 3,686,400 = 6<br />
TH1 = 256 - 6 = 250 = 0xFA</p>
<p>两种方案都可行。我选择 SMOD=0、TH1=0xFA 的方案(更常见)。下面给出完整的串口收发程序。</p>
<pre><code class="language-c">/*---------------------------------------------------------------------------*/
/* --- STC89C52RC 串口收发程序 (波特率9600, 时钟22.1184MHz) -------------- */
/* --- 功能: 串口方式1, 定时器1方式2(8位自动重装)产生波特率 --- */
/* --- 接收到的数据原样发送回(回环测试) --- */
/* --- 接线: RXD(P3.0) - TXD(P3.1) 接USB转串口模块 --- */
/* --- 晶振: 22.1184MHz, 12T模式(默认) --- */
/*---------------------------------------------------------------------------*/
#include "reg51.h"
/* 波特率参数: SMOD=0, TH1=0xFA, 9600bps @ 22.1184MHz */
#define RELOAD_VALUE0xFA
/* 缓冲区定义 */
#define RX_BUF_SIZE16
unsigned char rx_buffer; /* 接收缓冲区 */
unsigned char rx_index = 0; /* 接收缓冲区索引 */
unsigned char rx_flag = 0; /* 接收到一帧数据的标志 */
/* 函数声明 */
void UART_Init(void);
void UART_SendByte(unsigned char dat);
void UART_SendString(unsigned char *str);
/*---------------------------------------------------------------------------*/
/* 串口初始化: 9600bps, 方式1, 定时器1方式2 */
/*---------------------------------------------------------------------------*/
void UART_Init(void)
{
/* 配置定时器1: 8位自动重装模式(方式2), 定时器模式 */
TMOD &= 0x0F; /* 清除T1的M1、M0位 */
TMOD |= 0x20; /* 设置T1为方式2 (8位自动重装) */
TH1 = RELOAD_VALUE; /* 设置重装值 */
TL1 = RELOAD_VALUE; /* 设置初值 */
/* 配置串口: 方式1 (8位UART), 允许接收 */
SCON = 0x50; /* SM0=0, SM1=1, REN=1, 方式1 */
/* SMOD=0, 波特率不加倍 (PCON.7=0) */
PCON = 0x00;
TR1 = 1; /* 启动定时器1 */
/* 使能串口中断 */
ES = 1; /* 允许串口中断 */
EA = 1; /* 开总中断 */
}
/*---------------------------------------------------------------------------*/
/* 串口发送一个字节 (查询方式) */
/*---------------------------------------------------------------------------*/
void UART_SendByte(unsigned char dat)
{
SBUF = dat; /* 将数据写入发送缓冲器 */
while (TI == 0); /* 等待发送完成 */
TI = 0; /* 清除发送中断标志 */
}
/*---------------------------------------------------------------------------*/
/* 串口发送字符串 */
/*---------------------------------------------------------------------------*/
void UART_SendString(unsigned char *str)
{
while (*str != '\0')
{
UART_SendByte(*str++);
}
}
/*---------------------------------------------------------------------------*/
/* 串口中断服务函数 */
/*---------------------------------------------------------------------------*/
void UART_ISR(void) interrupt 4
{
unsigned char ch;
if (RI == 1) /* 接收中断 */
{
RI = 0; /* 清除接收中断标志 */
ch = SBUF; /* 读取接收到的数据 */
/* 将接收到的数据存入缓冲区 (防止溢出) */
if (rx_index < RX_BUF_SIZE)
{
rx_buffer = ch;
}
/* 如果收到换行符(0x0A)或回车符(0x0D), 置位接收完成标志 */
if ((ch == '\n') || (ch == '\r'))
{
rx_buffer = '\0';/* 字符串结束符替换换行符 */
rx_flag = 1; /* 置位接收完成标志 */
}
}
if (TI == 1) /* 发送中断 (本程序未使用) */
{
TI = 0; /* 清除发送中断标志 */
}
}
/*---------------------------------------------------------------------------*/
/* 主函数 */
/*---------------------------------------------------------------------------*/
void main(void)
{
unsigned char i;
UART_Init(); /* 初始化串口 */
UART_SendString("STC89C52RC UART Test @ 9600bps, 22.1184MHz\r\n");
while (1)
{
/* 检查是否接收到一帧数据 */
if (rx_flag == 1)
{
rx_flag = 0; /* 清除标志 */
/* 将接收到的数据回显 */
UART_SendString("Received: ");
UART_SendString(rx_buffer);
UART_SendString("\r\n");
/* 清空接收缓冲区 */
for (i = 0; i < RX_BUF_SIZE; i++)
{
rx_buffer = 0;
}
rx_index = 0;
}
}
}
</code></pre>
<hr />
<h3>程序说明</h3>
<p><strong>1. 波特率计算(22.1184MHz,12T模式)</strong></p>
<p>STC89C52RC 默认工作在 <strong>12T模式</strong>(烧录时可在 ISP 软件中设置,此处按默认12T处理)。</p>
<p>公式:<code>波特率 = 2^SMOD / 32 × (SYSclk / (12 × (256 - TH1)))</code></p>
<p>取 SMOD=0(不加倍),代入:</p>
<pre><code>9600 = 1/32 × (22,118,400 / (12 × (256 - TH1)))
9600 = 22,118,400 / (384 × (256 - TH1))
256 - TH1 = 22,118,400 / (384 × 9600) = 6
TH1 = 256 - 6 = 250 = 0xFA
</code></pre>
<p><strong>2. 寄存器配置</strong></p>
<table>
<thead>
<tr>
<th align="left">寄存器</th>
<th align="center">值</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">TMOD</td>
<td align="center">0x20</td>
<td align="left">定时器1方式2(8位自动重装)</td>
</tr>
<tr>
<td align="left">TH1/TL1</td>
<td align="center">0xFA</td>
<td align="left">波特率重装值</td>
</tr>
<tr>
<td align="left">SCON</td>
<td align="center">0x50</td>
<td align="left">方式1(8位UART),允许接收</td>
</tr>
<tr>
<td align="left">PCON</td>
<td align="center">0x00</td>
<td align="left">SMOD=0,波特率不加倍</td>
</tr>
</tbody>
</table>
<p><strong>3. 程序功能</strong></p>
<ul>
<li>上电后串口发送欢迎信息</li>
<li>串口接收数据存入缓冲区,遇到 <code>\n</code> 或 <code>\r</code> 认为一帧结束</li>
<li>将接收到的数据原样回显(回环测试)</li>
</ul>
<p><strong>4. 使用说明</strong></p>
<ul>
<li>晶振使用 <strong>22.1184MHz</strong>(注意不是11.0592MHz)</li>
<li>串口连接:P3.0(RXD) 接 USB转串口模块的 TXD,P3.1(TXD) 接 RXD,GND 共地</li>
<li>串口助手设置为:<strong>9600bps,8数据位,1停止位,无校验</strong></li>
</ul>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&mod=forum&q=STC89C52RC%20%E4%B8%B2%E5%8F%A3%E6%94%B6%E5%8F%91%20%E6%B3%A2%E7%89%B9%E7%8E%879600%2022.1184MHz&f=_all&m=yes&syn=yes&s=relevance&fid=0">🔍 搜索 "STC89C52RC 串口收发 波特率9600 22.1184MHz"</a></p>
<p><strong>📌 相关论坛讨论</strong></p>
<ol>
<li><a href="https://www.stcaimcu.com/forum.php?mod=viewthread&tid=21659&highlight=%E9%9C%80%E8%A6%81%20STC89C52RC%E7%9A%84%E4%B8%B2%E5%8F%A3%E6%94%B6%E5%8F%91%E7%A8%8B%E5%BA%8F%EF%BC%8C%E6%B3%A2%E7%89%B9%E7%8E%879600%EF%BC%8C%E6%97%B6%E9%92%9F22.1184MHz%2C&page=1&extra=#pid199905">【天王归来】STC89C52RC使用专用定时器2做波特率发生器,定时器0做串口接收超时检测!</a></li>
<li>STC89C52RC, T2做波特率发生器,波特率 = 系统时钟/32/(65536 - [RCAP2H,RCAP2L</li>
<li><a href="https://www.stcaimcu.com/forum.php?mod=viewthread&tid=18935&highlight=%E9%9C%80%E8%A6%81%20STC89C52RC%E7%9A%84%E4%B8%B2%E5%8F%A3%E6%94%B6%E5%8F%91%E7%A8%8B%E5%BA%8F%EF%BC%8C%E6%B3%A2%E7%89%B9%E7%8E%879600%EF%BC%8C%E6%97%B6%E9%92%9F22.1184MHz%2C&page=1&extra=#pid175214">图形化配置 STC89C52RC系列各功能模块, 程序框架自动生成, AiCube-ISP-V6.96V</a></li>
</ol>
<p>⏱️ 查找用时 3.8s | 总回答用时 20.6s</p>
让 STC 【AI 助手】自动帮您写你需要的通用MCU程序
STC-ISP最新版软件,AiCube-ISP V6.96Z版内置:
STC 【AiCube】:图形化配置各功能模块外设,自动生成程序;
STC 【AI 助手】:按输入的要求,自动生成程序,
或排查您程序的错误。
STC 【AI 助手】,已加载 STC全系列MCU专业技术手册。
help.stcaimcu.com
可以帮您:
- 回答STC技术手册中的技术问题
- 自动生成您需要的通用MCU程序
- 自动高效排查您程序中的错误
所以只要有 C语言的基础,STC的MCU,你其实已经算能用了,
再用到哪,研究到哪,
让 STC 【AI 助手】帮你研究总结
让 STC 【AI 助手】自动帮您写你需要的通用MCU程序
页:
[1]