kktron 发表于 2023-2-9 17:05

HC32L170FAUA-TIM6关联串口超时问题

本帖最后由 kktron 于 2023-2-13 07:56 编辑

这里看不懂   u16Period = 0xF000;u16GCMAValue = 0x0F00;配置各种值
都会出现断包分包。

我理解是不是应该配置后,数据字节与字节 超过比如5ms, 就定时器中断?

现在我值了后发现发的数据长比如300字节,收到200多字节就定时器超时了,
但设置的慢超时,又会不及时返回上位机,

170FAUA 也没看到空闲中断,这个DMA 配合TIM6高级定时器 什么原理呢?


void Time6_init(void)
{
    uint16_t                u16Period,u16GCMAValue;
    stc_adt_basecnt_cfg_t   stcAdtBaseCntCfg;
    stc_adt_aos_trig_cfg_tstcAdtAosTrigCfg;

    DDL_ZERO_STRUCT(stcAdtBaseCntCfg);
    DDL_ZERO_STRUCT(stcAdtAosTrigCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdvTim, TRUE);//ADT外设时钟使能

    stcAdtBaseCntCfg.enCntMode = AdtSawtoothMode;
    stcAdtBaseCntCfg.enCntDir = AdtCntUp;
    stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0Div64;
    Adt_Init(M0P_ADTIM6, &stcAdtBaseCntCfg);                   //ADT载波、计数模式、时钟配置

    u16Period = 0xF000;
    Adt_SetPeriod(M0P_ADTIM6, u16Period);                      //周期设置

    u16GCMAValue = 0x0F00;
    Adt_SetCompareValue(M0P_ADTIM6, AdtCompareA, u16GCMAValue);//通用比较基准值寄存器A设置

    stcAdtAosTrigCfg.enAos0TrigSrc = AdtAosxTrigSelUart0Int;   //AOS0选择UART0中断
    stcAdtAosTrigCfg.enAos1TrigSrc = AdtAosxTrigSelUart0Int;   //AOS1选择UART0中断
    Adt_AosTrigCfg(&stcAdtAosTrigCfg);

                Adt_CfgHwClear(M0P_ADTIM6, AdtHwTrigAos0);               //AOS0事件 清零TIM6
    Adt_CfgHwStart(M0P_ADTIM6, AdtHwTrigAos0);               //AOS0事件触发TIM6启动
               
                Adt_CfgHwClear(M0P_ADTIM6, AdtHwTrigAos1);               //AOS1事件 清零TIM6
    Adt_CfgHwStart(M0P_ADTIM6, AdtHwTrigAos1);               //AOS1事件触发TIM6启动

    Adt_EnableHwStart(M0P_ADTIM6);                           //硬件启动使能
    Adt_EnableHwClear(M0P_ADTIM6);                           //硬件清零使能
    Adt_EnableHwStop(M0P_ADTIM6);                              //硬件停止使能

    Adt_ClearAllIrqFlag(M0P_ADTIM6);
    Adt_CfgIrq(M0P_ADTIM6, AdtCMAIrq, TRUE);                   //配置TIM6比较中断
    EnableNvic(ADTIM6_IRQn, IrqLevel0, TRUE);
}


/**
******************************************************************************
** \briefTim6_IRQHandler
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void Tim6_IRQHandler(void)
{
    volatile uint16_t len = 0;
    stc_adt_sw_sync_t stcAdtSwSync;
    stcAdtSwSync.bAdTim4 = TRUE;

    if(TRUE == Adt_GetIrqFlag(M0P_ADTIM6, AdtCMAIrq))
    {
      Adt_ClearIrqFlag(M0P_ADTIM6, AdtCMAIrq);
      Adt_ClearAllIrqFlag(M0P_ADTIM6);

      Adt_StopCount(M0P_ADTIM6);
      M0P_UART0->ICR_f.RCCF = 0;       //清中断状态位

      Dma_DisableChannel(DmaCh1);
      Dma_ClrStat(DmaCh1);             //清除通道1状态值
                        
      len = (M0P_DMAC->CONFA1)&0x0000FFFF;
      if(len == 0xFFFF) len = 1;
      else len = 0xFFFF - (M0P_DMAC->CONFA1)&0x0000FFFF - 1;
                        g_uart0_cfg.rx_len=len;
      Uart0_DMA_SendData(g_uart0_cfg.uart0RxBuf,g_uart0_cfg.rx_len);
      memset(&g_uart0_cfg.uart0RxBuf,0,sizeof(g_uart0_cfg.uart0RxBuf));

      Dma_SetBlockSize(DmaCh1,1);       //BC = 0 配置 DMA 通道待传输的数据块的大小为
      Dma_SetTransferCnt(DmaCh1,65535); //TC = 0 配置 DMA 通道待传输的数据块的大小为
      Dma_SetSourceAddress(DmaCh1,0x40000000);
      Dma_SetDestinationAddress(DmaCh1,(uint32_t)&g_uart0_cfg.uart0RxBuf);
      Dma_EnableChannel(DmaCh1);
      Dma_ClrStat(DmaCh1);             //清除通道0状态值
    }
}
/**
******************************************************************************
** \briefuart0_DmaCfg
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_DmaCfg(void)
{
    stc_dma_cfg_t stcDmaCfg;

    DDL_ZERO_STRUCT(stcDmaCfg);                              //初始化变量

    Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE);      //使能DMAC外设时钟门控开关

    //rx dma配置
    stcDmaCfg.u32SrcAddress = 0x40000000;                      //接收数据寄存器地址,uart0的基地址
    stcDmaCfg.u32DstAddress = (uint32_t)&g_uart0_cfg.uart0RxBuf; //接收缓冲
    stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable;//使能DMA源地址重载
    stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable;   //使能BC和CONFA:TC的重载功能
    stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable; //使能DMA目的地址重载
    stcDmaCfg.enTransferMode = DmaMskContinuousTransfer;       //连续传输,DMAC传输完成时不清除CONFA:ENS位
    stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc;                //目的地址自增
    stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrFix;                //源地址固定
    stcDmaCfg.u16BlockSize = 1;                              //块传输个数,串口寄存器只能有一个数据 ,含义:数据块大小
    stcDmaCfg.u16TransferCnt = 65535;                           //块传输次数,此处设置为最大65535
    stcDmaCfg.enMode = DmaMskBlock;                            //块(Block)传输
    stcDmaCfg.enTransferWidth = DmaMsk8Bit;                  // 8 bit字节传输
    stcDmaCfg.enRequestNum = DmaUart0RxTrig;                   //DMA硬件触发源位Uart0Rx
    stcDmaCfg.enPriority = DmaMskPriorityFix;                  //DMA 各通道优先级固定 (CH0>CH1)

    Dma_Enable();                                              //DMA模块使能
    Dma_InitChannel(DmaCh1, &stcDmaCfg);                     //DMA通道1初始化
    Dma_EnableChannel(DmaCh1);                                 //使能通道1
}

kktron 发表于 2023-2-9 17:12

本帖最后由 kktron 于 2023-2-9 17:14 编辑

还有个问题就是    需要一般普通的1152008/none/1模式,不要什么多机,校验花,   是这样配置校验UartMskDataOrAddr , 模式1吗?

///<UART Init
    stcCfg.enRunMode      = UartMskMode1;          ///<模式1
    stcCfg.enStopBit      = UartMsk1bit;         ///<1bit停止位
    stcCfg.enMmdorCk      = UartMskDataOrAddr;   ///<无校验

    stcCfg.stcBaud.u32Baud= 115200;                ///<波特率115200

    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;       ///<通道采样分频配置
    stcCfg.stcBaud.u32Pclk= Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值
    Uart_Init(M0P_UART0, &stcCfg);                   ///<串口初始化

yang377156216 发表于 2023-2-9 18:24

kktron 发表于 2023-2-9 17:12
还有个问题就是    需要一般普通的1152008/none/1模式,不要什么多机,校验花,   是这样配置校验U ...

///< HC32L170 串口0模块配置 N - 8 - 1
void App_UartCfg(void)
{
    stc_uart_cfg_tstcCfg;
    stc_uart_multimode_t stcMulti;
    stc_uart_baud_t stcBaud;

    DDL_ZERO_STRUCT(stcCfg);
    DDL_ZERO_STRUCT(stcMulti);
    DDL_ZERO_STRUCT(stcBaud);
   
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);//UART0外设模块时钟使能
   
    stcCfg.enRunMode = UartMskMode1;   //模式1
    stcCfg.enStopBit = UartMsk1bit;      //1位停止位
    stcCfg.enMmdorCk = UartMskDataOrAddr;      //无校验
    stcCfg.stcBaud.u32Baud = 9600;       //波特率9600
    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;         //通道采样分频配置
    stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq();    //获得外设时钟(PCLK)频率值
    Uart_Init(M0P_UART0, &stcCfg);       //串口初始化

    Uart_ClrStatus(M0P_UART0,UartRC);    //清接收请求
    Uart_ClrStatus(M0P_UART0,UartTC);    //清发送请求
    Uart_EnableIrq(M0P_UART0,UartRxIrq); //使能串口接收中断
    Uart_EnableIrq(M0P_UART0,UartTxIrq); //使能串口发送中断
}

yang377156216 发表于 2023-2-9 18:27

原理就是软件方式去模拟了硬件的串口接收超时功能,在ST 中也叫做串口空闲功能,超时时间的配置需要与当前波特率去匹配的,也就是一位所占的时间。

kktron 发表于 2023-2-10 09:21

yang377156216 发表于 2023-2-9 18:24


谢谢,配置串口那OK的

martinhu 发表于 2023-2-10 09:25

你可以看看这个例子,虽然是在L136上的,但是对于高级定时器的使用是一样的。



kktron 发表于 2023-2-10 09:28

yang377156216 发表于 2023-2-9 18:27
原理就是软件方式去模拟了硬件的串口接收超时功能,在ST 中也叫做串口空闲功能,超时时间的配置需要与当前 ...

像ST的普通定时器,定义1ms超时,每收到一字节超时清0定时器,比如配合115200bps
4ms 每byte进来,就空闲解析了

但这个TIM6 我试了各种值超时 都无法做到10~300字节各种不定长一包的稳定超时空闲。
感觉TIM6是从开始接收到结束接收的溢出定时,所以不定长就各种分包,
不是字节&字节的定时超时,不知道理解对否

martinhu 发表于 2023-2-10 16:29

kktron 发表于 2023-2-10 09:28
像ST的普通定时器,定义1ms超时,每收到一字节超时清0定时器,比如配合115200bps
4ms 每byte进来,就空闲 ...

如果是F460或者F4A0的timer6,可能处理起来简单一点,如果是L17x,接收数据之后,需要(UART_RX)中断信号输出到timer6的硬件清零寄存器,把timer6的计数器清零。
而如果UART_Rx如果没有使能中断,那么要想办法在每次接收之后将RX中断标志清零,否则下次不会触发DMA或者触发timer6的硬件清零。
而F460或者F4A0,UART_RX可以是触发事件,可以不用每次必须清零标志。

kktron 发表于 2023-2-10 17:56

martinhu 发表于 2023-2-10 16:29
如果是F460或者F4A0的timer6,可能处理起来简单一点,如果是L17x,接收数据之后,需要(UART_RX)中断信 ...

谢谢!
TIM6配合DMA_UART0, 在170FAUA下可以了,定义了TIM6 4ms超时,现在没问题了

新的问题又出现2个,
1.PC1ms间隔 压力测试发300字节数据发现溢出Hardfault进入了。
    stcDmaCfg.enMode =DmaMskBlock;   
    stcDmaCfg.u16BlockSize = 0x01u;                  
    stcDmaCfg.u16TransferCnt = 800;
    stcDmaCfg.enTransferWidth = DmaMsk8Bit;   
    stcDmaCfg.u32DstAddress = (uint32_t)&g_uart0_obj.RxData;//RXData开的1024字节

    我理解不是800字节DMA   怎么也不会超过1024 数组吧?
   
还有一个就是 收到数据后,我串口就非DMA的去返回,抓包看断开严重

   while(tx_len--)
    {
      Uart_SendDataPoll(M0P_UART0, *tx_pBuf);
      tx_pBuf++;
    }

Uart_SendDataPoll(M0P_UART0, *tx_pBuf);为什么抓包看会断包的? 这是库函数,里面没动它。

en_result_t Uart_SendDataPoll(M0P_UART_TypeDef* UARTx, uint8_t u8Data)
{
    while(FALSE == Uart_GetStatus(UARTx,UartTxe))
    {}
    UARTx->SBUF_f.DATA = u8Data;
    while(FALSE == Uart_GetStatus(UARTx,UartTC))
    {}
    Uart_ClrStatus(UARTx,UartTC);      
    return Ok;
}

kktron 发表于 2023-2-10 18:00

本帖最后由 kktron 于 2023-2-10 18:09 编辑

这是测试170FAUA   TIM6配合DMA串口0,超时4ms接收不定长的代码。
共享出来大家 看看指出还有什么问题

//myuart.h文件里如下#defineUART0_TX_MAX_LEN128
#defineUART0_RX_MAX_LEN(128+512)

void uart0_init(void);
void uart0_GpioCfg(void);
void uart0_BaseCfg(void);
void uart0_DmaCfg(void);
void uart0_Time6Cfg(uint16_t tPeriod);
void Uart0_SendData(uint8_t *tx_pBuf, uint16_t tx_len);

//uart0状态结构体
typedef struct
{
      __IO uint8_tRxFinished;      
      __IO uint8_tTxData;
      __IO uint8_tRxData;
      __IO uint8_tRxCopy;
      __IO uint16_t TxCnt;
      __IO uint16_t RxCnt;
      __IO uint16_t RxNow;
}my_stc_uart_t;

extern my_stc_uart_tg_uart0_obj;


//myuart.c文件里如下
my_stc_uart_tg_uart0_obj;

/**
******************************************************************************
** \briefuart0_init
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_init(void)
{
    uart0_GpioCfg();
    uart0_BaseCfg();
    uart0_DmaCfg();
    uart0_Time6Cfg(3000); //3000*(1/48M)*64分频 = 0.004s =4ms)24MHz外接晶振倍频到最高48MHz
}
/**
******************************************************************************
** \briefuart0_GpioCfg
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_GpioCfg(void)
{
    stc_gpio_cfg_t stcGpioCfg;

    DDL_ZERO_STRUCT(stcGpioCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //使能GPIO模块时钟

    ///<TX
    stcGpioCfg.enDir = GpioDirOut;
    Gpio_Init(GpioPortA, GpioPin9, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin9, GpioAf1); //配置PA09 端口为URART1_TX
    ///<RX
    stcGpioCfg.enDir = GpioDirIn;
    Gpio_Init(GpioPortA, GpioPin10, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin10, GpioAf1);//配置PA10 端口为URART1_RX
}
/**
******************************************************************************
** \briefuart0_BaseCfg
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_BaseCfg(void)
{
    ///< 串口参数配置
    stc_uart_cfg_t    stcCfg;
          stc_uart_multimode_t stcMulti;
    stc_uart_baud_t   stcBaud;

    DDL_ZERO_STRUCT(stcCfg);
          DDL_ZERO_STRUCT(stcMulti);
    DDL_ZERO_STRUCT(stcBaud);
    ///< 开启外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);///<使能uart0模块时钟

    ///<UART Init
    stcCfg.enRunMode      = UartMskMode1;          ///<模式1
    stcCfg.enStopBit      = UartMsk1bit;         ///<1bit停止位
    stcCfg.enMmdorCk      = UartMskDataOrAddr;   ///<无校验

    stcCfg.stcBaud.u32Baud= 115200;                ///<波特率115200,@48MHz 下0.16%误差

    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;       ///<通道采样分频配置
    stcCfg.stcBaud.u32Pclk= Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值
    Uart_Init(M0P_UART0, &stcCfg);                   ///<串口初始化

    M0P_UART0->SCON_f.DMARXEN = 1; //DMA_RX使能允许

    ///<UART中断使能
    Uart_ClrStatus(M0P_UART0,UartRC);          ///<清接收请求
    Uart_ClrStatus(M0P_UART0,UartTC);          ///<清发送请求
                Uart_DisableIrq(M0P_UART0,UartTxIrq);      ///<禁止串口发送中断
    Uart_EnableIrq(M0P_UART0,UartRxIrq);       ///<使能串口接收中断
    Uart_EnableIrq(M0P_UART0,UartFEIrq);       ///<帧错误中断使能
    EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE); ///<系统中断使能
}
/**
******************************************************************************
** \briefuart0_DmaCfg
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void uart0_DmaCfg(void)
{
    stc_dma_cfg_t   stcDmaCfg;

    DDL_ZERO_STRUCT(stcDmaCfg);
    Sysctrl_SetPeripheralGate(SysctrlPeripheralDma, TRUE);      //ADT外设时钟使能

    //DMA_Ch0_RX
    stcDmaCfg.enMode =DmaMskBlock;                            //选择块传输
    stcDmaCfg.u16BlockSize = 0x01u;                           //块传输个数
    stcDmaCfg.u16TransferCnt = UART0_RX_MAX_LEN;                //Block模式,一次传输数据大小为 8(BlockSize),传输1次
    stcDmaCfg.enTransferWidth = DmaMsk8Bit;                     //传输数据的宽度,此处选择字(8Bit)宽度
    stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrFix;               //源地址固定
    stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc;               //目的地址自增
    stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadDisable; //禁止重新加载传输目的地址
    stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadDisable;//禁止重新加载传输源地址
    stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadDisable;   //禁止能重新加载BC/TC值
    stcDmaCfg.u32SrcAddress = (uint32_t)&(M0P_UART0->SBUF);   //指定传输源地址
    stcDmaCfg.u32DstAddress = (uint32_t)&g_uart0_obj.RxData; //指定传输目的地址
    stcDmaCfg.enTransferMode = DmaMskContinuousTransfer;      //DMAC 在传输完成时清除 CONFA:ENS 位。
    stcDmaCfg.enRequestNum = DmaUart0RxTrig;                        //设置为Uart0Rx触发
    stcDmaCfg.enPriority = DmaMskPriorityFix;                   //DMA 各通道优先级固定 (CH0>CH1)
    Dma_InitChannel(DmaCh0,&stcDmaCfg);                              //初始化DMA通道0

    Dma_Enable();
    Dma_EnableChannel(DmaCh0);
    Uart_ClrStatus(M0P_UART0,UartRC);
}
/**
******************************************************************************
** \briefuart0_Time6Cfg
** \paramtPeriod
** \retval 无
** \retval 无
******************************************************************************/
void uart0_Time6Cfg(uint16_t tPeriod)
{
    stc_adt_basecnt_cfg_t   stcAdtBaseCntCfg;
    stc_adt_aos_trig_cfg_tstcAdtAosTrigCfg;

    DDL_ZERO_STRUCT(stcAdtBaseCntCfg);
    DDL_ZERO_STRUCT(stcAdtAosTrigCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdvTim, TRUE); //ADT外设时钟使能

    stcAdtBaseCntCfg.enCntMode = AdtSawtoothMode;
    stcAdtBaseCntCfg.enCntDir = AdtCntUp;
    stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0Div64;
    Adt_Init(M0P_ADTIM6, &stcAdtBaseCntCfg);               //ADT载波、计数模式、时钟配置

    Adt_SetPeriod(M0P_ADTIM6, tPeriod);                      //周期设置

    stcAdtAosTrigCfg.enAos0TrigSrc = AdtAosxTrigSelUart0Int; //AOS0选择UART0中断
    Adt_AosTrigCfg(&stcAdtAosTrigCfg);

    Adt_CfgHwStart(M0P_ADTIM6, AdtHwTrigAos0);               //AOS0事件触发TIM6启动
    Adt_CfgHwClear(M0P_ADTIM6, AdtHwTrigAos0);               //AOS0事件 清零TIM6

    Adt_EnableHwStart(M0P_ADTIM6);                           //硬件启动使能
    Adt_EnableHwClear(M0P_ADTIM6);                           //硬件清零使能

    Adt_ClearAllIrqFlag(M0P_ADTIM6);
    Adt_CfgIrq(M0P_ADTIM6, AdtOVFIrq, TRUE);               //配置TIM6 上溢中断
    EnableNvic(ADTIM6_IRQn, IrqLevel0, TRUE);
}
/**
******************************************************************************
** \briefUART0 数据发送
** \paramtx_pBuf,tx_len
** \retval 无
** \retval 无
******************************************************************************/
void Uart0_SendData(uint8_t *tx_pBuf, uint16_t tx_len)
{
    while(tx_len--)
    {
      Uart_SendDataPoll(M0P_UART0, *tx_pBuf);
      tx_pBuf++;
    }
}
/**
******************************************************************************
** \briefUart0_IRQHandler
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void Uart0_IRQHandler(void)
{
    if(Uart_GetStatus(M0P_UART0,UartRC))
    {
      Uart_ClrStatus(M0P_UART0, UartRC);
    }
    if(Uart_GetStatus(M0P_UART0,UartFE))
    {
      Uart_ClrStatus(M0P_UART0, UartFE);
    }
}

/**
******************************************************************************
** \briefTim6_IRQHandler
** \param无
** \retval 无
** \retval 无
******************************************************************************/
void Tim6_IRQHandler(void)
{
    Adt_StopCount(M0P_ADTIM6);
    if(TRUE == Adt_GetIrqFlag(M0P_ADTIM6, AdtOVFIrq))
    {
      Dma_DisableChannel(DmaCh0);

      g_uart0_obj.RxNow = (UART0_RX_MAX_LEN - 1) - M0P_DMAC->CONFA0_f.TC;
      if(g_uart0_obj.RxNow>=UART0_RX_MAX_LEN)
      {
            g_uart0_obj.RxNow=0;
      }
      g_uart0_obj.RxCnt = g_uart0_obj.RxNow;

      for(uint16_t i = 0; i < g_uart0_obj.RxCnt; i++)
      {
            g_uart0_obj.RxCopy =g_uart0_obj.RxData;
      }

      Dma_SetTransferCnt(DmaCh0, UART0_RX_MAX_LEN);
      Dma_SetDestinationAddress(DmaCh0, (uint32_t)&g_uart0_obj.RxData);
      Dma_EnableChannel(DmaCh0);
      Uart_ClrStatus(M0P_UART0,UartRC);

      g_uart0_obj.RxFinished = 1;
      Adt_ClearIrqFlag(M0P_ADTIM6, AdtOVFIrq);
    }
}

/******************************************************************************
* EOF (not truncated)
******************************************************************************/

//主函数.C里例如下
int main (void)
{
      ;略初始化
   while(1)
    {
       if(1 == g_uart0_obj.RxFinished)      {
            if(g_uart0_obj.RxCnt>0)
            {
                g_uart0_obj.TxCnt = g_uart0_obj.RxCnt;
               g_uart0_obj.RxCnt = 0;
                Uart0_SendData((uint8_t *)&g_uart0_obj.RxCopy,g_uart0_obj.TxCnt);
            }
            g_uart0_obj.RxFinished = 0;
      }
   }
}




martinhu 发表于 2023-2-16 09:25

kktron 发表于 2023-2-10 17:56
谢谢!
TIM6配合DMA_UART0, 在170FAUA下可以了,定义了TIM6 4ms超时,现在没问题了



收到数据后,最好用中断返回,不要用查询的方式

zljiu 发表于 2023-3-4 14:59

感觉这个超时的时间配置的不要过长太长了也没有用

tpgf 发表于 2023-3-4 15:25

kktron 发表于 2023-2-10 18:00
这是测试170FAUA   TIM6配合DMA串口0,超时4ms接收不定长的代码。
共享出来大家 看看指出还有什么问题
...

用查询模式太浪费资源了而且实时性也不太好

nawu 发表于 2023-3-4 15:41

martinhu 发表于 2023-2-16 09:25
收到数据后,最好用中断返回,不要用查询的方式

使用中断模式一定要注意中断函数的处理要干净

coshi 发表于 2023-3-4 16:07

kktron 发表于 2023-2-10 18:00
这是测试170FAUA   TIM6配合DMA串口0,超时4ms接收不定长的代码。
共享出来大家 看看指出还有什么问题
...

数据量不大的话感觉完全没有问题主函数轮序里边还发送了数据

磨砂 发表于 2023-3-4 16:21

请问在楼主的代码注释中,有一个是ADT载波这个是什么意思呢

晓伍 发表于 2023-3-4 16:32

磨砂 发表于 2023-3-4 16:21
请问在楼主的代码注释中,有一个是ADT载波这个是什么意思呢

ADT和数据类型实质上是一个概念.其区别是: ADT的范畴更广,它不再局限于系统已定义并实现的数据类型,还包括用户自己定义的数据类型
页: [1]
查看完整版本: HC32L170FAUA-TIM6关联串口超时问题