好的,信息已经查全了。现在我来给这位用户提供一个完整的 STC8H2K32U 串口1(P3.0/P3.1)打印例程。
STC8H2K32U 串口1(P3.0/P3.1)打印例程
您好!第一次使用 STC 芯片遇到串口打印问题很常见,我来帮您分析并提供可直接编译运行的例程。
常见失败原因排查
在给出代码之前,先排查几个最容易出问题的地方:
- P3.0/P3.1 默认就是串口1的 RxD/TxD,无需切换功能脚(S1_S[1:0]=00 即为默认值)
- STC8H2K32U 上电后 P3.0/P3.1 为弱上拉/准双向口模式,可直接用于串口通信
- 串口1的波特率发生器可以选择定时器1或定时器2,推荐用定时器2(更简单)
- ISP下载时选择的IRC频率必须与代码中一致,您选24MHz,代码中也要用24MHz
完整例程代码
/*
* STC8H2K32U 串口1 (P3.0/P3.1) 打印例程
* 时钟:内部IRC 24MHz
* 波特率:115200
* 串口模式:模式1(8位UART,可变波特率)
* 波特率发生器:定时器2(1T模式)
*
* 使用说明:
* 1. 在ISP下载软件中,设置内部IRC频率为 24MHz
* 2. 将本代码编译后下载到芯片
* 3. 用USB转串口工具连接:P3.0(RxD)接对方TxD,P3.1(TxD)接对方RxD,GND接GND
* 4. 打开串口助手,设置波特率115200,数据位8,停止位1,无校验
* 5. 上电或复位后,串口助手将收到 "STC8H2K32U UART1 Test OK!\r\n"
*/
#include "stc8h.h"
#include "intrins.h"
// 函数声明
void UART1_Init(void);
void UART1_SendByte(unsigned char dat);
void UART1_SendString(unsigned char *str);
void main(void)
{
unsigned char i;
// 使能访问XFR(扩展寄存器区域)
P_SW2 |= 0x80;
// 设置所有I/O口为准双向口(默认模式)
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
// 初始化串口1,波特率115200,时钟24MHz
UART1_Init();
// 发送测试字符串
UART1_SendString("STC8H2K32U UART1 Test OK!\r\n");
// 循环发送递增数字,验证通信
i = 0;
while(1)
{
UART1_SendString("Count: ");
UART1_SendByte('0' + i); // 发送数字字符(0~9循环)
UART1_SendString("\r\n");
i++;
if(i > 9) i = 0;
// 延时约1秒(粗略延时)
{
unsigned int j, k;
for(j = 0; j < 1000; j++)
for(k = 0; k < 1200; k++);
}
}
}
/*
* 串口1初始化函数
* 使用定时器2作为波特率发生器
* 模式1(8位UART),波特率115200
* 时钟频率:24MHz
*
* 波特率计算公式(定时器2,1T模式):
* 波特率 = SYSclk / 4 / (65536 - RL)
* 115200 = 24000000 / 4 / (65536 - RL)
* RL = 65536 - 24000000 / 4 / 115200
* RL = 65536 - 52.08 ≈ 65536 - 52 = 65484 = 0xFFCC
*/
void UART1_Init(void)
{
// 配置串口1控制寄存器
SCON = 0x50; // 模式1(8位UART),允许接收(REN=1)
// 配置定时器2为波特率发生器
// 定时器2的寄存器在XFR区域,需要先使能访问
P_SW2 |= 0x80; // 使能访问XFR(如果之前已使能可省略)
// 选择定时器2作为串口1的波特率发生器
AUXR &= ~0x01; // S1ST2 = 0 选择定时器1... 不对,查手册:
// AUXR.0 (S1ST2) = 1 选择定时器2作为波特率发生器
AUXR |= 0x01; // S1ST2 = 1,选择定时器2作为串口1波特率发生器
// 配置定时器2:1T模式,自动重装载
AUXR |= 0x10; // T2x12 = 1,定时器2为1T模式(12倍速)
AUXR |= 0x04; // T2R = 1... 先设置重装值再启动
// 设置定时器2重装载值
// 24MHz,115200波特率,1T模式
// 重装值 = 65536 - 24000000 / 4 / 115200 = 65536 - 52 = 65484 = 0xFFCC
T2H = (unsigned char)((65536 - 52) >> 8); // 0xFF
T2L = (unsigned char)(65536 - 52); // 0xCC
// 启动定时器2
AUXR |= 0x10; // T2x12 = 1,1T模式(重复确保)
AUXR |= 0x04; // T2R = 1,启动定时器2
// 清除发送和接收标志
TI = 0;
RI = 0;
}
/*
* 串口1发送单字节
* 查询方式发送
*/
void UART1_SendByte(unsigned char dat)
{
SBUF = dat; // 将数据写入发送缓冲区,启动发送
while(TI == 0); // 等待发送完成
TI = 0; // 清除发送完成标志
}
/*
* 串口1发送字符串
* 调用 UART1_SendByte 逐字节发送
*/
void UART1_SendString(unsigned char *str)
{
while(*str != '\0')
{
UART1_SendByte(*str);
str++;
}
}
关键配置说明
| 项目 |
值 |
说明 |
| 芯片 |
STC8H2K32U |
含2路串口,带硬件奇偶校验和接收超时中断 |
| 串口 |
串口1 |
默认引脚 P3.0(RxD) / P3.1(TxD) |
| 工作模式 |
模式1 |
8位UART,1位起始位+8位数据+1位停止位 |
| 波特率发生器 |
定时器2 |
1T模式,自动重装载 |
| 时钟 |
24MHz 内部IRC |
ISP下载时需选择24MHz |
| 波特率 |
115200 |
误差约0.16%,完全可用 |
如果仍然没有输出,请检查以下硬件问题
-
接线是否正确?
- P3.0(RxD)→ 串口工具的 TxD
- P3.1(TxD)→ 串口工具的 RxD
- GND → GND
- 注意:P3.0/P3.1 同时也是 USB 的 D-/D+,如果板上有 USB 接口电路,可能会影响串口通信,建议下载完成后断开 USB 的 D+/D- 连接
-
ISP下载时频率设置是否正确?
- 在 ISP 下载软件中,必须将 内部IRC频率设置为 24MHz,与代码一致
-
串口助手设置是否正确?
- 波特率:115200
- 数据位:8
- 停止位:1
- 校验位:无
- 流控制:无
-
P3.0/P3.1 是否被其他外设占用?
- 如果板上有 USB 接口或其他电路连接到 P3.0/P3.1,可能会干扰串口通信
-
尝试用示波器或逻辑分析仪测量 P3.1 引脚,看是否有数据波形输出,这是最直接的排查方法。
如果以上都检查无误仍无输出,请告知您的具体硬件连接方式和 ISP 下载时的频率设置截图,我帮您进一步分析。
🔍 搜索 "STC 单片机 论坛 帖子"
⏱️ 查找用时 11.2s | 总回答用时 33.4s