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);
}
}
} //===================================
// 主函数
//===================================
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();
}
}
}
如果把发送中断移值主程序,偶尔就会出现发送指令不执行或延迟执行的现象 。 建议引入发送标志位 避免在主程序中无条件调用发送函数 使用独立的发送缓冲区 从官网找例程,从开发板找例程 没有清除标志位的缘故 中断方式需要将标志位清零 从代码和现象来看,问题核心在于主程序发送逻辑未考虑 LPUART 发送缓冲区状态,导致数据发送被阻塞或丢失。 当发送逻辑放在接收中断中时,中断上下文确保了发送的原子性;而移到主程序后,若主程序存在其他耗时操作或发送时机不当,就会出现异常
页:
[1]