找回密码
 立即注册
查看: 342|回复: 27

关于ai8051u 的串口1切换引脚到 P3.6 P3.7 后 出现的异常| 已经解决 ,见20楼

[复制链接]

54

主题

397

回帖

864

积分

高级会员

积分
864
发表于 2026-8-23 19:21:24 | 显示全部楼层 |阅读模式
我将例程 《Ai8051U-32Bit\33-IO模拟SPI访问FLASH-串口监控》 的串口1 引脚切换到  P3.6 P3.7 后,

打印是正常的,可是接收总是不对。 这个是咋回事呢?

我看J18D  和  S2 两个地方都没有连接,应该是不干扰的啊,可pc给实验箱发送,实验箱收到的总是错误的。打印是正常的。

33-IO模拟SPI访问FLASH-串口监控.rar (14.41 KB, 下载次数: 25)

截图202608241114379565.jpg


################
目前看来是硬件有问题?
在我的实验箱上 用论坛里大佬验证通过的hex烧录后,
结果还是不对。


截图202608241209087177.jpg    

为了避免是自己操作步骤哪里错误,我特意下载了两次大佬给的hex


截图202608241210551195.jpg

---------------------------------------------------------------------------

另外我自己还焊接一个板子。 于是我那大佬验证通过的hex,试了一下自己焊接的板子。
我发现效果 就更奇怪了  效果如图。

截图202608241239034636.jpg




        (P_SW1  40 );
        (SCON    50 );  
        (AUXR    40 );
        
        (TCON    C0 );  
        (TMOD   00 );

        (TL1      );   这个值 无法查看,是动态变化的
        (TH1     );   这个值 无法查看,是动态变化的

        (IE        90 );


答案: 见20楼, link1d在捣乱。










点评

答案已置顶,方便各位参考  发表于 2026-8-24 21:36
1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
回复

使用道具 举报 送花

已绑定手机
已实名认证

147

主题

4045

回帖

1万

积分

超级版主

积分
10681
发表于 2026-8-24 20:58:17 | 显示全部楼层
xie2*** 发表于 2026-8-24 20:23
这个问题 目前无解 .

我后来  自己从头写了一个,  还是不对。 可能是我 对手册理解不够?   

我觉得可能要借助示波器查看一下
我对比了一下它的二进制码,这种看起来像是上拉能力不足导致的。
我认为你可以进行这样尝试,也就是在串口通讯的引脚上接一个额外的上拉电阻到 MCU VCC。
以及如果你使用了 Link 1D 的 cdc2,我记得早些版本有可能 cdc2 的上拉配置有问题?和 cdc 1 的一些配置混合了,也就是同时用正常,单独用 cdc2 可能不大正常,可以通过给 Link 1D 更新一下程序试试。

点评

大佬真厉害啊。。。。。这问题都被你发现了。 竟然是是link1D 在捣乱啊。。。。。哈哈哈 我刚刚换到 把 link1d 换到p3.0 和p3.1 上 ,立马正常了。。  发表于 2026-8-24 21:17
回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 2026-8-23 23:49:10 | 显示全部楼层
截图202608232346313460.jpg 截图202608232347361299.jpg

截图202608232348278371.jpg    截图202608232349032338.jpg
回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 2026-8-23 23:51:04 | 显示全部楼层
截图202608232351008485.jpg
回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 2026-8-23 23:57:59 | 显示全部楼层
截图202608232353391217.jpg 截图202608232354145138.jpg


我之前只 打印的时候,这样写是可以的:

void Uart1Init()
{
    S1_S0 = 1;      //UART1(RxD1_2/P3.6, TxD1_2/P3.7)
    S1_S1 = 0;
       
    SCON = 0x50;
    TMOD &= ~0xf0;
    S1BRT = 0;
       
       
    TL1 = TM;
    TH1 = TM >> 8;

    T1x12 = 1;
    TR1 = 1;

    PS = 1;     //提高串口1中断优先级,防止数据丢失
    // ES = 1;
}

回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 2026-8-24 07:00:10 | 显示全部楼层
    这个是官方例程中p3.0 p3.1 的这是可以正常接收的。但切换引脚就有问题。
    S1_S1 = 0;      //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4
    S1_S0 = 0;
    SCON = (SCON & 0x3f) | 0x40;
    T1x12 = 1;      //定时器时钟1T模式
    S1BRT = 0;      //串口1选择定时器1为波特率发生器
    TL1  = TM;
    TH1  = TM>>8;
    TR1 = 1;        //定时器1开始计时
    REN = 1;        //允许接收
    ES  = 1;        //允许中断
回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 2026-8-24 07:35:29 | 显示全部楼层
截图202608240735255357.jpg     截图202608240738476783.jpg
回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 2026-8-24 08:07:30 | 显示全部楼层
截图202608240807277168.jpg
回复

使用道具 举报 送花

已绑定手机

121

主题

5082

回帖

1万

积分

超级版主

无情的代码机器

积分
11222
发表于 2026-8-24 09:09:13 | 显示全部楼层
36 设置错误 推挽模式 了

截图202608240908594906.jpg

点评

感谢大佬的回复。那个是尝试的时候,临时加的没删掉。 删掉后,依然是错误的 。 具体效果我放在10楼吧。 点评不能放图片。  发表于 2026-8-24 09:31
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 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_SW10x40S1_S[1:0]=01 → RxD=P3.6, TxD=P3.7
SCON0x50模式1, REN=1允许接收
AUXR0x40T1x12=1(1T), S1BRT=0(定时器1)
TMOD0x00定时器1模式0(16位自动重载)
TCON0x40TR1=1启动定时器1
IE0x90EA=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 推挽输出也正常发出数据。

不过我想确认一下您那边的具体情况:
  • "Uart Test !\r\n" 能正常收到,说明发送方向没问题。
  • 发 FF 收 FE 这个现象需要注意——如果您的实验箱硬件上 P3.6 和 P3.7 之间有环路短接(RxD 和 TxD 直接相连做回环测试),那么发 FF 应该收回 FF。收到 FE 说明数据在传输中可能丢失了一位(FF 的 bit0 被清零变成 FE),这可能有几种原因:

    • 波特率误差:如果波特率有微小误差,长时间连续发送时可能导致个别位采样错误。
    • 硬件连接:如果您是通过外部线缆把 P3.6 和 P3.7 短接测试,检查接触是否良好。
    • 波形质量问题:如果线较长或负载重,边沿变化可能不够陡峭,此时 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)是典型的波特率偏差症状。
请提供您的实际时钟频率和波特率,我来帮您修正!

--------------------------------------



回复

使用道具 举报 送花

54

主题

397

回帖

864

积分

高级会员

积分
864
 楼主| 发表于 2026-8-24 09:32:46 | 显示全部楼层
erci*** 发表于 2026-8-24 09:09
36 设置错误 推挽模式 了

截图202608240932437484.jpg

点评

[attachimg]147960[/attachimg] 代码屏蔽那一行就行了。再检查硬件?还不行给板载串口模块刷新下固件  详情 回复 发表于 2026-8-24 09:38
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-9-23 15:05 , Processed in 0.089528 second(s), 93 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表