你好,关于你使用 STC15W408AS 芯片进行串口通信调试过程中出现“只有发送没有接收”的问题,下面我将从硬件、软件、配置、调试工具等多个方面进行分析,并给出可能的排查建议和优化方向。
一、问题描述总结
你当前使用的芯片为 STC15W408AS,使用 ISP 的 CDC/HID 串口助手进行串口通信调试,发现:
发送功能正常(可以打印“System Started!”);
接收无响应(没有收到任何数据);
已开启接收中断(ES = 1),也开启了总中断(EA = 1);
使用的是 串口1(UART1),波特率为 115200 bps,晶振为 24MHz。
二、代码分析
我们先来看你的串口初始化函数:
- c
- void Uart1Init(void) //115200bps@24000MHz
- {
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x40; //定时器时钟1T模式
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //设置定时器模式
- TL1 = 0xCC; //设置定时初始值
- TH1 = 0xFF; //设置定时初始值
- ET1 = 0; //禁止定时器中断
- TR1 = 1; //定时器1开始计时
- ES = 1; //打开接收中断
- EA = 1; //打开总中断
- }
复制代码
这段代码看起来是标准的 STC15 系列 UART 初始化配置,但有几个细节需要进一步确认:
1. 波特率是否准确?
你使用的是 24MHz 晶振,波特率为 115200 bps,使用定时器1在1T模式下作为波特率发生器。
计算公式如下:
- Baud = Fosc / (32 12 (256 - TH1))
复制代码
代入你设置的 TH1 = 0xFF, TL1 = 0xCC:
- TH1 = 0xFF, TL1 = 0xCC → 重载值为 0xFFCC → 十进制为 65484
- 256 - (65484 / 256) ≈ 256 - 255.816 ≈ 0.184
- Baud = 24000000 / (32 12 0.184) ≈ 33690 bps
复制代码
结论:波特率设置错误!
你当前设置的定时器初值无法达到 115200 bps,实际波特率约为 33k bps,与串口助手设置的 115200 不匹配,会导致接收失败。
✅ 建议:重新计算正确的波特率初值
推荐使用 STC 官方提供的 波特率计算工具或以下公式重新设置:
- TH1 = TL1 = 256 - Fosc / (32 12 Baud)
复制代码
代入 Fosc = 24MHz,Baud = 115200:
- TH1 = TL1 = 256 - 24000000 / (32 12 115200)
- ≈ 256 - 24000000 / 4423680
- ≈ 256 - 5.426 ≈ 250.574 → 取 250 → 0xFA
复制代码
因此,应修改为:
复制代码
三、接收中断未定义处理函数
你在代码中开启了接收中断:
复制代码
但你没有提供接收中断服务函数,如:
- c
- void UART1ISR(void) interrupt 4
- {
- if(RI)
- {
- RI = 0;
- // 处理接收数据
- }
- if(TI)
- {
- TI = 0;
- txbusy = 0;
- }
- }
复制代码
问题: 没有定义中断服务函数,会导致中断触发后无法处理,甚至程序跑飞。
✅ 建议:补充串口接收中断服务函数
例如:
- c
- void UART1ISR(void) interrupt 4
- {
- if(RI)
- {
- RI = 0;
- u8 dat = SBUF;
- // 可以回显或者处理接收到的数据
- UARTSendByte(dat);
- }
- if(TI)
- {
- TI = 0;
- txbusy = 0;
- }
- }
复制代码
四、硬件连接问题排查
1. 串口引脚是否正确连接?
STC15W408AS 的串口1引脚为:
P3.0(RXD):接收;
P3.1(TXD):发送。
请确认:
你是否将 TXD 接到 USB 转 TTL 模块的 RX;
RXD 是否接到 USB 模块的 TX;
GND 是否共地;
电平是否匹配(3.3V / 5V);
2. 使用的是 ISP 下载口自带的串口?
有些 ISP 下载器(如 STC-USB)内部使用的是虚拟串口(CDC),在使用时需注意:
驱动是否安装;
串口号是否正确;
是否与其他串口冲突;
是否支持全双工通信(有些只支持下载,不支持调试);
五、调试建议
1. 使用逻辑分析仪或示波器查看 TXD 波形
确认 TXD 是否有发送数据;
查看波特率是否与设置一致;
判断是否因电平、波特率不匹配导致接收失败。
2. 使用串口助手发送数据测试
手动发送“HELLO”等字符;
观察是否能触发接收中断;
在中断中添加 LED 闪烁或打印回显判断是否收到数据。
六、完整修正后的代码示例
- c
- include
- include
- typedef unsigned int u16;
- typedef unsigned char u8;
- sbit Beep = P1^6;
- bit txbusy = 0;
- void UARTSendByte(u8 dat)
- {
- while(txbusy); // 等待上次发送完成
- SBUF = dat;
- txbusy = 1;
- }
- void UARTSendString(const char s)
- {
- while(s)
- {
- UARTSendByte(s++);
- }
- }
- void Uart1Init(void)
- {
- SCON = 0x50; // 8位数据,可变波特率
- AUXR |= 0x40; // 定时器时钟为1T模式
- AUXR &= 0xFE; // 串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; // 设置定时器模式
- TL1 = 0xFA; // 115200@24MHz
- TH1 = 0xFA;
- ET1 = 0; // 禁止定时器1中断
- TR1 = 1; // 启动定时器1
- ES = 1; // 使能串口中断
- EA = 1; // 使能全局中断
- }
- void UART1ISR(void) interrupt 4
- {
- if(RI)
- {
- RI = 0;
- u8 dat = SBUF;
- UARTSendByte(dat); // 回显
- }
- if(TI)
- {
- TI = 0;
- txbusy = 0;
- }
- }
- void main()
- {
- u16 i;
- Beep = 0;
- Uart1Init();
- while(1)
- {
- Beep = 0;
- UARTSendString("System Started!\r\n");
- for(i = 0; i < 30000; i++);
- }
- }
复制代码
七、总结
| 问题点 | 原因 | 解决方案 |
|--------|------|-----------|
| 波特率设置错误 | TH1/TL1 初值不匹配 115200 | 修改为 0xFA |
| 无接收中断处理 | 没有定义中断函数 | 添加 UART1ISR 函数 |
| 硬件连接问题 | 引脚接错或电平不匹配 | 检查串口连接、电平、共地 |
| 调试工具问题 | ISP 串口不支持接收 | 使用独立 USB 转 TTL 模块 |
八、扩展建议
使用串口调试助手(如 XCOM、SSCOM)进行收发测试;
使用串口缓冲区实现更复杂的接收逻辑;
使用定时器或延时函数控制发送频率;
若需更高波特率或稳定通信,可考虑使用 定时器2 或 独立波特率发生器模块(部分 STC15 支持)。
如仍有问题,欢迎提供更详细的硬件连接图、串口助手截图或波形图,我可以进一步协助排查。
祝调试顺利!
[本文内容由国芯人工智能辅助生成,仅供参考] |