完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
代码:全选
#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/rmt.h" #include "driver/periph_ctrl.h" #include "soc/rmt_reg.h" void app_main() { rmt_config_t rmt_rx = { .channel = 0, .gpio_num = 17, .clk_div = 80, //1MHz .mem_block_num = 1, .rmt_mode = RMT_MODE_RX, .rx_config.filter_en = true, .rx_config.filter_ticks_thresh = 100, .rx_config.idle_threshold = 9500 }; rmt_config(&rmt_rx); rmt_driver_install(rmt_rx.channel, 1000, 0); RingbufHandle_t rb = NULL; rmt_get_ringbuf_handle(rmt_rx.channel, &rb); rmt_rx_start(rmt_rx.channel, 1); while(rb) { size_t rx_size = 0; rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 1000); if(item) { for (int i = 0; i < rx_size>>2; i++) { printf("%d:%dus %d:%dus\n", (item+i)->level0, (item+i)->duration0, (item+i)->level1, (item+i)->duration1); } vRingbufferReturnItem(rb, (void*) item); } else { break; } } } 如果我在 64Hz 时在引脚 17 上给它一个 75% 的占空比,我得到预期的输出,除了占空比的较短的 25% 部分有一个周期值,而较长的 75% 部分高于 9500us 超时: 代码:全选 0:3906us 1:0us 0:3906us 1:0us 0:3907us 1:0us 0:3906us 1:0us 0:3906us 1:0us 0:3906us 1:0us 0:3906us 1:0us 0:3906us 1:0us 0:3906us 1:0us 0:3906us 1:0us 0:3907us 1:0us 我想使用 30000us 超时(这在 1MHz 的 15 位计数器上应该是可能的)但是当 11000us 工作时,12000us 或更高会给出错误: 代码:全选 E (2016) rmt: RMT[0] ERR E (2016) rmt: status: 0x13000040 令人惊讶的是,如果我在引脚 17 上以 128Hz 的频率馈送它,或者如果我在不按比例降低空闲阈值的情况下增加 clk_div,我会得到类似的错误。 代码:全选 E (1014) rmt: RMT[0] ERR E (1014) rmt: status: 0x13000040 我希望最小输入频率被检测为 33Hz,因此 1MHz 时钟和预期的 30000us 空闲阈值。我想用微秒分辨率测量周期。 还尝试过:不同的 GPIO、不同的 RMT 通道、不同的 CPU 速度、不同的 FreeRTOS 节拍率、启用详细日志记录并通过回读检查寄存器是否被正确写入。 idle_threshold 超过 11000 到 12000 之间的值的错误仅在连接了脉冲串输入的输入时发生。问题似乎是低于 idle_threshold 的有效第二个周期。 我现在已经进行了 2 天,想法用完了,但会发布更多数据。 没有启用环形缓冲区,没有问题,但我需要做一些工作来获得一个在没有环形缓冲区的情况下获取数据的示例。似乎零周期的接收端中断不合适,因为在我想要连续测量脉冲序列的周期和频率的情况下,这将是一个错误条件。 这个非常快速和肮脏的示例用于读取周期并允许 idle_threshold 的预期设置。它没有使用环形缓冲区,只是简单地读取接收缓冲区中的第一个条目并重置,因此任务延迟和频率纠缠在一起。 代码:全选 #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/rmt.h" #include "driver/periph_ctrl.h" #include "soc/rmt_reg.h" void app_main() { rmt_config_t rmt_rx = { .channel = 0, .gpio_num = 18, .clk_div = 80, //1MHz .mem_block_num = 1, .rmt_mode = RMT_MODE_RX, .rx_config.filter_en = true, .rx_config.filter_ticks_thresh = 255, .rx_config.idle_threshold = 65535 }; rmt_config(&rmt_rx); while (1) { rmt_rx_start(rmt_rx.channel, 1); vTaskDelay(100 / portTICK_PERIOD_MS); rmt_item32_t* item = (rmt_item32_t*) (RMT_CHANNEL_MEM(rmt_rx.channel)); printf("high %dus | ", (item)->level0*(item)->duration0 + (item)->level1*(item)->duration1); printf("low %dus\n", !(item)->level0*(item)->duration0 + !(item)->level1*(item)->duration1); } } 经过多天的工作,我认为我看到的错误是缓冲区已满,这是基于我自己的 5ms 任务处理 RMT 接收缓冲区和我得到的错误代码的实验。错误代码未记录。 如果环形缓冲区能够在任务而不是中断中实现,它就可以工作,但是将 idle_threshold 提高到输入脉冲周期以上意味着不会触发中断。 换句话说,环形缓冲区不能用于连续脉冲序列(比 RMT 接收缓冲区长)。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
1912个成员聚集在这个小组
加入小组我的项目我做主,使用GN+Ninja来完成构建系统(VSCode开发RT106X)
36362 浏览 0 评论
NXP IMX8应用处理器快速入门必备:技巧、使用、设计指南
4400 浏览 0 评论
6055 浏览 1 评论
6765 浏览 0 评论
NXP i.MX6UL开发板(linux系统烧录+规格+硬件+模块移植)使用手册
4217 浏览 0 评论
620浏览 2评论
求助,S32G上Core M启动后如何让Core A在Flash指定位置加载uboot?
618浏览 2评论
ESP32-WROVER-IE + LAN8720以太网,GPIO0电压只有1.6v,无法正常进入spi flash boot模式如何解决?
609浏览 2评论
求分享适用于PN7160 Android的NFC工厂测试应用程序
695浏览 2评论
799浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 06:54 , Processed in 0.996089 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号