[原创] STM32 定时器TIMx 编码器应用 函数 TIM_EncoderInterfaceConfig 分析

今天把STM32 定时器输入作为 编码器接口相关的 函数   TIM_EncoderInterfaceConfig ,好好分析了一遍

因为网上不少人对这个函数有问题

  1 void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
  2                                 uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
  3 {
  4   uint16_t tmpsmcr = 0;
  5   uint16_t tmpccmr1 = 0;
  6   uint16_t tmpccer = 0;
  7
  8   /* Get the TIMx SMCR register value */
  9   tmpsmcr = TIMx->SMCR;
 10
 11   /* Get the TIMx CCMR1 register value */
 12   tmpccmr1 = TIMx->CCMR1;
 13
 14   /* Get the TIMx CCER register value */
 15   tmpccer = TIMx->CCER;
 16
 17   /* Set the encoder Mode */
 18   tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));  //0x0007    //关闭从模式
 19
 20     //#define  TIM_SMCR_SMS                        ((uint16_t)0x0007)            /*!< SMS[2:0] bits (Slave mode selection) */
 21     //#define  TIM_SMCR_SMS_0                      ((uint16_t)0x0001)            /*!< Bit 0 */
 22     //#define  TIM_SMCR_SMS_1                      ((uint16_t)0x0002)            /*!< Bit 1 */
 23     //#define  TIM_SMCR_SMS_2                      ((uint16_t)0x0004)            /*!< Bit 2 */
 24     //0x0007 -> 0b0000 0000 0000 0111 -> 位取反 -> 0b1111 1111 1111 1000 ->再与,也就是把 tmpsmcr[2:0]置0
 25     //tmpsmcr[2:0]置0 , 就是TIMx->SMCR[2:0] =000 ,
 26     /*
 27         SMCR[2:0]  SMS:从模式选择
 28         当选择了外部信号,触发信号(TRGI)的有效边沿与选中的外部输入极性相关(见输入控制寄存器
 29         和控制寄存器的说明)
 30         000:关闭从模式 – 如果CEN=1,则预分频器直接由内部时钟驱动。
 31         001:编码器模式1 – 根据TI1FP1的电平,计数器在TI2FP2的边沿向上/下计数。
 32         010:编码器模式2 – 根据TI2FP2的电平,计数器在TI1FP1的边沿向上/下计数。
 33         011:编码器模式3 – 根据另一个输入的电平,计数器在TI1FP1和TI2FP2的边沿向上/下计数。
 34         100:复位模式 – 选中的触发输入(TRGI)的上升沿重新初始化计数器,并且产生一个更新寄存
 35         器的信号。
 36         101:门控模式 – 当触发输入(TRGI)为高时,计数器的时钟开启。一旦触发输入变为低,则计
 37         数器停止(但不复位)。计数器的启动和停止都是受控的。
 38         110:触发模式 – 计数器在触发输入TRGI的上升沿启动(但不复位),只有计数器的启动是受控
 39         的。
 40         111:外部时钟模式1 – 选中的触发输入(TRGI)的上升沿驱动计数器。
 41         注:如果TI1F_EN被选为触发输入(TS=100)时,不要使用门控模式。这是因为, TI1F_ED在每
 42         次TI1F变化时输出一个脉冲,然而门控模式是要检查触发输入的电平。
 43     */
 44
 45     //#define TIM_EncoderMode_TI1                ((uint16_t)0x0001)
 46     //#define TIM_EncoderMode_TI2                ((uint16_t)0x0002)
 47     //#define TIM_EncoderMode_TI12               ((uint16_t)0x0003)
 48
 49   tmpsmcr |= TIM_EncoderMode; //0x0003
 50     //SMCR[2:0]  SMS:从模式选择
 51     //011:编码器模式3 – 根据另一个输入的电平,计数器在TI1FP1和TI2FP2的边沿向上/下计数。
 52
 53
 54
 55   /* Select the Capture Compare 1 and the Capture Compare 2 as input */
 56      //#define  TIM_CCMR1_CC1S   ((uint16_t)0x0003)            /*!< CC1S[1:0] bits (Capture/Compare 1 Selection) */
 57     //#define  TIM_CCMR1_CC2S   ((uint16_t)0x0300)            /*!< CC2S[1:0] bits (Capture/Compare 2 Selection) */
 58   tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)));
 59   //简化一下
 60   //tmpccmr1 &= (    (~(TIM_CCMR1_CC1S))       &       (~(TIM_CCMR1_CC2S))          );
 61   //(~(TIM_CCMR1_CC1S)) = ~0x0003 = 0b1111 1111 1111 1100
 62   //(~(TIM_CCMR1_CC2S)) = ~0x0300 = 0b1111 1100 1111 1111
 63   //上面两个先位与 , 得到 ---------0b1111 1100 1111 1100
 64   //tmpccmr1 =tmpccmr1 & 0b1111 1100 1111 1100   -->  CCMR1[9:8]=00 ; CCMR1[1:0] = 00
 65   /*
 66     CCMR1[9:8] --> CC2S[1:0]:捕获/比较2选择。
 67     该位定义通道的方向(输入/输出),及输入脚的选择:
 68     00: CC2通道被配置为输出;
 69     01: CC2通道被配置为输入, IC2映射在TI2上;
 70     10: CC2通道被配置为输入, IC2映射在TI1上;
 71     11: CC2通道被配置为输入, IC2映射在TRC上。此模式仅工作在内部触发器输入被选中时(由
 72     TIMx_SMCR寄存器的TS位选择)。
 73     注: CC2S仅在通道关闭时(TIMx_CCER寄存器的CC2E=0)才是可写的。
 74
 75     CCMR1[1:0] --> CC1S[1:0]:捕获/比较1 选择。
 76     这2位定义通道的方向(输入/输出),及输入脚的选择:
 77     00: CC1通道被配置为输出;
 78     01: CC1通道被配置为输入, IC1映射在TI1上;
 79     10: CC1通道被配置为输入, IC1映射在TI2上;
 80     11: CC1通道被配置为输入, IC1映射在TRC上。此模式仅工作在内部触
 81     TIMx_SMCR寄存器的TS位选择)。
 82     注: CC1S仅在通道关闭时(TIMx_CCER寄存器的CC1E=0)才是可写的。
 83   */
 84
 85
 86
 87     //#define  TIM_CCMR1_CC1S_0     ((uint16_t)0x0001)            /*!< Bit 0 */
 88     //#define  TIM_CCMR1_CC2S_0     ((uint16_t)0x0100)            /*!< Bit 0 */
 89   tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
 90   // tmpccmr1 = tmpccmr1 | TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
 91   // TIM_CCMR1_CC1S_0 = 0b0000 0000 0000 0001
 92   // TIM_CCMR1_CC2S_0 = 0b0000 0001 0000 0000
 93
 94   // tmpccmr1 -> CCMR1[9:8]=01 ; CCMR1[1:0] = 01
 95   // CCMR1[9:8]        01: CC2通道被配置为输入, IC2映射在TI2上;
 96   // CCMR1[1:0]       01: CC1通道被配置为输入, IC1映射在TI1上;
 97
 98
 99   /* Set the TI1 and the TI2 Polarities */
100
101     //#define  TIM_CCER_CC1P    ((uint16_t)0x0002)            /*!< Capture/Compare 1 output Polarity */
102     //#define  TIM_CCER_CC2P    ((uint16_t)0x0020)            /*!< Capture/Compare 2 output Polarity */
103   tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P)));
104     //简化一下
105     //tmpccer &= (      (~(TIM_CCER_CC1P))        &       (~(TIM_CCER_CC2P))      );
106     //(~(TIM_CCER_CC1P)) = ~0x0002  = 0b1111 1111 1111 1101
107     //(~(TIM_CCER_CC2P)) = ~0x0020  = 0b1111 1111 1101 1111
108     //上面两个先位与 ---------------->0b1111 1111 1101 1101
109     // CCER[5]=0   CCER[1]=0
110
111     /*
112     CCER位5 CC2P:输入/捕获2输出极性。参考CC1P的描述。
113     CCER位1 CC1P:输入/捕获1输出极性
114                     CC1通道配置为输出:
115                     0: OC1高电平有效
116                     1: OC1低电平有效
117                     CC1通道配置为输入:(******上面已经将CC1/CC2 配置位输入了 !!!!!)
118                     该位选择是IC1还是IC1的反相信号作为触发或捕获信号。
119                     0:不反相:捕获发生在IC1的上升沿;当用作外部触发器时, IC1不反
120                     1:反相:捕获发生在IC1的下降沿;当用作外部触发器时, IC1反相
121     */
122
123
124
125
126     //#define  TIM_ICPolarity_Rising             ((uint16_t)0x0000)
127     //#define  TIM_ICPolarity_Falling            ((uint16_t)0x0002)
128     //#define  TIM_ICPolarity_BothEdge           ((uint16_t)0x000A)    //0b1010
129   tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
130    //1. 如果参数为 TIM_ICPolarity_Rising  -> 0x0000
131    // tmpccer |= 0;
132    // CCER没有改变,其实就是上面注释中的 --> 0 不反相:捕获发生在IC1/IC2的上升沿;当用作外部触发器时,IC1/IC2不反
133
134    //2. 如果参数为 TIM_ICPolarity_Falling -> 0x0002
135    // tmpccer |= 0x0002 | (0x0002<<4) = 0b0000 0010  | 0b0010 0000 = 0b0010 0010;
136    // CCER[5]=1   CCER[1]=1
137    // CCER没有改变,其实就是上面注释中的 --> 1:反相:捕获发生在IC1/IC2的下降沿;当用作外部触发器时, IC1/IC2反相
138
139    //3. 如果参数为 TIM_ICPolarity_BothEdge  -> 0x000A -> 0b1010
140    // ( 0b0000 0000 0000 1010 <<4 ) 结果是:0b0000 0000 1010 0000
141    // 好吧  我都不想说了,真不知道为啥要做这个参数 !!!!!!!!
142
143
144   /* Write to TIMx SMCR */
145   TIMx->SMCR = tmpsmcr;
146     //跟函数的参数有关系
147     //tmpsmcr -> SMCR[2:0]  SMS:从模式选择
148     //011:编码器模式3 – 根据另一个输入的电平,计数器在TI1FP1和TI2FP2的边沿向上/下计数。
149
150
151   /* Write to TIMx CCMR1 */
152   TIMx->CCMR1 = tmpccmr1;
153     // 函数内部处理,已经固定好了
154     // tmpccmr1 -> CCMR1[9:8]=01 ; CCMR1[1:0] = 01
155     // CCMR1[9:8]        01: CC2通道被配置为输入, IC2映射在TI2上;
156     // CCMR1[1:0]       01: CC1通道被配置为输入, IC1映射在TI1上;
157
158
159   /* Write to TIMx CCER */
160   TIMx->CCER = tmpccer;
161     //跟函数的参数有关系
162
163 }

请看上面的注释

谢谢留言分享

原文地址:https://www.cnblogs.com/caohenry999/p/12622362.html

时间: 2024-10-14 19:32:18

[原创] STM32 定时器TIMx 编码器应用 函数 TIM_EncoderInterfaceConfig 分析的相关文章

[stm32] STM32的通用定时器TIMx系统了解

通用定时器(TIMx) 一.TIMx简介 二.TIMx主要功能 三.TIMx功能描述 3.1 时基单元 3.2 计数器模式 3.3 时钟选择 3.4 捕获/比较通道 3.5 输入捕获模式 3.6 PWM输入模式 3.7 强置输出模式 3.8 输出比较模式 3.9 PWM 模式 3.10 单脉冲模式 四.简单例子理解TIMx 4.1 使得PB5-TIM3通道2产生频率为12.5Hz的方波,该方波控制LED1的闪烁 4.2 周期控制通用定时器3的2通道,实现1KHz的不同占空比波形,控制LED实现呼

STM32 定时器用于外部脉冲计数(转)

源:STM32 定时器用于外部脉冲计数 STM32 定时器(一)——定时器时间的计算 STM32的定时器是灰常NB的,也是灰常让人头晕的(当然是对于白菜来说的). STM32中的定时器有很多用法: (一)系统时钟(SysTick) 设置非常简单,以下是产生1ms中断的设置,和产生10ms延时的函数: void RCC_Configuration(void) { RCC_ClocksTypeDef RCC_ClockFreq; SystemInit();//源自system_stm32f10x.c

第八章:STM32定时器

时间:2014年8月15日 一.定时器种类:      1.四个可同步运行的通用定时器(TIM2~TIM5),每个均有一个16位的自动加载递增/递减计数器.一个16位预分频器和4个独立的通道.       2.两个16位高级控制定时器(TIM1和TIM8)         特点:由一个可编程预分频器驱动的16为自动装载 计数器组成,与通用定时器有共同处,但功能更强大.       3.两个基本定时器(TIM6和TIM7)        特点:主要用于产生DAC触发信号,也可以当作通用的16为时基

STM32定时器的预装载寄存器与影子寄存器之间的关系【转】

首先转载:   STM32定时器的预装载寄存器与影子寄存器之间的关系 本文的说明依据STM32参考手册(RM0008)第10版:英文:http://www.st.com/stonline/products/literature/rm/13902.pdf中译文:http://www.stmicroelectronics.com.cn/stonline/mcu/images/STM32_RM_CH_V10_1.pdf 在STM32参考手册的第13.14章中,都有一张定时器的框图,下面是第14章中定时

基于STM32的旋转编码器

..\..\SYSTEM\usart\usart.c(1): error:  #5: cannot open source input file "sys.h": No such file or directory #include "..\sys\sys.h"这样就可以找到路径了 再次编译出现了问题 ..\..\SYSTEM\usart\..\sys\sys.h(3): error:  #5: cannot open source input file "

Unity时钟定时器插件——Vision Timer源码分析之一

Unity时钟定时器插件--Vision Timer源码分析之一 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 因为项目中,UI的所有模块都没有MonBehaviour类(纯粹的C#类),只有像NGUI的基本组件的类是继承MonoBehaviour.因为没有继承MonoBehaviour,这也不能使用Update,InVoke,StartCoroutine等方法,这样就会显得很蹩脚.后来一个同事添加vp_Timer和vp_TimeUti

(转)x264源码分析(1):main、parse、encode、x264_encoder_open函数代码分析

转自:http://nkwavelet.blog.163.com/blog/static/2277560382013103010312144/ x264版本:   x264-snapshot-20140226-2245  1.     首先对主函数进行分析,main函数很简洁,主要有三个步骤,见下图: 2.   接下来分析一下Parse函数中的主要过程: static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t

Unity时钟定时器插件——Vision Timer源码分析之二

Unity时钟定时器插件--Vision Timer源码分析之二 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面的已经介绍了vp_Timer(点击前往查看),vp_TimeUtility相对简单很多,vp_TimeUtility定义了个表示时间的结构Units: C#代码   /// <summary> /// represents a time measured in standard units /// </summar

常用hash函数对比分析(一)

主要目标:寻找一个hash函数,高效的支持64位整数运算,使得在速度.空间等效率相对其它函数函数较高,以及内部运算时32位整数运算. 测试了"RSHash","JSHash","PJWHash","ELFHash","BKDRHash","SDBMHash","DJBHash","DEKHash","BPHash","