[RISC-V MCU 应用开发] 第七十三章、CH32V103应用教程——TIM-编码器模式

[复制链接]
 楼主| RISCVLAR 发表于 2021-2-24 15:23 | 显示全部楼层 |阅读模式
本帖最后由 RISCVLAR 于 2021-2-24 15:22 编辑

CH32V103应用教程——TIM-编码器模式

编码器,是一种用来测量机械旋转或位移的传感器。这种传感器能够测量机械部件在旋转或直线运动时的位移位置或速度等信息,并将其转换成一系列电信号。定时器可配置成编码器模式,本章教程主要对定时器编码器模式进行基本配置。

1、TIM简介及相关函数介绍
编码器模式是定时器的一个典型应用,可以用来接入编码器的双相输出,核心计数器的计数方向和编码器的转轴方向同步,编码器每输出一个脉冲就会使核心计数器加一或减一。使用编码器的步骤为:将SMS域置为001b(只在TI2边沿计数)、010b(只在TI1边沿计数)或者011b(在TI1和TI2双边沿计数),将编码器接到比较捕获通道1、2的输入端,给重装值寄存器设一个值,这个值可以设的大一点。在编码器模式时,定时器内部的比较捕获寄存器,预分频器,重复计数寄存器等都正常工作。下表表明了计数方向和编码器信号的关系。
图片1.png

2、硬件设计
本章教程将TIM2配置成编码器模式,需要用到PA0(TIM2_CH1)和PA1(TIM2_CH2)两个引脚。这两个引脚与编码器的连接方式如下:
  • PA0连接编码器的B相输出;
  • PA1连接编码器的A相输出;
注意:本章教程所用编码器为增量式旋转编码器。

3软件设计
本章教程主要进行定时器TIM编码器模式的基本配置,具体程序如下:
encoder.h文件
  1. #ifndef __ENCODER_H
  2. #define __ENCODER_H

  3. #include "ch32v10x_conf.h"

  4. void Encoder_Init_TIM2(void);
  5. void TIM2_IRQHandler(void);

  6. #endif
encoder.h文件主要进行函数的声明;
encoder.c文件

  1. #include "encoder.h"

  2. void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

  3. //TIM编码器模式配置函数
  4. void Encoder_Init_TIM2(void)
  5. {
  6.     GPIO_InitTypeDef        GPIO_InitStructure;
  7.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  8.     TIM_ICInitTypeDef       TIM_ICInitStructure;

  9.     //使能相应时钟
  10.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  12.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //使能AFIO复用功能模块时钟

  13.     //GPIO初始化配置 TIM2_CH1(PA0)  TIM2_CH2(PA1)
  14.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
  15.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  16.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  17.     //定时器初始化配置
  18.     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  19.     TIM_TimeBaseStructure.TIM_Period = 0xFFFF;                  //计数器自动重装载值
  20.     TIM_TimeBaseStructure.TIM_Prescaler = 1;                    //预分频器值
  21.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频
  22.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
  23.     TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;            //重复计数器值
  24.     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);             //初始化结构体

  25.     TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //使用编码器模式3

  26.     //输入捕获配置
  27.     TIM_ICInitStructure.TIM_Channel = TIM_Channel_1|TIM_Channel_2;
  28.     TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;       //输入捕获极性设置,可用于配置编码器正反相
  29.     TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;             //输入捕获预分频器设置
  30.     TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;   //输入捕获通道选择,编码器模式需选用此配置
  31.     TIM_ICInitStructure.TIM_ICFilter = 10;                            //输入捕获滤波器设置
  32.     TIM_ICInit(TIM2, &TIM_ICInitStructure);
  33.    
  34.     TIM_ClearFlag(TIM2, TIM_FLAG_Update);        //清除TIM更新标志位
  35.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);   //使能开启TIM中断
  36.     //Reset counter
  37.     TIM_SetCounter(TIM2,0);

  38.     TIM_Cmd(TIM2, ENABLE);
  39. }

  40. //中断服务函数
  41. void TIM2_IRQHandler(void)
  42. {
  43.     if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)    //是否产生更新(溢出)中断
  44.     {
  45.         TIM_ClearITPendingBit(TIM2,TIM_IT_Update);  //清空TIM5中断标志位
  46.     }
  47. }
encoder.c文件主要进行定时器的编码器模式配置,与应用教程第九章输入捕获类似。
main.c文件
  1. int main(void)
  2. {
  3.         Delay_Init();
  4.         USART_Printf_Init(115200);
  5.     Encoder_Init_TIM2();

  6.         printf("SystemClk:%d\r\n",SystemCoreClock);
  7.         printf("This is encoder example\r\n");

  8.     while(1)
  9.     {
  10.         enc = TIM_GetCounter(TIM2);

  11.         TIM_SetCounter(TIM2,0);

  12.         printf("enc = %d\r\n", enc);

  13.         Delay_Ms(500);
  14.     }
  15. }
main.c文件主要进行函数初始化以及计数器值的打印输出。

4下载验证
将编译好的程序下载到开发板并复位,转动编码器,串口打印如下(其中正负代表方向):
正转:
图片2.png
反转:
图片3.png

72、TIM-编码器模式配置.rar

485.25 KB, 下载次数: 278

金葫芦123 发表于 2021-6-28 21:29 | 显示全部楼层
请问一下,如果将编码器换成霍尔传感器也可以么?还有就是比如无刷直流电机有三个霍尔传感器,我需要接三个引脚,这里的通道TIM_Channel_1,是不是要TIM_Channel_1、TIM_Channel_2和TIM_Channel_3这三个通道?
 楼主| RISCVLAR 发表于 2021-6-29 09:41 | 显示全部楼层
金葫芦123 发表于 2021-6-28 21:29
请问一下,如果将编码器换成霍尔传感器也可以么?还有就是比如无刷直流电机有三个霍尔传感器,我需要接三个 ...

霍尔传感器没用过,不清楚其具体工作原理,可以百度一下STM32霍尔传感器应用,大体类似
金葫芦123 发表于 2021-6-29 10:30 | 显示全部楼层
RISCVLAR 发表于 2021-6-29 09:41
霍尔传感器没用过,不清楚其具体工作原理,可以百度一下STM32霍尔传感器应用,大体类似 ...

霍尔传感器和编码器类似,在无刷直流电机中可以判断转子的位置和用于测速,请问一下,这款芯片有没有控制无刷直流电机的工程或者开发样例?

评论

没有  发表于 2021-6-29 11:28
Estelle1999 发表于 2021-6-29 13:32 | 显示全部楼层
哇 这个教程写的详细 不错不错 感谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

296

帖子

44

粉丝
快速回复 在线客服 返回列表 返回顶部