|
|
楼主 |
发表于 2026-8-24 09:21:34
|
显示全部楼层
|
下面这个是论坛的ai助手写的。奇怪的是它的写的也是无法正常 接收 PC 发来的数据。 好的,现在我已经确认了所有关键寄存器的位定义。让我一一核对之前代码中的寄存器配置: 关键寄存器位定义核对1. P_SW1(地址 A2H)B7= S1_S1, B6= S1_S0, B5= -, B4= -, B3= SPI_S1, B2= SPI_S0, B1= -, B0= -📋要设置 S1_S[1:0] = 01(RxD=P3.6, TxD=P3.7): - B7(S1_S1) = 0
- B6(S1_S0) = 1
P_SW1 = 0x40 ✅ 我之前写的是 P_SW1 = 0x10,这是错误的!因为 S1_S[1:0] 占据的是 B7、B6,不是 B5、B4。正确值应为 0x40。 2. SCON(地址 98H)B7=SM0/FE, B6=SM1, B5=SM2, B4=REN, B3=TB8, B2=RB8, B1=TI, B0=RI📋模式1(SM0=0, SM1=1),允许接收(REN=1),SM2=0:
SCON = 0x50 ✅(0x50 = 0101 0000B) 3. AUXR(地址 8EH)B7=T0x12, B6=T1x12, B5=UART_M0x6, B4=T2R, B3=T2_C/T, B2=T2x12, B1=EXTRAM, B0=S1BRT📋- T1x12=1(B6=1)→ 定时器1 1T模式
- S1BRT=0(B0=0)→ 选定时器1做波特率发生器
AUXR = 0x40 ✅ 但我之前写 AUXR = 0x00 然后 AUXR |= 0x40 的写法是没问题的,最终等价于 0x40。 4. TMOD(地址 89H)B7=T1_GATE, B6=T1_C/T, B5=T1_M1, B4=T1_M0, B3=T0_GATE, B2=T0_C/T, B1=T0_M1, B0=T0_M0📋定时器1模式0(16位自动重载):T1_M1=0, T1_M0=0 → TMOD 高4位 = 0000 TMOD = 0x00 ✅(手册例程中使用 TMOD = 0x00) 5. TCONB7=TF1, B6=TR1, B5=TF0, B4=TR0, B3=IE1, B2=IT1, B1=IE0, B0=IT0📋启动定时器1(TR1=1):TCON = 0x40 ✅ 6. IE(地址 A8H)B7=EA, B6=ELVD, B5=EADC, B4=ES, B3=ET1, B2=EX1, B1=ET0, B0=EX0📋EA=1(B7),ES=1(B4)→ IE = 0x90 ✅ ⚠️ 我之前的错误P_SW1 的值写错了! 我之前写的是 P_SW1 = 0x10,但根据手册,S1_S[1:0] 在 P_SW1 的 B7、B6 位,所以正确值应为 0x40(B6=1)。 ✅ 修正后的完整代码// ============================================================// AI8051U 实验箱 - 串口1 使用 P3.6(RxD) / P3.7(TxD)// 系统时钟: 11.0592MHz, 波特率: 115200// 定时器1模式0(16位自动重载, 1T模式) 作波特率发生器// ============================================================#include "Ai8051U.H"#include "intrins.h"#define FOSC 11059200UL#define BRT (65536 - (FOSC / 115200 + 2) / 4)bit busy;char wptr;char rptr;char buffer[16];void UartIsr() interrupt 4{ if (TI) { TI = 0; busy = 0; } if (RI) { RI = 0; buffer[wptr++] = SBUF; wptr &= 0x0f; }}void UartInit(){ SCON = 0x50; // SM0=0,SM1=1(模式1),REN=1(允许接收),SM2=0 S1BRT = 0; // 选择定时器1作为波特率发生器 TMOD = 0x00; // 定时器1模式0(16位自动重载) TL1 = BRT; TH1 = BRT >> 8; TR1 = 1; // 启动定时器1 T1x12 = 1; // 定时器1 1T模式 wptr = 0x00; rptr = 0x00; busy = 0;}void UartSend(char dat){ while (busy); busy = 1; SBUF = dat;}void UartSendStr(char *p){ while (*p) { UartSend(*p++); }}void main(){ P_SW2 |= 0x80; // 允许访问扩展寄存器 XFR (8位模式) P1M0 &= ~0x30; // P1.4/P1.5 M0=0 P1M1 |= 0x30; // P1.4/P1.5 M1=1 => 高阻输入 P3M0 = (P3M0 & ~0x40) | 0x80; // P3.7推挽输出(P37M0=1), P3.6不推挽(P36M0=0) P3M1 &= ~0xc0; // P3.6/P3.7 M1清0 P_SW1 = 0x40; // S1_S[1:0]=01 => RxD=P3.6, TxD=P3.7 SCON = 0x50; // 串口1模式1, 允许接收 AUXR = 0x40; // T1x12=1(定时器1 1T模式), S1BRT=0(选定时器1) TL1 = BRT; // 定时器1重装值低8位 TH1 = BRT >> 8; // 定时器1重装值高8位 TCON = 0x40; // TR1=1, 启动定时器1 IE = 0x90; // EA=1(总中断), ES=1(串口1中断) UartInit(); // 再调用一次初始化, 确保缓冲区指针清零 UartSendStr("Uart Test !\r\n"); while (1) { if (rptr != wptr) { UartSend(buffer[rptr++]); rptr &= 0x0f; } }}📋 核对总结[td]寄存器 | 值 | 说明 | 验证 | | P_SW1 | 0x40 | S1_S[1:0]=01 → RxD=P3.6, TxD=P3.7 | ✅ | | SCON | 0x50 | 模式1, REN=1允许接收 | ✅ | | AUXR | 0x40 | T1x12=1(1T), S1BRT=0(定时器1) | ✅ | | TMOD | 0x00 | 定时器1模式0(16位自动重载) | ✅ | | TCON | 0x40 | TR1=1启动定时器1 | ✅ | | IE | 0x90 | EA=1, ES=1(串口中断) | ✅ |
P_SW1 之前我写错了,现在修正为 0x40,这是经过手册核对的正确值。感谢您提醒我验证!
📌 相关论坛讨论 ⏱️ 查找用时 25.6s | 总回答用时 42.3s 📋
✋
[09:10:39.035]接收←55 61 72 74 20 54 65 73 74 20 21 0D 0A
[09:11:19.347]发送→FF
[09:11:19.348]接收←FE
AI
我看到您的串口通信已经工作了: - 接收到的数据:55 61 72 74 20 54 65 73 74 20 21 0D 0A = ASCII 码 "Uart Test !\r\n" ✅
- 发送 FF,接收 FE:说明串口1回环通信正常 ✅
串口已经正常工作了!P3.6(RxD) / P3.7(TxD) 的配置正确,P3.7 推挽输出也正常发出数据。
不过我想确认一下您那边的具体情况:
您能否确认一下: - 您的系统时钟频率是多少?(是 11.0592MHz 还是其他?)
- 目标波特率是多少?
- P3.6 和 P3.7 之间是如何连接的?(短接回环,还是接外部设备?)
这样我帮您进一步确认计算的重装值是否准确。如果时钟不是 11.0592MHz,我写的 BRT 计算值就不对了,需要重新调整。
📌 相关论坛讨论 ⏱️ 查找用时 0.7s | 总回答用时 4.7s 📋
✋
[09:10:39.035]接收←55 61 72 74 20 54 65 73 74 20 21 0D 0A
[09:11:19.347]发送→FF
[09:11:19.348]接收←FE
[09:12:11.852]发送→55
[09:12:11.859]接收←00
AI
好的,我再分析一下您的串口回环测试结果: - 发送 FF → 接收 FE (差了一位,bit0 从1变0)
- 发送 55 → 接收 00 (差了很多位)
这两个现象说明通信数据存在错误。55 是 0101 0101B,收回来变成 00,说明接收端采样出现了严重问题。 这个现象的核心原因很可能是波特率不匹配或系统时钟频率不对。 我之前的代码假设的是: - 系统时钟 = 11.0592MHz
- 波特率 = 115200
如果您的 AI8051U 实验箱实际系统时钟不是 11.0592MHz,那么 BRT 的重装值就完全错了,会导致波特率偏差很大,收发数据就会出错。
能确认一下您的实验箱系统时钟频率是多少吗?AI8051U 实验箱默认的 IRC 频率有多种可选,常见的有: - 11.0592MHz
- 24MHz
- 30MHz
- 33.1776MHz
- 40MHz
- 48MHz
等
请您告诉我: - 系统时钟频率是多少?(在 ISP 下载软件中设置或查看)
- 目标波特率是多少?
我帮您精确计算正确的 BRT 重装值。如果您的系统时钟不是 11.0592MHz,当前代码中 #define FOSC 11059200UL 就需要改为实际值,然后重新计算 BRT。 另外,还有一个可能:P3.6 和 P3.7 的硬件连接问题。如果您的回环测试是通过外部跳线相连,请确认: - 接触是否良好
- 是否 P3.6 和 P3.7 之间有其他干扰
不过最可能的还是时钟频率不匹配,因为偶尔错一位(FF→FE)和全部错位(55→00)是典型的波特率偏差症状。 请提供您的实际时钟频率和波特率,我来帮您修正!
--------------------------------------
|
|