一、M487 QEI简介
6.14.1 概述
M480 有两组 QEI 控制器。正交编码接口 (QEI) 解读转速和动作传感器的信息。它可以用在任何使用正
交编码器作为反馈的应用里。
6.14.2 特性
6.14.2.1 正交编码接口 (QEI) 特性
多达 2 个 QEI 控制器,QEI0 及 QEI1
2 个 QEI 相位输入,QEA 及 QEB;1 个索引输入
1 个 32 位的上/下正交编码脉冲计数器 (QEI_CNT)
1 个 32 位的软件锁存正交编码脉冲计数器保存寄存器 (QEI_CNTHOLD)
1 个 32 位的正交编码脉冲计数器索引锁存寄存器 (QEI_CNTLATCH)
1 个 32 位的正交编码脉冲计数器比较寄存器 (QEI_CNTCMP),并提供最大计数预设值寄存
器 (QEI_CNTMAX)
1 个 QEI 控制寄存器 (QEI_CTL) 和 1 个 QEI 状态寄存器 (QEI_STATUS)
4 种正交编码脉冲计数器操作模式
– 支持 x4 自由计数模式
– 支持 x2 自由计数模式
– 支持 x4 比较计数模式
– 支持 x2 比较计数模式
编码脉冲宽度测量模式
不做消噪时,QEA/QEB/IDX 的输入频率必须低于 PCLK/4
有做消噪时,QEA/QEB/IDX 的输入频率必须低于噪声滤波器的 Clk/8
二、软件测试环境
KEIL MDK v5.26
Env RT-Thread 开发辅助工具。
终端联机工具Tera Term V4.99
RT-Thread 标准版系统及bsp包
三、硬件环境
NuMaker-IoT-M487
四、开始建立测试环境
1.在官网下载Env RT-Thread 开发辅助工具包,包含了终端联机工具Tera Term;
2.根据NuMaker-IoT-M487 上手指南
下载更新RT-Thread 标准版系统及bsp包
3.在ENV环境下,输入cd rt-thread>> cd bsp/nuvoton/numaker-iot-m487>>menuconfig打开系统配置界面,Hardware Drivers Config>>On-Chip Peripheral Drivers >>Enable quadrature Encoder Interface(QEI)>>QEI0;
如图:
![]()
![]()
最后输入scons —target=mdk5 进行编译;
打开KEIL编译通过后下载到板上;通过终端联机工具Tera Term 输入list_device查询
![]()
出现qei0接口对象, 说明项目配置成功;
4.找出M487 QEI0 对应的IO QEI0_A = PA4, QEI0_B = PA3,
如图
![]()
在nutool_pincfg.c 中的nutool_pincfg_init 和nutool_pincfg_deinit中分别加入: nutool_pincfg_init_qei0(), nutool_pincfg_deinit_qei0();
void nutool_pincfg_init_qei0(void)
{
/* Set PA multi-function pins for QEI0_A, QEI0_B, QEI0_INDEX */
SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA4MFP_Msk | SYS_GPA_MFPL_PA3MFP_Msk | SYS_GPA_MFPL_PA5MFP_Msk);
SYS->GPA_MFPL |= (SYS_GPA_MFPL_PA4MFP_QEI0_A | SYS_GPA_MFPL_PA3MFP_QEI0_B | SYS_GPA_MFPL_PA5MFP_QEI0_INDEX);
}
void nutool_pincfg_deinit_qei0(void)
{
SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA4MFP_Msk | SYS_GPA_MFPL_PA3MFP_Msk | SYS_GPA_MFPL_PA5MFP_Msk);
}
如图:
![]()
![]()
5.找出NuMaker-IoT-M487 对应的测试端子;
![]()
![]()
然后将杜邦线连接:
![]()
6.开始代码测试
用keil 打开 rt-threadsp
uvoton
umaker-iot-m487 目录下project项目;在 applications 下新增 QEI_test.c;
#include "rtthread.h"
#include "rtdevice.h"
#include "NuMicro.h"
#include
#define A0 NU_GET_PININDEX(NU_PA, 0)
#define B0 NU_GET_PININDEX(NU_PA, 1)
struct nu_qei
{
struct rt_pulse_encoder_device dev;
char *name;
QEI_T *qei_base;
rt_uint32_t max_cntval;
rt_uint32_t cmp_val;
IRQn_Type IRQn;
rt_uint8_t qei_type;
rt_uint8_t qei_flag;
};
typedef struct nu_qei *nu_qei_t;
void qei_thread_entry(void *arc)
{
rt_int32_t s32_Count = 0;
rt_uint8_t u8_GetEncoderType = 0;
rt_device_t qei_ops=rt_device_find("qei0");
if(qei_ops == RT_NULL)
{
rt_kprintf("not find device qei0
");
return ;
}
rt_kprintf("find device qei0
");
((nu_qei_t)qei_ops)->cmp_val = 4096;
((nu_qei_t)qei_ops)->max_cntval = 4096;
rt_device_open(qei_ops, PULSE_ENCODER_CMD_ENABLE); //设置比较模式
rt_device_control(qei_ops,PULSE_ENCODER_CMD_GET_TYPE, &u8_GetEncoderType); //取编码类型
switch( u8_GetEncoderType )
{
case UNKNOWN_PULSE_ENCODER_TYPE: /* Unknown pulse_encoder type */
rt_kprintf("PULSE_ENCODER_TYPE: UNKNOWN_PULSE_ENCODER_TYPE!
" );
case SINGLE_PHASE_PULSE_ENCODER: /* single phase pulse_encoder */
rt_kprintf("PULSE_ENCODER_TYPE: SINGLE_PHASE_PULSE_ENCODER!
" );
case AB_PHASE_PULSE_ENCODER: /* two phase pulse_encoder */
rt_kprintf("PULSE_ENCODER_TYPE: two phase pulse_encoder!
" );
}
rt_device_control(qei_ops,PULSE_ENCODER_CMD_CLEAR_COUNT,RT_NULL); //计数器清零
rt_device_read( qei_ops, RT_NULL, &s32_Count, 1);
rt_kprintf("Count: %d
",s32_Count );
while(1)
{
rt_pin_write(A0, PIN_HIGH);
rt_thread_delay(2);
rt_pin_write(B0, PIN_HIGH);
rt_thread_delay(2);
rt_pin_write(A0, PIN_LOW);
rt_thread_delay(2);
rt_pin_write(B0, PIN_LOW);
rt_thread_delay(2);
}
}
int run_qei(void)
{
rt_pin_mode(A0, PIN_MODE_OUTPUT);
rt_pin_mode(B0, PIN_MODE_OUTPUT);
rt_thread_t tid = RT_NULL;
tid = rt_thread_create("qei_test_thd", qei_thread_entry, RT_NULL, 2048, 12, 10);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
else
{
return RT_ERROR;
}
return RT_EOK;
}
//INIT_APP_EXPORT(run_qei);
MSH_CMD_EXPORT(run_qei , qei test );
编译通过后下载到板上;
打开
终端联机工具Tera Term 输入run_qei;
如图:
![]()
实现了AB相位脉冲编码器4096个脉冲比较中断测试;
五、测评总结
1、qei 模块 作为 “Miscellaneous Device” 个人感觉“ I/O 设备管理层实现了对设备驱动程序的封装”还需要扩展,一些参数的灵活配置仍然留给底层;
2、RT-Thread I/O 设备模型 思路还是不错的;可以提高应用代码的可移植性;
原作者:颜旭涛
|