Stark_GS · 2022年11月26日 · 广东

【GD32F427开发板试用】04-编码器接口的使用

【GD32F427开发板试用】04-编码器接口的使用


定时器中编码器接口的简介及特点

正交译码器

正交译码器功能使用由 TIMERx_CH0 和 TIMERx_CH1 引脚生成的 CI0 和 CI1 正交信号各自相互作用产生计数值。在每个输入源改变期间,DIR 位被硬件自动改变。输入源可以是只有 CI0,可以只有 CI1,或着可以同时有 TI1 和 TI2,通过设置 SMC=0x01, 0x02 或 0x03 来选择使用哪种模式。计数器计数方向改变的机制如下图. 计数方向与编码器信号之间的关系所示。 正交译码器可以当作一个带有方向选择的外部时钟,这意味着计数器会在 0 和自动加载值之间连续的计数。因此,用户必须在计数器开始计数前配置 TIMERx_CAR 寄存器。

编码器的三种模式,由 TIMERx_SMCFG 寄存器的 SMC[2:0]控制
对应下图,编码器模式0、编码器模式1、编码器模式2

比如 1000 线的编码器
编码器模式0、编码器模式1:编码器旋转一周计数器计数 2000
编码器模式2:编码器旋转一周计数器计数 4000

1234.png

注意: "-" 意思是"无计数"; "X" 意思是不可能。

在【GD32F427开发板试用】03-PWM单通道输出文章中有讲到具有编码器接口的定时器,如下所示。

  • TIMER0 TIMER7 这两个定时器适合做电机控制(带死区插入功能)
  • TIMER0 TIMER7 TIMER1 TIMER2 TIMER3 TIMER4 这六个定时器具有编码器的接口和霍尔的接口

开发环境&参考文档

  • Keil-MDK 5.27.1.0
  • Windows11
  • 固件库-GD32F4xx_Firmware_Library_V3.0.2
  • GD32F427xx_Datasheet_Rev1.2
  • GD32F4xx_User_Manual_Rev2.7_CN
  • GD32F4xx 固件库使用指南_V1.0

代码部分

这里我们使用的 2000 线编码器,采用编码器模式2

encoder.h 文件

#ifndef _ENCODER_H_
#define _ENCODER_H_

#include "gd32f4xx.h"


void Encoder_Init(void);

#endif

encoder.c 文件

#include "encoder.h"


void Encoder_Init(void)
{
    timer_parameter_struct Timer_ParamType;
    timer_ic_parameter_struct Timer_IC_ParamType;
    
    rcu_periph_clock_enable(RCU_GPIOA);//启用外设时钟功能
    rcu_periph_clock_enable(RCU_TIMER2);
    
    gpio_af_set(GPIOA,GPIO_AF_2,GPIO_PIN_6);//端口复用为TIMER2_CH0模式
    gpio_af_set(GPIOA,GPIO_AF_2,GPIO_PIN_7);//端口复用为TIMER2_CH1模式
    
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);

    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);

    timer_deinit(TIMER2);
    timer_struct_para_init(&Timer_ParamType);
    
    Timer_ParamType.alignedmode = TIMER_COUNTER_EDGE;//配置为边沿对其模式
    Timer_ParamType.clockdivision = TIMER_CKDIV_DIV1;//配置死区时间和采样时钟(DTS)之间的分频系数
    Timer_ParamType.counterdirection = TIMER_COUNTER_UP;//配置计数方向为向上计数
    Timer_ParamType.period = 2000*4;//周期
    Timer_ParamType.prescaler = 0;//预分频
    Timer_ParamType.repetitioncounter = 0;
    timer_init(TIMER2,&Timer_ParamType);
    
    timer_channel_input_struct_para_init(&Timer_IC_ParamType);
    
    Timer_IC_ParamType.icfilter = 0x5;//配置滤波器
    Timer_IC_ParamType.icpolarity = TIMER_IC_POLARITY_RISING;
    Timer_IC_ParamType.icselection = TIMER_IC_SELECTION_DIRECTTI;
    Timer_IC_ParamType.icprescaler = TIMER_IC_PSC_DIV1;
    timer_input_capture_config(TIMER2,TIMER_CH_0,&Timer_IC_ParamType);
    timer_input_capture_config(TIMER2,TIMER_CH_1,&Timer_IC_ParamType);

    //此处第二个参数配置编码器模式
    timer_quadrature_decoder_mode_config(TIMER2,TIMER_ENCODER_MODE2,TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_RISING);

    timer_enable(TIMER2);
}

main.c 文件

文件中的其他模块使用请参照前几篇文章

#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>

#include "gpio.h"
#include "uart.h"
#include "encoder.h"


uint32_t EncoderValue;
int main(void)
{
    systick_config();    //配置系统时钟
    
    GPIO_Init();
    USART_Init();
    Encoder_Init();
    
    while(1) 
    {
        gpio_bit_toggle(GPIOC, GPIO_PIN_6);    //反转PC6
//        delay_1ms(200);
        
        EncoderValue = timer_counter_read(TIMER2);
        printf("samples:%d\n",EncoderValue);
    }
}

上位机获取角度

这里使用的上位机为 vofa+

1234.png

推荐阅读
关注数
4
文章数
14
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息