RT1064学习笔记(2)--编码器例程(Encoder Demo)

RT1064之编码器例程

Ps:本例程主要作用是,展示如何使用QTIMER模块来实现正交解码。
主板为:逐飞RT1064 + 母板

一,QTMR—四路通道定时器

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 同一时间只能有一个引脚与定时器相关联
    
二,PWM——输出捕获

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  引脚可选范围
    
三,while循环内执行的代码

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);
        
    }
}

调试窗口 Value为5(表示接收到pwm波)
RT1064学习笔记(2)--编码器例程(Encoder Demo)_第1张图片

你可能感兴趣的:(RT1064学习笔记)