完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我有一个简单的程序,它从UART接口接收数据并驱动WS2812b LED灯条。因此,我使用USART3接收数据(在IRQ模式下)和T3C2(定时器3,通道2)来驱动LED。这是代码: 如果我在没有启用计时器的情况下使用uart接口,一切工作都很完美,但是当我启用计时器时,我开始丢失数据。例如,这里是日志,如果我发送5个类似的32字节数据包[0x41..0x60]
每次丢失3~4个字节。 我尝试使用不同的波特率,不同的usart端口 - 结果是一样的。计时器间隔在第142行中设置: timer_set_period(TIM3, WSP);哪里 #define TICK_NS (1000/72)#define WSP (1300 / TICK_NS)如果我注释掉这一行,问题就会消失,但是,当然,如果没有它,我将无法驱动LED。 因此,看起来我无法同时驱动WS2812b LED并从UART接收数据。这应该是这样的吗?知道我该如何修复它?
|
|
相关推荐
11个回答
|
|
首先确定您是否正在查看硬件故障(例如:由于LED的PWM导致的损坏帧)或软件故障(例如:某处停止太长时间)。提示:USART_SR-> ORE。
|
|
|
|
谢谢!是的,当我丢失数据时,我收到了USART_SR_ORE标志。有没有办法找到超限的原因?
|
|
|
|
我有一些数据丢失和(高波特率)UART的经验。唯一好的解决方案似乎是使用UART的最高中断优先级(以及仅用于UART),并确保仅在非常短的持续时间内禁用UART IRQ(例如,在评估接收缓冲区时)。在我的情况下,我无法使用DMA,因为我不知道我会收到多少字节。
|
|
|
|
看着这个
#define TICK_NS (1000/72) #define WSP (1300 / TICK_NS) 你的计时器需要大约100步(如果我从规格中得到它)然后运行你告诉它的任何例行程序。我无法清楚地看到你的程序需要多少时间才能完成一个步骤,但似乎你的计时器例程应该经常运行(每秒偶数1000次或更多)。 现在,如果您的uart例程在没有计时器的情况下按预期工作,但在引入时丢失数据,则强烈建议计时器中断您的串行通信。 这可能是因为: 你的计时器例程经常运行 计时器例程太长 定时器中断的优先级高于uart中断。 或者可能将它们全部放在一起。 可能的解决方案: STM32具有称为NVIC(嵌套矢量中断控制器)的东西,您可以使用它来更改中断优先级。 当你使用两个或多个中断时,你必须考虑它们几乎可以在同一时间运行(这种情况在两个中断以相似的频率运行时更常发生),并且一个例程可能因此而丢失信息(特别是使用uart)。所以你必须想办法处理这个明确的案例 - >锁定机制或改变优先级。 您的日常工作时间越长,您输入第二点所述情况的可能性就越高。通常的做法是使中断例程尽可能短,并且永远不要在中断中使用延迟或循环。 考虑是否有一种方法可以更少地运行您的计时器例程。这样你至少可以最大限度地减少数据丢失的可能性,但是要完全排除它,你将不得不做第1-3点中描述的事情。 |
|
|
|
可能的解决方案5:考虑不使用中断来驱动LED灯条。特别是如果时间不重要,那么应该等到主循环中的某个时间点。
|
|
|
|
与增加中断优先级不一样?
|
|
|
|
谢谢你的回答!测量调试定时器频率的时间间隔以及评估中断处理程序例程的运行时间的最佳方法是什么?
|
|
|
|
实际上应该很容易找出你的“timerclock”滴答的速度,如果你没有改变你应该在数据表中找到值的设置,它可能与你的quarz或外部时钟频率(或者你的任何频率)相同使用),也许使用一套预分频器。但是,如果你想测量它,我建议每次调用timerroutine时切换一个IO引脚,并将引脚连接到示波器。调试器也可以告诉你程序中的命令需要多长时间,但由于我使用了不同的编程工具,我遗憾地无法给你任何有用的提示如何继续
|
|
|
|
在某种程度上它是相同的,因为无论哪种情况都没有阻止你的中断。然而,尝试使用尽可能少的IRQ并使它们尽可能小(例如,只唤醒μC并为主循环中的实际处理设置标志)具有消除竞争条件潜力的额外好处。这样,您也可以始终相信您的处理以相同的顺序发生(在主循环中)。很明显,当我这样提到它时,但想象一下,如果你突然决定在IRQ(以及其他地方)使用UART调试打印,会发生什么。
|
|
|
|
我认为问题是定时器中断例程所花费的时间,而您尚未配置优先级。要么使定时器程序足够有效,要么为UART制作DMA缓冲区,或者提高uart中断的优先级(较低优先级数)(这可能意味着显示器上出现视觉毛刺,在这种情况下,定时器代码的关键部分为非 - 可中断并查看是否足以帮助UART)
您也可以在一个定时器中断例程中统一所有这些。您可以使UART的定时器频率足够快,而不使用DMA缓冲器并轮询它并运行较低频率的正常定时器代码,或者制作DMA缓冲区并按照正常代码需要运行定时器并轮询UART缓冲区。与过程模式中的轮询相比,这使得事物更具确定性。 |
|
|
|
谢谢你的回答!看起来优先级调整对我有用,但我要在中断例程中做一些更改
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1712 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
887 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1269 浏览 1 评论
LL库F030进行3个串口收发,2个串口为232,一个为485,长时间后,会出现串口1停止运行,另外两个正常,只有重启复原
1740 浏览 1 评论
552 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-13 15:50 , Processed in 0.732059 second(s), Total 62, Slave 55 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号