1.主计时器负责设置脉冲输出的频率以及输出脉冲,从计数器所控制输出的脉冲数。
2.具体过程是这样的,主进程启动主从计时器,从计时器通过主计时器输出的触发信号开始脉冲计数,当达到指定的计数值后,产生中断停止主计时器输出,直到主进程再次开启这一过程。
TIM_SLAVEMODE_EXTERNAL1 <=== 其实它就是内部的触发源做为时钟 而非外部时钟
触发源来一个脉冲 从定时器计一个数,这就是我们想要的结果。
TIM2->CNT就是我们想要的脉冲数, 停止时将它CLR.
TIM_SLAVEMODE_DISABLE //禁用从模式
TIM_SLAVEMODE_RESET //触发源 复位从定时器CNT
TIM_SLAVEMODE_GATED //低电平时计数器启动计数,高电平时停止计数
TIM_SLAVEMODE_TRIGGER //可选内部时钟和外部时钟
TIM_SLAVEMODE_EXTERNAL1 //触发源做为时钟 记数 这个功能很好
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193/* TIM1 init function */ void MX_TIM1_Init(void) { /* USER CODE BEGIN TIM1_Init 0 */ /* USER CODE END TIM1_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; /* USER CODE BEGIN TIM1_Init 1 */ /* USER CODE END TIM1_Init 1 */ htim1.Instance = TIM1; htim1.Init.Prescaler = 16; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 65535; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 0; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } /* TIM2 init function */ void MX_TIM2_Init(void) { /* USER CODE BEGIN TIM2_Init 0 */ /* USER CODE END TIM2_Init 0 */ TIM_SlaveConfigTypeDef sSlaveConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM2_Init 1 */ /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 0xffffffff; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; sSlaveConfig.InputTrigger = TIM_TS_ITR0; if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ /* USER CODE END TIM2_Init 2 */ } //======================================================================================= void StartMotor1PWMFunc(u16 num) { switch(num) { case 0x00: if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4) == HAL_OK) { HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_4); //开启MOTOR1通道的输入捕获中断 } break; case 0x01: if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2) == HAL_OK) { HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_2); //开启MOTOR2通道的输入捕获中断 } break; case 0x02: if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3) == HAL_OK) { HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_3); //开启MOTOR3通道的输入捕获中断 } break; case 0x03: if (HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_1) == HAL_OK) //从定时器没有 { //HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_1); //开启MOTOR4通道的输入捕获中断 } break; default: break; } } //======================================================================================= void StopMotor1PWMFunc(u16 num) { htim1.Instance->CR1 &= ~(TIM_CR1_CEN); //Counter disabled SetCounterFunc(0); switch(num) { case 0x00: if(HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_4)==HAL_OK) //关闭MOTOR1的PWM输出 { HAL_TIM_OC_Stop_IT(&htim2,TIM_CHANNEL_4) ; //关闭定时器的通道1的输入中断捕获 } break; case 0x01: if(HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_2)==HAL_OK) //关闭MOTOR2的PWM输出 { HAL_TIM_OC_Stop_IT(&htim2,TIM_CHANNEL_2) ; //关闭定时器的通道1的输入中断捕获 } break; case 0x02: if(HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_3)==HAL_OK) //关闭MOTOR3的PWM输出 { HAL_TIM_OC_Stop_IT(&htim2,TIM_CHANNEL_3) ; //关闭定时器的通道1的输入中断捕获 } break; case 0x03: if(HAL_TIM_PWM_Stop_IT(&htim9, TIM_CHANNEL_1)==HAL_OK) 从定时器没有 { //HAL_TIM_OC_Stop_IT(&htim2,TIM_CHANNEL_1) ; //关闭定时器的通道1的输入中断捕获 } break; default: break; } }
最后
以上就是无辜芒果最近收集整理的关于巨坑的STM32 定时器从模式 外部时钟 --------高速脉冲计数源码的全部内容,更多相关巨坑的STM32内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复