赞
踩
RMT(远程控制)模块驱动器可用于发送和接收红外远程控制信号。由于RMT模块的灵活性,该驱动器还可用于产生或接收许多其他类型的信号。
该信号由一系列脉冲组成,由RMT的发射器根据一系列数值产生。这些数值定义了脉冲持续时间 和二进制电平,见下文。发射器也可以提供一个载波,并用提供的脉冲对其进行调制。
反向操作由接收器执行,一系列的脉冲被解码成一个包含脉冲持续时间和二进制电平的数值列 表。可以应用一个滤波器来去除输入信号中的高频噪声。
有几个典型的步骤来设置和操作RMT
:
RMT有八个通道,编号从0到7。每个通道都能独立发送或接收数据。它们被rmt_channel_t
所定义。
有几个参数定义了特定通道的运作方式。这些参数中的大多数参数是通过设置结构的rmt_config_t
特定成员来配置的。其中一些参数对发射或接收模式都是通用的,有些是特定模式。它们都在下面讨论。
rmt_channel_t
枚举器中选一个。rem_mode
为rmt_mode_t
数值之一来选择。RMT
信号引脚编号是什么,通过设置gpio_num
选择。men_block_num
设置。RMT_CHANNEL_FLAGS_AWARE_DFS
被设置时,RMT通道将采用 REF_ TICK或XTAL作为源时钟。这样做的好处是,即使APB时钟改变,RMT通道也能 继续工作。更多信息请参见电源管理。clk_div
为[1 … 255]范围内的一个值来选择。RMT的源时钟通常为APB CLK,默认为80Mhz 。但是当RMT_CHANNEL_FLAGS_AWARE_DFS
被设置为标志时,RMT的源时钟会被改变为 REF_TICK或XTAL。时钟分频器之后的方波周期称为 “刻度”。由RMT发射器产生的脉冲或由接收器辨别的脉冲的长度以 "刻度"的数量配置。
还有一些特定的参数需要设置,这取决于所选通道是配置在发射模式还是接收模式。
当在发送模式下配置通道时,设置tx_config
和以下结构体成员的rmt_tx_config_t
:
loop_en
。carrier_en
。carrier_freq_hz
。carrier_duty_percent
。carrier_level
。idle_output_en
。idle_level
。/** * @brief Default configuration for Tx channel * */ #define RMT_DEFAULT_CONFIG_TX(gpio, channel_id) \ { \ .rmt_mode = RMT_MODE_TX, \ .channel = channel_id, \ .gpio_num = gpio, \ .clk_div = 80, \ .mem_block_num = 1, \ .flags = 0, \ .tx_config = { \ .carrier_freq_hz = 38000, \ .carrier_level = RMT_CARRIER_LEVEL_HIGH, \ .idle_level = RMT_IDLE_LEVEL_LOW, \ .carrier_duty_percent = 33, \ .carrier_en = false, \ .loop_en = false, \ .idle_output_en = true, \ } \ }
在接受模式下,设置rx_config
和以下结构体成员rmt_rx_config_t
。
filter_en
。filter_ticks_thresh
。短于此设置的脉冲将被过滤掉。注意 :输入刻度值的范围是[0…255]。idle_threshold
。接收器将忽略长于此设置的脉冲。/** * @brief Default configuration for RX channel * */ #define RMT_DEFAULT_CONFIG_RX(gpio, channel_id) \ { \ .rmt_mode = RMT_MODE_RX, \ .channel = channel_id, \ .gpio_num = gpio, \ .clk_div = 80, \ .mem_block_num = 1, \ .flags = 0, \ .rx_config = { \ .idle_threshold = 12000, \ .filter_ticks_thresh = 100, \ .filter_en = true, \ } \ }
一旦给rmt_config_t
结构体被填充了参数,然后应该调用rmt_config()
以使配置生效。
最后一个配置步骤是在内存中安装驱动程序,调用rmt_driver_install()
。如果这个函数的参数rx_buf_size
>0,那么就有一个环形缓冲器用于传入的数据将被分配。一个默认的ISR处理程序将被安装,参见使用中断中的说明。
现在,根据通道的配置情况,我们已经准备好发送数据或接收数据了,这将在下两节中描述。
在能够发射一些RMT脉冲之前,我们需要定义脉冲模式。RMT控制器识别的最小模式,后来被称为 “项目”,以rmt_item32_t
结构提供 。每个项目由两对两个值组成。一对中的第一个值描述了信号的持续时间,长度为15bits,第二项提供了信号的电平(高或低),包含在一个bits中。下面介绍一个由几个项目组成的块和一个项目的结构。
这些项目是通过调用函数rmt_write_items()
提供给RMT控制器的。这个函数也自动触发了传输的开始。它可能被调用以等待传输完成或在传输开始后退出。在这种情况下,你可以等待传输结束后,通过调用rmt_wait_tx_done()
。这个函数不限制数据项目进行传输。它使用一个中断来连续复制新的数据块到RMT的内部存储器,因为之前提供的数据被送出了。
另一种提供数据传输的方式是通过调用rmt_fill_tx_items()
。在这种情况下传输不会自动开始。要控制传输过程,请使用rmt_tx_start()
和rmt_tx_stop()
。要发送的项目数量受限于在RMT控制器的内部存储器中分配的内存块,详细见rmt_set_mem_block_num()
。
RMT RX通道不能接收项目大于其内存块大小的数据包。如果你把内存块数量设置为1,那么这个RX通道就不能接收超过64个项目的数据包。这是一个硬件限制。
在启动接收机之前,我们需要一些存储空间来存放传入的项目。RMT控制器有512 x 32位的内部RAM,由所有八个通道共享。
在通常情况下,它不足以作为所有传入(和传出)项目的最终存储。因此,这个API支持实时检索传入的项目,将它们保存在一个由用户决定大小的环形缓冲区。这个大小是在调用 rmt_driver_install()
上面讨论过。为了得到这个缓冲区的句柄,可以调用rmt_get_ringbuf_handle()
。
完成上述步骤后,我们可以通过rmt_rx_start()
调用和转到检查缓冲区内的内容。要做到这一点,你可以使用FreeRTOS
的普通函数与环形缓冲区互动。
要停止接收机,请使用rmt_rx_stop()
前面描述的rmt_config()
函数提供了一个方便的方法来设置几个配置参数一次就能完成。这通常是在应用程序启动时完成的。然后,当应用程序运行时,API提供了另一种方法,通过调用专用函数来更新各个参数。每个函数指的是作为第一个输入参数提供的特定RMT通道。大多数函数都有对应的_get_来读回当前配置的值。
rmt_set_pin()
。rmt_set_mem_pd()
。rmt_set_clk_div()
。rmt_set_source_clk()
。rmt_set_tx_loop_mode()
。rmt_set_tx_carrier()
,选自rmt_carrier_level_t
rmt_set_idle_level()
,选自rmt_idle_level_t
。rmt_set_rx_filter()
。rmt_set_rx_idle_thresh()
。rmt_set_memory_owner()
,选自rmt_men_owner_t
。为RMT控制器注册一个中断处理程序是通过调用rmt_isr_register()
。
当
rmt_driver_install()
调用系统RMT驱动时,一个默认的ISR正在被调用安装。在这种情况下,你不需要注册rmt_isr_register()
一个通用的ISR处理程序。
RMT控制器在下面描述的四个特定事件中触发中断。为了启用这些事件的中断,提供了以下功能。
rmt_set_rx_intr_en()
。rmt_set_tx_intr_en()
。rmt_set_tx_thr_intr_en()
。rmt_set_err_intr_en()
。设置或清除特定通道和事件的中断使能掩码也可以通过rmt_set_intr_enable_mask()
或rmt_set_intr_enable_mask()
。
如果你不再需要一个ISR,你可以通过调用一个函数来取消它的注册rmt_isr_deregister()
。
我们不建议用户在他们的应用程序中注册一个中断处理程序。RMT驱动高度依赖于中断,尤其是在以“ping-pong”方式时,所以驱动本身已经注册了一个默认的处理程序,叫做
rmt_driver_isr_default
相反,如果你想要的是在处理完成后得到一个通知,那么就用rmt_register_tx_end_callback()
。
如果RMT驱动程序已经安装rmt_driver_install()
了一段特定的时间。的时间,然后就不需要了,可以通过调用以下命令删除驱动程序以释放分配的资源rmt_driver_uninstall()
。
反,如果你想要的是在处理完成后得到一个通知,那么就用rmt_register_tx_end_callback()
。
如果RMT驱动程序已经安装rmt_driver_install()
了一段特定的时间。的时间,然后就不需要了,可以通过调用以下命令删除驱动程序以释放分配的资源rmt_driver_uninstall()
。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。