0%

HAL库 - 定时器从模式控制器

从模式控制器

从模式控制器
从模式控制器可以作为从机被控制(控制定时器的启、停、复位、增、减)
也可以作为主机控制别人(比如另一个定时器、ADC、DAC等)
两种模式可以同时使用。

从模式控制器的工作模式

作为从机(被控制)作为主机(控制别人)
Slave Mode Disable
从模式禁止
Reset
复位
Encoder Mode 1
编码器模式1
Enable
使能
Encoder Mode 2
编码器模式2
Update
更新
Encoder Mode 3
编码器模式3
Compare Pulse
输出比较脉冲
Reset Mode
复位模式
Compare OC1Ref
输出比较参考信号1
Gated Mode
门模式
Compare OC2Ref
输出比较参考信号2
Trigger Mode
触发模式
Compare OC3Ref
输出比较参考信号3
External Clock Mode 1
外部时钟模式1
Compare OC4Ref
输出比较参考信号4
1、从模式禁止

不使用从机功能
从模式禁止

2、复位模式

使用TRGI的上升沿来复位CNT,同时产生Update事件
复位模式

3、门模式

使用TRGI控制时基单元的开关
门模式

4、触发模式

使用TRGI上升沿来启动定时器
触发模式

5、外部时钟模式1

把TRGI作为定时器的时钟
外部时钟模式1

6、使能

通过TRGO把时基单元的开关状态输出出去
使能

7、更新

每产生一个Update时基就向TRGO输出一个脉冲
更新

8、编码器模式

模式1:在A相的边沿计数(Counting On TI1 Edge)
模式2:在B相的边沿计数(Counting On TI2 Edge)
模式3:双边沿计数(Counting On Both Edge)

常用函数

HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
作用:启动编码器

HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
作用:停止编码器

示例:占空比测量

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
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);//TIM3发送PWM
while (1)
{
//1、清除CC1标志位
__HAL_TIM_CLEAR_FLAG(&htim1,TIM_FLAG_CC1);
//2、启动定时器(CH1和CH2的输入捕获)
HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_2);
//3、等待CC1标志位并再次清除
while(__HAL_TIM_GET_FLAG(&htim1,TIM_FLAG_CC1) == 0);
__HAL_TIM_CLEAR_FLAG(&htim1,TIM_FLAG_CC1);
//4、再次等待CC1标志位
while(__HAL_TIM_GET_FLAG(&htim1,TIM_FLAG_CC1) == 0);
//5、关闭定时器
HAL_TIM_IC_Stop(&htim1,TIM_CHANNEL_1);
HAL_TIM_IC_Stop(&htim1,TIM_CHANNEL_2);
/*
6、计算测量结果
周期 = CCR1 * 分辨率
占空比 = (CCR2 / CCR1) * 100%
*/
uint16_t ccr1 = __HAL_TIM_GET_COMPARE(&htim1,TIM_CHANNEL_1);
uint16_t ccr2 = __HAL_TIM_GET_COMPARE(&htim1,TIM_CHANNEL_2);

float period = ccr1 * 1e-6f;
float pulseWidth = ccr2 * 1e-6f;
float duty = pulseWidth / period;

//串口发送周期、脉宽、占空比
char ch_period[8];
sprintf(ch_period, "%.1f", period*1e6f);
HAL_UART_Transmit(&huart1, (const uint8_t *)"周期=", 7, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (uint8_t*)ch_period, strlen(ch_period), HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (const uint8_t *)"us", 2, HAL_MAX_DELAY);
char ch_pulsewidth[8];
sprintf(ch_pulsewidth, "%.1f", pulseWidth*1e6f);
HAL_UART_Transmit(&huart1, (const uint8_t *)"脉宽=", 7, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (uint8_t*)ch_pulsewidth, strlen(ch_pulsewidth), HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (const uint8_t *)"us", 2, HAL_MAX_DELAY);
char ch_duty[8];
sprintf(ch_duty, "%.1f", duty*100.0f);
HAL_UART_Transmit(&huart1, (const uint8_t *)"占空比=", 10, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (uint8_t*)ch_duty, strlen(ch_duty), HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1, (const uint8_t *)"%", 1, HAL_MAX_DELAY);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

编码器实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  /* USER CODE BEGIN 2 */
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_1);//启动TIM3计时器编码器,通道1
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_2);//启动TIM3计时器编码器,通道2
OLED_Init();
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */

while (1)
{
uint8_t cnt = __HAL_TIM_GET_COUNTER(&htim3);//读取TIM3计时器CNT的值
OLED_ShowString(1,1,"cnt:");
OLED_ShowNum(1,5,cnt,2);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}