[原创] STM32 定时器TIMx 编码器应用 函数 TIM_EncoderInterfaceConfig 分析
2021-03-28 07:25
标签:分析 *** inpu pre 今天 tmp selection 触发器 驱动 今天把STM32 定时器输入作为 编码器接口相关的 函数 TIM_EncoderInterfaceConfig ,好好分析了一遍 因为网上不少人对这个函数有问题 请看上面的注释 谢谢留言分享 [原创] STM32 定时器TIMx 编码器应用 函数 TIM_EncoderInterfaceConfig 分析 标签:分析 *** inpu pre 今天 tmp selection 触发器 驱动 原文地址:https://www.cnblogs.com/caohenry999/p/12622362.html 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) /*! 21 //#define TIM_SMCR_SMS_0 ((uint16_t)0x0001) /*! 22 //#define TIM_SMCR_SMS_1 ((uint16_t)0x0002) /*! 23 //#define TIM_SMCR_SMS_2 ((uint16_t)0x0004) /*! 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) /*! 57 //#define TIM_CCMR1_CC2S ((uint16_t)0x0300) /*!
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) /*! 88 //#define TIM_CCMR1_CC2S_0 ((uint16_t)0x0100) /*!
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) /*!102 //#define TIM_CCER_CC2P ((uint16_t)0x0020) /*!
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 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 | (0x0002136 // 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 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 }
上一篇:(转)解决Eclipse加载图片或网页出现404错误
下一篇:HTTP
文章标题:[原创] STM32 定时器TIMx 编码器应用 函数 TIM_EncoderInterfaceConfig 分析
文章链接:http://soscw.com/index.php/essay/68942.html