Ps:本例程主要作用是,展示如何使用QTIMER模块来实现正交解码。
主板为:逐飞RT1064 + 母板
1)简介:与 PIT(周期中断定时器)和 GPT(通用定时器)相比 QTMR 定时器(Quad Timer) 功能更
强大。 第一, RT1052 拥有 4 个片上 QTMR 定时器模块,每个 QTMR 定时器模块包含四个
通道,每个通道都可以单独作为一个定时器使用,每个通道都可触发中断可产生 DMA 请
求。 QTMR 最多提供 16 个定时器。第二, QTMR 模块的每个通道可以配置为多种工作模
式。
2)工作模式介绍(只介绍正交解码):正交编码模式( Quadrature-Count Mode) , 正交编码模式用于获得编码器转动角度,编码器的 PHASEA 和 PHASEB 分别连接到定时器的主计数源(primary count source)
和辅助计数源。
3)QTMR定时器有四个模块,每个模块有四个不同的通道
4)代码
//一个QTIMER可以 创建两个正交解码
//初始化 QTIMER_1 A相使用QTIMER1_TIMER0_C0 B相使用QTIMER1_TIMER1_C1
qtimer_quad_init(QTIMER_1,QTIMER1_TIMER0_C0,QTIMER1_TIMER1_C1);
//初始化 QTIMER_1 A相使用QTIMER1_TIMER2_C2 B相使用QTIMER1_TIMER3_C24
qtimer_quad_init(QTIMER_1,QTIMER1_TIMER2_C2,QTIMER1_TIMER3_C24);
qtimer_quad_init(QTIMER_2,QTIMER2_TIMER0_C3,QTIMER2_TIMER3_C25);
qtimer_quad_init(QTIMER_3,QTIMER3_TIMER2_B18,QTIMER3_TIMER3_B19);
//将C0与 D0使用杜邦线链接起来
//将C2与 D1使用杜邦线链接起来
//将C3与 D2使用杜邦线链接起来
//将B18与 D3使用杜邦线链接起来
//将C1 C3 C24 B19 接地,可以看到采集到的数据为5.
//如果直接连接编码器的A B相,那么则可以直接采集编码器数据
5)QTIMER正交解码初始化
//-------------------------------------------------------------------------------------------------------------------
// @brief QTIMER正交解码初始化
// @param qtimern 选择QTIMER模块(QTIMER_1、QTIMER_2)
// @param phaseA 选择正交解码 A端口
// @param phaseB 选择正交解码 B端口
// @return void
// Sample usage: qtimer_quad_init(QTIMER_1, QTIMER1_TIMER0_C0,QTIMER1_TIMER1_C1);
//-------------------------------------------------------------------------------------------------------------------
void qtimer_quad_init(QTIMERN_enum qtimern, QTIMER_PIN_enum phaseA, QTIMER_PIN_enum phaseB)
6)QTIMER引脚枚举(部分展示)
QTIMER1_TIMER0_C0 =1*12+3*0, //定时器0 同一时间只能有一个引脚与定时器相关联
QTIMER1_TIMER1_C1 =1*12+3*1, //定时器1 同一时间只能有一个引脚与定时器相关联
QTIMER1_TIMER2_C2 =1*12+3*2, //定时器2 同一时间只能有一个引脚与定时器相关联
QTIMER1_TIMER3_C24=1*12+3*3, //定时器3 同一时间只能有一个引脚与定时器相关联
1)代码
//pwm__int 初始化代码
pwm_init(PWM1_MODULE3_CHB_D1 , 50, 5000);
pwm_init(PWM1_MODULE3_CHA_D0 , 50, 5000);
pwm_init(PWM2_MODULE3_CHB_D3 , 50, 5000);
pwm_init(PWM2_MODULE3_CHA_D2 , 50, 5000);
2)zf_pwm.c 中的初始化代码
//-------------------------------------------------------------------------------------------------------------------
// @brief PWM初始化
// @param pwmch PWM通道号及引脚
// @param freq PWM频率
// @param duty PWM占空比
// @return void
// Sample usage: pwm_init(PWM1_MODULE0_CHB_D13, 50, 5000); //初始化PWM1 子模块0 通道B 使用引脚D13 输出PWM频率50HZ 占空比为百分之 5000/PWM_DUTY_MAX*100
// PWM_DUTY_MAX在fsl_pwm.h文件中 默认为50000
//-------------------------------------------------------------------------------------------------------------------
void pwm_init(PWMCH_enum pwmch, uint32 freq, uint32 duty)
3)注意事项
1.关于子模块的解释 具体参考 zf_pwm.h
同一个子模块不同通道只能输出相同频率的PWM,占空比可设置不同
例如
//PWM1_MODULE0_CHB与PWM1_MODULE0_CHA属于同一个子模块,频率只能一样,但是占空比可以不一样
//PWM1_MODULE0_CHA_D12与PWM1_MODULE1_CHA_D14虽然是同一个PWM模块但是属于不同的子模块可以输出不同频率的PWM
4)pw_pwm.h(部分展示)
PWM1_MODULE0_CHB_D13=1*40+5*0, PWM1_MODULE0_CHB_E24, //PWM1 子模块0 通道B 引脚可选范围
PWM1_MODULE0_CHA_D12=1*40+5*1, PWM1_MODULE0_CHA_E23, //PWM1 子模块0 通道A 引脚可选范围
PWM1_MODULE1_CHB_D15=1*40+5*2, PWM1_MODULE1_CHB_E26, //PWM1 子模块1 通道B 引脚可选范围
PWM1_MODULE1_CHA_D14=1*40+5*3, PWM1_MODULE1_CHA_E25, //PWM1 子模块1 通道A 引脚可选范围
PWM1_MODULE2_CHB_D17=1*40+5*4, PWM1_MODULE2_CHB_E28, //PWM1 子模块2 通道B 引脚可选范围
PWM1_MODULE2_CHA_D16=1*40+5*5, PWM1_MODULE2_CHA_E27, //PWM1 子模块2 通道A 引脚可选范围
PWM1_MODULE3_CHB_B11=1*40+5*6, PWM1_MODULE3_CHB_C17, PWM1_MODULE3_CHB_D1, PWM1_MODULE3_CHB_D25, PWM1_MODULE3_CHB_E13,//PWM1 子模块3 通道B 引脚可选范围
PWM1_MODULE3_CHA_B10=1*40+5*7, PWM1_MODULE3_CHA_C16, PWM1_MODULE3_CHA_D0, PWM1_MODULE3_CHA_D24, PWM1_MODULE3_CHA_E12,//PWM1 子模块3 通道A 引脚可选范围
1)
while(1)
{
//读取编码器计数值
encoder1 = qtimer_quad_get(QTIMER_1,QTIMER1_TIMER0_C0 );
encoder2 = qtimer_quad_get(QTIMER_1,QTIMER1_TIMER2_C2 );
encoder3 = qtimer_quad_get(QTIMER_2,QTIMER2_TIMER0_C3 );
encoder4 = qtimer_quad_get(QTIMER_3,QTIMER3_TIMER2_B18);
//清除
qtimer_quad_clear(QTIMER_1,QTIMER1_TIMER0_C0 );
qtimer_quad_clear(QTIMER_1,QTIMER1_TIMER2_C2 );
qtimer_quad_clear(QTIMER_2,QTIMER2_TIMER0_C3 );
qtimer_quad_clear(QTIMER_3,QTIMER3_TIMER2_B18);
systick_delay_ms(100);
}
2) QTIMER正交解码计数获取函数 qtimer_quad_get()
//-------------------------------------------------------------------------------------------------------------------
// @brief QTIMER正交解码计数获取
// @param qtimern 选择QTIMER模块(QTIMER_1、QTIMER_2)
// @param phaseA 选择正交解码 A端口 这个参数需要与qtimer_quad_init函数第二个参数一致
// @return int16 返回脉冲数
// Sample usage: qtimer_quad_get(QTIMER_1, QTIMER1_TIMER0_C0);
//-------------------------------------------------------------------------------------------------------------------
int16 qtimer_quad_get(QTIMERN_enum qtimern, QTIMER_PIN_enum phaseA)
3) QTIMER正交解码计数清零函数 qtimer_quad_clear()
//-------------------------------------------------------------------------------------------------------------------
// @brief QTIMER正交解码计数清零
// @param qtimern 选择QTIMER模块(QTIMER_1、QTIMER_2)
// @param phaseA 选择正交解码 A端口 这个参数需要与qtimer_quad_init函数第二个参数一致
// @return void
// Sample usage: qtimer_quad_clear(QTIMER_1, QTIMER1_TIMER0_C0);
//-------------------------------------------------------------------------------------------------------------------
void qtimer_quad_clear(QTIMERN_enum qtimern, QTIMER_PIN_enum phaseA)
#include "headfile.h"
int16 encoder1;
int16 encoder2;
int16 encoder3;
int16 encoder4; // 用来获取编码器的返回值
int main(void)
{
DisableGlobalIRQ();
board_init();//务必保留,本函数用于初始化MPU 时钟 调试串口
//pwm初始化
pwm_init(PWM1_MODULE3_CHB_D1,50,5000); //50 频率 5000占空比 计算公式 输出PWM频率50HZ 占空比为百分之 5000/PWM_DUTY_MAX*100
// PWM_DUTY_MAX在fsl_pwm.h文件中 默认为50000
pwm_init(PWM1_MODULE3_CHA_D0,50,5000);
pwm_init(PWM2_MODULE3_CHB_D3,50,5000);
pwm_init(PWM2_MODULE3_CHA_D2,50,5000);
一个QTIMER可以 创建两个正交解码
//初始化 QTIMER_1 A相 使用QTIMER1_TIMER0_C0 B相 使用QTIMER1_TIMER1_C1
qtimer_quad_init(QTIMER_1,QTIMER1_TIMER0_C0,QTIMER1_TIMER1_C1);
//初始化 QTIMER_1 A相使用QTIMER1_TIMER2_C2 B相使用QTIMER1_TIMER3_C24
qtimer_quad_init(QTIMER_1,QTIMER1_TIMER2_C2,QTIMER1_TIMER3_C24);
qtimer_quad_init(QTIMER_2,QTIMER2_TIMER0_C3,QTIMER2_TIMER3_C25);
qtimer_quad_init(QTIMER_3,QTIMER3_TIMER2_B18,QTIMER3_TIMER3_B19);
//将C0与 D0使用杜邦线链接起来
//将C2与 D1使用杜邦线链接起来
//将C3与 D2使用杜邦线链接起来
//将B18与 D3使用杜邦线链接起来
//将C1 C3 C24 B19 接地,可以看到采集到的数据为5.
//如果直接连接编码器的A B相,那么则可以直接采集编码器数据
//总中断最后开启
EnableGlobalIRQ(0);
while (1)
{
//读取编码器计数值
encoder1 = qtimer_quad_get(QTIMER_1,QTIMER1_TIMER0_C0 );//下面的代码只能读取A相 B相尝试发现没有数据
encoder2 = qtimer_quad_get(QTIMER_1,QTIMER1_TIMER2_C2 );//qtimer_quad_get 这个函数获取 pwm输出频率的 1/10 (与占空比无关)^*
encoder3 = qtimer_quad_get(QTIMER_2,QTIMER2_TIMER0_C3 );
encoder4 = qtimer_quad_get(QTIMER_3,QTIMER3_TIMER2_B18);
qtimer_quad_clear(QTIMER_1,QTIMER1_TIMER0_C0 );
qtimer_quad_clear(QTIMER_1,QTIMER1_TIMER2_C2 );
qtimer_quad_clear(QTIMER_2,QTIMER2_TIMER0_C3 );
qtimer_quad_clear(QTIMER_3,QTIMER3_TIMER2_B18);
systick_delay_ms(100);
}
}