完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
小弟在线程中每隔50ms绝对值使用rt_pwm_set()调整一次pwm的周期,发现会有很明显的杂波。把间隔时间从50ms调整为500ms后确认确实是切换周期引起的杂波,之前用io口采用延时拉高拉低的方式没有这个杂波。有没有遇到同样问题的大佬们给个建议!
1.以下是线程初始化代码
2.以下是数组和线程内部代码
|
|
相关推荐
1个回答
|
|
|
根据问题描述,用户在RT-Thread中创建了一个线程,每隔50ms使用`rt_pwm_set`调整PWM周期,结果产生了杂波。当将间隔时间增加到500ms时,确认杂波是由于周期切换引起的。之前用IO口模拟PWM(延时拉高拉低)没有这个问题。 可能的原因: 1. 在调整PWM周期时,PWM设备可能没有正确地在波形周期的合适时机切换参数,导致产生毛刺。 2. 线程调度或定时器的不精确性可能导致调整PWM周期的时间点与PWM波形周期不同步,从而产生杂波。 解决方案建议: 1. 检查PWM设备驱动:确认驱动是否支持在运行过程中动态改变周期,并且驱动内部在改变周期时是否有同步机制(比如在周期结束或开始时更新)。有些PWM硬件要求在特定的时刻(如计数器为0)更新周期和占空比,以避免毛刺。 2. 同步调整:在改变PWM周期时,最好在PWM周期结束(或开始)的瞬间进行更新。但是,RT-Thread的PWM框架并没有直接提供这样的同步机制。因此,可能需要通过其他方式实现,例如: - 在调整之前先停止PWM,设置新参数,然后重新启动PWM。但这会导致PWM输出短暂停止,可能不是理想方案。 - 如果硬件支持,使用双缓冲机制:设置新的周期和占空比,然后等待当前周期结束,再自动切换新参数。这需要硬件支持以及驱动实现。 3. 调整线程优先级:提高PWM控制线程的优先级,确保它能够及时运行,避免由于线程调度延迟导致更新时机不准确。 4. 调整时机:尝试在PWM周期的开始(比如通过捕获中断)进行参数更新,但这需要额外的硬件支持(如捕获中断)和更复杂的软件设计。 5. 使用硬件特性:如果使用的微控制器支持PWM的同步更新(例如STM32的TIMx_EGR中的UG位可以产生更新事件来同步更新周期和占空比),则可以在驱动中实现这个特性。 针对RT-Thread的PWM框架,可以尝试以下步骤: 步骤1:在设置PWM之前先停止PWM,设置后再启动(可能会有短暂停顿,但可以避免毛刺): rt_pwm_disable(pwm_dev, pwm_channel); // 先关闭 rt_pwm_set(pwm_dev, pwm_channel, period, pulse); // 设置新参数 rt_pwm_enable(pwm_dev, pwm_channel); // 重新使能 步骤2:如果步骤1不能接受(因为PWM输出会中断),那么可能需要查看具体硬件驱动是否支持在周期结束时自动更新参数。例如,在STM32的驱动中,我们可以配置为在更新事件时修改周期和占空比,这样更新会发生在下一个周期开始。 步骤3:如果驱动不支持,可能需要修改驱动以支持同步更新。 另外,用户提到之前用IO模拟没有杂波,可能是因为IO模拟时,切换发生在软件控制的精确时刻(虽然可能不如硬件PWM精确,但没有硬件切换的中间状态)。而硬件PWM在改变参数时,如果硬件正在输出,可能会打断当前周期。 因此,建议先尝试在设置参数前先停止PWM,设置后再启动,观察是否还有杂波。如果问题解决,但无法接受PWM的短暂停止,则需要考虑修改驱动或使用硬件同步更新。 此外,还需要注意,频繁地改变PWM周期(50ms一次)可能会带来一定的系统开销,而且如果PWM周期本身很短(比如20kHz的PWM,周期50us),那么50ms内会经历1000个周期,在改变周期时出现一个杂波可能影响不大。但如果PWM周期较长,则杂波的影响可能更明显。 如果问题仍然存在,请检查具体的PWM驱动实现,确保在设置新周期时,硬件寄存器的更新是在安全的时候进行的。 由于用户没有提供具体的硬件和驱动,以上是一般性建议。 示例代码修改: 将原来的线程中直接调用`rt_pwm_set`改为先停止、设置、再启动(注意:这样会导致每次设置都会有一个PWM输出的停顿,根据应用需求决定是否可接受): ```c static void tens_thread_entry(void *parameter) { rt_device_t pwm_dev = RT_NULL; pwm_dev = rt_device_find(PWM_DEV_NAME); if (pwm_dev == RT_NULL) { rt_kprintf("pwm sample run failed! can't find %s device!n", PWM_DEV_NAME); return; } while (1) { // 假设需要设置的周期和占空比 rt_uint32_t period = ...; // 新周期 rt_uint32_t pulse = ...; // 新占空比 // 先停止PWM rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL); // 设置新参数 rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); // 重新使能 rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); rt_thread_mdelay(50); // 等待50ms } } ``` 如果这样操作后杂波消失,但出现PWM输出中断(可能是一个低电平),那么说明问题解决了,但带来了新的问题(中断)。这时需要权衡,或者寻找更好的方法。 如果硬件支持,另一种方法是在驱动中实现“影子寄存器”,即设置新参数后,硬件会在当前周期结束时自动更新。这需要修改驱动。以STM32为例,可以在驱动中配置为使用预装载寄存器,然后设置新的周期和占空比,最后通过设置TIMx_EGR寄存器的UG位来更新寄存器(或者在驱动中等待更新事件标志)。具体实现需要参考硬件手册和现有驱动。 由于RT-Thread的PWM驱动框架没有强制要求这种同步机制,所以可能需要用户自行扩展驱动。 总结: 1. 先尝试停止-设置-启动的方法,看是否解决问题(尽管可能有短暂停顿)。 2. 如果不可接受,则需要修改PWM驱动,利用硬件同步更新机制。 希望这些建议能帮助解决问题。 针对使用 问题根源分析
解决方案1. 启用硬件影子寄存器(推荐)
2. 调整参数更新时机(软件同步)
3. 降低更新频率
4. 优化线程优先级
5. 使用单次触发模式(高级)
验证步骤
备选方案若以上方法无效,可考虑:
|
|
|
|
|
只有小组成员才能发言,加入小组>>
184个成员聚集在这个小组
加入小组rtstudio是否可像keil加载ini解决虚拟串口与mcu串口通讯?
1212 浏览 0 评论
【Vision Board创客营连载体验】基于RA8D1-Vision Board的自动路径规划小车
1776 浏览 1 评论
【Vision Board创客营连载体验】基于Vision Board的垃圾分类
2156 浏览 0 评论
【Vision Board创客营连载体验】使用 Vision Board 做一个 UVC Camera
1777 浏览 0 评论
【Vision Board创客营连载体验】TinyMaix进行手写数字识别
2006 浏览 0 评论
1465浏览 5评论
在RT-Thread Studio中新建的stm32f407-atk-explorer工程运行qemu失败,是什么原因引起的?
1767浏览 3评论
为什么rt_device_read()只能读取到两个字节数据?
364浏览 3评论
连得上热点,但是ping baidu.com出现timeout,请问跟什么有关?
422浏览 3评论
421浏览 2评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 01:10 , Processed in 0.588682 second(s), Total 47, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2383
