You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PIC18F47K40的EUSART串口配置问题:Modbus RTU实现异常

PIC18F47K40 EUSART1看门狗触发与串口乱码问题排查方案

一、看门狗触发问题解决

  • 调整喂狗时机:确保主循环、串口收发的阻塞等待循环中都加入CLRWDT()喂狗操作,避免长时间无喂狗触发超时。比如在等待TXREG为空的死循环里,每次循环都喂狗,防止串口发送耗时超过看门狗周期。
  • 优化看门狗配置:根据系统时钟调整看门狗预分频器(WDTPS位),延长超时周期。比如系统时钟40MHz时,设置合适的预分频值让看门狗超时时间大于最长的单次操作耗时(比如串口发送一个字符串的时间)。
  • 移除不必要的阻塞逻辑:尽量避免在主循环中使用死循环等待,改用中断驱动的缓冲区机制,让主循环能持续喂狗。

二、串口乱码问题解决

  • 校验波特率精度:根据实际系统时钟重新计算波特率发生器参数(SPBRG/SPBRGH),确保实际波特率与19200的误差≤5%(Modbus RTU要求)。注意区分高速(BRGH=1)和低速(BRGH=0)模式的分频系数:
    • 高速模式:SPBRG_VAL = (FOSC/(16*BAUD)) - 1
    • 低速模式:SPBRG_VAL = (FOSC/(64*BAUD)) - 1
      同时要开启BRG16位使用16位波特率发生器,提升精度。
  • 检查中断配置:确认全局中断(INTCONbits.GIE)、外围中断(INTCONbits.PEIE)、EUSART收发中断(PIE3bits.RCIE/PIE3bits.TXIE)均已正确启用,中断优先级配置与系统需求匹配。
  • 修正中断服务程序(ISR):
    • 接收ISR中需及时读取RCREG寄存器,避免数据溢出;同时维护接收环形缓冲区的读写指针,确保数据正确存储。
    • 发送ISR中仅负责加载下一个待发送字节,不要在ISR内执行耗时操作(如字符串处理),主循环负责填充发送缓冲区。
    • ISR末尾需清除中断标志位(如PIR3bits.RCIF/PIR3bits.TXIF),避免重复触发中断。
  • 确认引脚配置:将RC6(TX)设为输出、RC7(RX)设为输入,同时禁用对应引脚的模拟功能(清零ANSELC相关位),防止引脚功能冲突。
  • 排查缓冲区逻辑:如果使用环形缓冲区,检查缓冲区大小是否足够,读写指针的更新是否原子化(避免中断中指针被篡改导致数据错乱),确保缓冲区不会溢出或读取无效数据。

波特率配置示例(40MHz时钟,19200波特率)

#define FOSC 40000000UL
#define BAUD 19200UL

void EUSART1_Init(void) {
    // 引脚配置
    TRISCbits.TRISC6 = 0; // RC6为TX输出
    TRISCbits.TRISC7 = 1; // RC7为RX输入
    ANSELCbits.ANSELC6 = 0; // 禁用模拟功能
    ANSELCbits.ANSELC7 = 0;

    // 波特率配置
    TXSTAbits.BRGH = 1; // 高速模式
    BAUDCONbits.BRG16 = 1; // 16位波特率发生器
    unsigned int spbrg_val = (FOSC / (16 * BAUD)) - 1;
    SPBRG = spbrg_val & 0xFF;
    SPBRGH = (spbrg_val >> 8) & 0xFF;

    // 串口使能
    TXSTAbits.TXEN = 1;
    RCSTAbits.SPEN = 1;
    RCSTAbits.CREN = 1;

    // 中断配置
    PIE3bits.RCIE = 1; // 启用接收中断
    INTCONbits.PEIE = 1;
    INTCONbits.GIE = 1;
}

喂狗操作示例

void EUSART1_SendChar(uint8_t data) {
    while(!TXSTAbits.TRMT) {
        CLRWDT(); // 等待发送完成时喂狗
    }
    TXREG = data;
}

void main(void) {
    // 看门狗配置(示例:超时约1秒,根据时钟调整)
    WDTCONbits.SWDTEN = 1;
    WDTPSbits.WDTPS = 0b1010; // 预分频值对应超时周期

    EUSART1_Init();

    while(1) {
        CLRWDT(); // 主循环定时喂狗

        // 处理串口缓冲区数据
        // ...
    }
}

内容的提问来源于stack exchange,提问作者Hamza khalid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:05:13