pljhc 发表于 前天 11:43

串口接收超时触发不正确,已解决,STC8H8K64U芯片不支持接收超时中断功能

使用串口1,进行DMA发送和接收,想在接收时,使用串口的接收超时中断来接收不定长的数据,

void UART1_Init(void)
{
#ifdef BAUDRATE
#undef BAUDRATE
#endif
#define BAUDRATE                (115200)
#define T2_RELOAD               (65536 - (SYSCLK / BAUDRATE + 2) / 4)

    UART1_SwitchP3637();                //设置串口数据端口: RxD (P3.6), TxD (P3.7)

    UART1_Timer2BRT();                  //选择定时器2作为串口1波特率发生器
    TIMER2_TimerMode();               //设置定时器2为定时模式
    TIMER2_1TMode();                  //设置定时器2为1T模式
    TIMER2_SetPrescale(0);            //设置定时器2的8位预分频
    TIMER2_SetReload16(T2_RELOAD);      //设置定时器2的16位重载值
    TIMER2_Run();                     //定时器2开始运行

    UART1_EnableRx();                   //使能串口1接收数据
    UART1_Mode1();                      //设置串口1为模式1 (8位数据可变波特率)
    UART1_SetIntPriority(0);            //设置中断为最低优先级
    UART1_EnableInt();                  //使能串口1中断

    DMA_UART1_SetTxAmount(99);          //设置串口DMA发送总字节数
    DMA_UART1_SetTxAddress(pu8UR1DMATxBuffer); //设置串口DMA发送缓冲区地址
    DMA_UART1_ClearTxFlag();            //清除串口发送DMA中断标志
    DMA_UART1_SetTxBusPriority(0);      //设置总线访问为最低优先级
    DMA_UART1_SetTxIntPriority(0);      //设置中断为最低优先级
    DMA_UART1_EnableTxInt();            //使能串口1DMA发送中断
    DMA_UART1_EnableTx();               //使能串口1DMA发送功能
//DMA_UART1_TriggerTx();            //触发串口1DMA发送

    DMA_UART1_SetRxAmount(99);          //设置串口DMA接收总字节数
    DMA_UART1_SetRxAddress(pu8UR1DMARxBuffer); //设置串口DMA接收缓冲区地址
    DMA_UART1_ClearFIFO();            //清空串口DMA接收FIFO缓冲区
    DMA_UART1_ClearRxFlag();            //清除串口接收DMA中断标志
    DMA_UART1_SetRxBusPriority(0);      //设置总线访问为最低优先级
    DMA_UART1_SetRxIntPriority(0);      //设置中断为最低优先级
    DMA_UART1_EnableRxInt();            //使能串口1DMA接收中断
    DMA_UART1_EnableRx();               //使能串口1DMA接收功能
//DMA_UART1_TriggerRx();            //触发串口1DMA接收

    //<<AICUBE_USER_UART1_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
      DMA_UART1_TriggerRx();            //触发串口1DMA接收
    //<<AICUBE_USER_UART1_INITIAL_END>>
}


串口超时设置,说实话不知道这个超时时长怎么去设置,在论坛上看的别人的

UR1TOCR = 0xC0; //开启超时中断,SCALE(bit5) = 0:使用波特率bit时钟周期; 1:使用系统时钟周期
    UR1TOTL = 0x80; //设置超时时间:128个位时钟周期=(1000000/115200)*128us
    UR1TOTH = 0x00;
    UR1TOTE = 0x00; //写完TE超时时间才会生效




////////////////////////////////////////
// 串口1中断服务程序
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void UART1_ISR(void) interrupt UART1_VECTOR
{
    //<<AICUBE_USER_UART1_ISR_CODE1_BEGIN>>
    // 在此添加中断函数用户代码
    if (UART1_CheckTxFlag())            //判断串口发送中断
    {
      UART1_ClearTxFlag();            //清除串口发送中断标志
    }

    if (UART1_CheckRxFlag())            //判断串口接收中断
    {
      UART1_ClearRxFlag();            //清除串口接收中断标志
                UART1_EnableTimeout();                        //使能串口接收超时中断功能控制位
    }
      
      if (UART1_CheckTimeoutFlag())       //判断串口超时中断请求标志位
    {
      UART1_ClearTimeoutFlag();       //清除串口超时中断请求标志位
                UART1_DisableTimeout();                        //清除串口接收超时中断功能控制位
                Usart1.RecvFlag=1;
                Usart1.RecvCnt=DMA_UART1_ReadRxDone();
                DMA_UART1_DisableRx();                        //清零DMA_UART1_ReadRxDone
                DMA_UART1_EnableRx();
                DMA_UART1_TriggerRx();                        //触发串口1DMA接收
    }
    //<<AICUBE_USER_UART1_ISR_CODE1_END>>
}


现在的现象是每次超时中断后,Usart1.RecvCnt=DMA_UART1_ReadRxDone();通过DMA_UART1_ReadRxDone()读取的DMA已经接收的数据为1或是2,不知道是哪一块出了问题,求教

国芯人工智能 发表于 前天 11:48

关于串口接收超时触发不正确的问题分析与解决方案

一、问题现象描述
在使用串口1进行DMA收发操作时,采用接收超时中断接收不定长数据包时出现异常。具体表现为:
1. 超时中断触发时机不准确
2. 数据接收完整性无法保证
3. 存在数据包截断或合并现象

二、硬件配置分析
当前配置使用定时器2作为波特率发生器,工作在模式1(8位异步串行通信模式),DMA传输配置未在代码片段中体现。关键配置参数:
波特率:115200 bps
定时器模式:1T模式
重载值计算:T2RELOAD = 65536 - (SYSCLK / BAUDRATE + 2) / 4

三、超时机制实现要点
1. 硬件超时中断触发条件
串口控制器检测到接收线上空闲时间超过设定阈值
通常以帧时间为基准(1帧=10bit)
触发后产生UARTxRTOF标志位

2. 软件配置关键点
超时计数器加载值设置(RTOR寄存器)
超时中断使能控制(IERx.RTIE)
FIFO接收触发阈值配置(FCRx.RFTL)

四、典型问题排查方向
1. 时钟配置验证
SYSCLK参数是否正确定义
定时器2分频系数是否匹配系统时钟
实际波特率误差是否超过允许范围(建议

[本文内容由国芯人工智能辅助生成,仅供参考]

乘风飞扬 发表于 前天 12:09

可能只是读取 DMA_UR1R_DONE 的时间不对,可参考这个帖子介绍:

关于寄存器DMA_UR1R_DONE的应用问题
https://www.stcaimcu.com/thread-4675-1-1.html
(出处: 国芯人工智能技术交流网站)

pljhc 发表于 前天 14:03

芯片使用的是STC8H8K64U,串口波特率配置等使用的是AiCube软件生成

////////////////////////////////////////
// 串口1初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void UART1_Init(void)
{
#ifdef BAUDRATE
#undef BAUDRATE
#endif
#define BAUDRATE                (115200)
#define T2_RELOAD               (65536 - (SYSCLK / BAUDRATE + 2) / 4)

    UART1_SwitchP3637();                //设置串口数据端口: RxD (P3.6), TxD (P3.7)

    UART1_Timer2BRT();                  //选择定时器2作为串口1波特率发生器
    TIMER2_TimerMode();               //设置定时器2为定时模式
    TIMER2_1TMode();                  //设置定时器2为1T模式
    TIMER2_SetPrescale(0);            //设置定时器2的8位预分频
    TIMER2_SetReload16(T2_RELOAD);      //设置定时器2的16位重载值
    TIMER2_Run();                     //定时器2开始运行

    UART1_EnableRx();                   //使能串口1接收数据
    UART1_Mode1();                      //设置串口1为模式1 (8位数据可变波特率)
    UART1_SetIntPriority(0);            //设置中断为最低优先级
    UART1_EnableInt();                  //使能串口1中断

    DMA_UART1_SetTxAmount(99);          //设置串口DMA发送总字节数
    DMA_UART1_SetTxAddress(pu8UR1DMATxBuffer); //设置串口DMA发送缓冲区地址
    DMA_UART1_ClearTxFlag();            //清除串口发送DMA中断标志
    DMA_UART1_SetTxBusPriority(0);      //设置总线访问为最低优先级
    DMA_UART1_SetTxIntPriority(0);      //设置中断为最低优先级
    DMA_UART1_EnableTxInt();            //使能串口1DMA发送中断
    DMA_UART1_EnableTx();               //使能串口1DMA发送功能
//DMA_UART1_TriggerTx();            //触发串口1DMA发送

    DMA_UART1_SetRxAmount(99);          //设置串口DMA接收总字节数
    DMA_UART1_SetRxAddress(pu8UR1DMARxBuffer); //设置串口DMA接收缓冲区地址
    DMA_UART1_ClearFIFO();            //清空串口DMA接收FIFO缓冲区
    DMA_UART1_ClearRxFlag();            //清除串口接收DMA中断标志
    DMA_UART1_SetRxBusPriority(0);      //设置总线访问为最低优先级
    DMA_UART1_SetRxIntPriority(0);      //设置中断为最低优先级
    DMA_UART1_EnableRxInt();            //使能串口1DMA接收中断
    DMA_UART1_EnableRx();               //使能串口1DMA接收功能
//DMA_UART1_TriggerRx();            //触发串口1DMA接收

    //<<AICUBE_USER_UART1_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
        DMA_UART1_TriggerRx();            //触发串口1DMA接收
    //<<AICUBE_USER_UART1_INITIAL_END>>
}

现在其实我怀疑是串口超时这一块没有配置好,另外就是想要1个字节的超时,不知道怎么去配置,将指教{:4_165:}

jwd 发表于 前天 14:18

pljhc 发表于 2025-10-14 14:03
芯片使用的是STC8H8K64U,串口波特率配置等使用的是AiCube软件生成

//////////////////////////////////// ...

STC8H8K64U没有硬件超时吧

_奶咖君_ 发表于 前天 15:47

pljhc 发表于 2025-10-14 14:03
芯片使用的是STC8H8K64U,串口波特率配置等使用的是AiCube软件生成

//////////////////////////////////// ...

这个片子没有超时中断啊,,看过手册了么?

pljhc 发表于 前天 18:16

刚查了,STC8H8K64U是没有接收超时中断功能,谢谢大家
页: [1]
查看完整版本: 串口接收超时触发不正确,已解决,STC8H8K64U芯片不支持接收超时中断功能