串口接收超时触发不正确,已解决,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,不知道是哪一块出了问题,求教
关于串口接收超时触发不正确的问题分析与解决方案
一、问题现象描述
在使用串口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分频系数是否匹配系统时钟
实际波特率误差是否超过允许范围(建议
[本文内容由国芯人工智能辅助生成,仅供参考] 可能只是读取 DMA_UR1R_DONE 的时间不对,可参考这个帖子介绍:
关于寄存器DMA_UR1R_DONE的应用问题
https://www.stcaimcu.com/thread-4675-1-1.html
(出处: 国芯人工智能技术交流网站)
芯片使用的是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:} pljhc 发表于 2025-10-14 14:03
芯片使用的是STC8H8K64U,串口波特率配置等使用的是AiCube软件生成
//////////////////////////////////// ...
STC8H8K64U没有硬件超时吧 pljhc 发表于 2025-10-14 14:03
芯片使用的是STC8H8K64U,串口波特率配置等使用的是AiCube软件生成
//////////////////////////////////// ...
这个片子没有超时中断啊,,看过手册了么? 刚查了,STC8H8K64U是没有接收超时中断功能,谢谢大家
页:
[1]