qihao74 发表于 2025-1-7 15:23

hc32l136 Lpuart发生异常

当发送指令放置在接收中断时,一切正常。如果把发送中断移值主程序,偶尔就会出现发送指令不执行或延迟执行的现象 。
//===================================
// 初始化Lpuart
//===================================
void lpuart_init(void)
{
    uint16_t u16Scnt = 0;
    stc_gpio_config_t stcGpioCfg;
    stc_lpuart_sclk_sel_t stcSclk;
    stc_lpuart_config_tstcConfig;
    stc_lpuart_irq_cb_t stcLPUartIrqCb;
    stc_lpuart_multimode_t stcMulti;
    stc_lpuart_baud_t stcBaud;
    DDL_ZERO_STRUCT(stcConfig);
    DDL_ZERO_STRUCT(stcLPUartIrqCb);
    DDL_ZERO_STRUCT(stcMulti);
    DDL_ZERO_STRUCT(stcBaud);
    DDL_ZERO_STRUCT(stcGpioCfg);
    DDL_ZERO_STRUCT(stcSclk);
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
    Sysctrl_SetPeripheralGate(SysctrlPeripheralLpUart1, TRUE);
    stcGpioCfg.enDir =GpioDirOut;
    Gpio_Init(GpioPortA, GpioPin0, &stcGpioCfg); //TX
    stcGpioCfg.enDir =GpioDirIn;
    stcGpioCfg.enPuPd = GpioPu;
    Gpio_Init(GpioPortA, GpioPin1, &stcGpioCfg); //RX
    Gpio_SetAfMode(GpioPortA, GpioPin0, GpioAf2);
    Gpio_SetAfMode(GpioPortA, GpioPin1, GpioAf2);
    stcLPUartIrqCb.pfnRxIrqCb   = LPUartRxIntCallback;
    stcLPUartIrqCb.pfnTxIrqCb   = NULL;
    stcLPUartIrqCb.pfnRxFEIrqCb = NULL;
    stcLPUartIrqCb.pfnPEIrqCb   = NULL;
    stcLPUartIrqCb.pfnCtsIrqCb= NULL;
    stcConfig.pstcIrqCb = &stcLPUartIrqCb;
    stcConfig.bTouchNvic = TRUE;
    stcConfig.enStopBit = LPUart1bit;
    stcConfig.enRunMode = LPUartMode1;//
    stcSclk.enSclk_Prs = LPUart4Or8Div;
    stcSclk.enSclk_sel = LPUart_Rcl;
    stcConfig.pstcLpuart_clk = &stcSclk;
    stcMulti.enMulti_mode = LPUartNormal;
    stcConfig.pstcMultiMode = &stcMulti;
    LPUart_Init(LPUART1, &stcConfig);
    LPUart_SetClkDiv(LPUART1, LPUart4Or8Div);
    stcBaud.u32Sclk = LPUart_GetSclk(LPUART1);
    stcBaud.enRunMode = LPUartMode1;
    stcBaud.u32Baud = 9600;
    u16Scnt = LPUart_CalScnt(LPUART1, &stcBaud);
    LPUart_SetBaud(LPUART1, u16Scnt);
    LPUart_EnableIrq(LPUART1, LPUartRxIrq);
    LPUart_ClrStatus(LPUART1, LPUartRC);
    LPUart_EnableFunc(LPUART1, LPUartRx);
}
//===================================
// LPUART 中断服务函数
//===================================
void LPUartRxIntCallback(void)
{
    Uartbuff = LPUart_ReceiveData(LPUART1);;
    if(UartRX_dp >= 8)
    {
      if( (Uartbuff == PollAdd) || (Uartbuff == 0) )
      {
            if((Uartbuff == 3) || (Uartbuff == 6) || (Uartbuff == 8))
            {
                ISRcrc16 = ISRcal_crc16(Uartbuff, 6);
                if( (Uartbuff == ((uint8_t)ISRcrc16)) && ( Uartbuff == ((uint8_t)(ISRcrc16 >> 8))) )
                {
                  //准备发送
                  UartHartrecok = 0x55;
                  if((Uartbuff == 3) || (Uartbuff == 6))
                        **.ReportSum** = 0;
                  //                                        Rxreal**=0;
                  UartRX_dp = 0;
                }
                code16 = 0;
            }
            else if(Uartbuff == 0x10)
            {
                if(UartRX_dp >= (Uartbuff + 9))
                {
                  ISRcrc16 = ISRcal_crc16(Uartbuff, Uartbuff + 7);
                  if( (Uartbuff + 7] == ((uint8_t)ISRcrc16)) && ( Uartbuff + 8] == ((uint8_t)(ISRcrc16 >> 8))) )
                  {
                        //准备发送
                        UartHartrecok = 0x55;
                        
                        **.ReportSum** = 0;
                        //                        Rxreal**=0;
                        UartRX_dp = 0;
                  }
                  code16 = 0;//20220419
                }
                else code16 = 0x55;                //未收完
            }
            else code16 = 0;
      }
      if( (UartHartrecok != 0x55) && (code16 != 0x55) )                              //数据不对,移除最旧的一个字节
      {
            uint8_t i;
            for(i = 0; i < UartRX_dp - 1; i++)      Uartbuff = Uartbuff;
            UartRX_dp -= 1;
      }
      if(UartHartrecok == 0x55)
      {
            MODBUSManagement();
      }                     
                              
    }
}
//===================================
// LPUART发送命令处理函数
//===================================
void MODBUSManagement(void)
{
    if(UartHartrecok == 0x55)
    {
      uint8_t UartTX_cn;
      UartHartrecok = 0;
      UartTX_cn = Uart_rx_deal(Uartbuff);
      /*数据发送*/
      for(uint8_t i = 0; i < UartTX_cn; i++)
      {
            LPUart_SendData(LPUART1, Uartbuff);
      }
    }
}

qihao74 发表于 2025-1-7 15:24

//===================================
// 主函数
//===================================
int32_t main(void)
{
    lpuart_init();
    初始化
while(1)
    {
      Wdt_Feed();
      MODBUSManagement();
      if((!**.M50** || Resetdly > 0) && Ovmagdly == 0)
      {
            //LCDLIB_PrintRSSI(4);//关闭信号强度显示
            stcConfig.enSLEEPDEEP   = SlpDpEnable;
            Lpm_Config(&stcConfig);
            Lpm_GotoLpmMode();
      }
      else
      {
            stcConfig.enSLEEPDEEP   = SlpDpDisable;
            Lpm_Config(&stcConfig);
            Lpm_GotoLpmMode();
      }
    }
}
如果把发送中断移值主程序,偶尔就会出现发送指令不执行或延迟执行的现象 。

probedog 发表于 2025-1-9 13:19

建议引入发送标志位

stormwind123 发表于 2025-1-9 13:22

避免在主程序中无条件调用发送函数

laocuo1142 发表于 2025-1-9 16:00

使用独立的发送缓冲区

地瓜patch 发表于 2025-1-21 21:23

从官网找例程,从开发板找例程

申小林一号 发表于 2025-1-22 08:54

没有清除标志位的缘故

MrChen93 发表于 2025-6-3 11:31

中断方式需要将标志位清零

初级工程渣 发表于 2025-6-30 14:02

从代码和现象来看,问题核心在于主程序发送逻辑未考虑 LPUART 发送缓冲区状态,导致数据发送被阻塞或丢失。

初级工程渣 发表于 2025-6-30 15:24

当发送逻辑放在接收中断中时,中断上下文确保了发送的原子性;而移到主程序后,若主程序存在其他耗时操作或发送时机不当,就会出现异常
页: [1]
查看完整版本: hc32l136 Lpuart发生异常