文章目录
定时器编程实战4:通用定时器脉冲计数
硬件设计
本实验用到的硬件资源有:
1) 外部按键
2) 串口
3) 定时器 TIM9
本实验,我们将读取TIM9_CH1(PA2)上的高电平,通过按键输入高电平给PA2,并从串口打印脉冲次数。
本实验要用到串口,所以在串口实验的工程文件上进行更改。
4)硬件连接方式:
脉冲计数实验原理
将外部的脉冲信号设置为定时器的时钟源频率,在每次定时器溢出后记录。配置如图
CubeMX配置
在 TIMERS->TIM9 配置项中,配置 slave mode的值为External Clock Mode 1,然后选Trigger Source 的值为TI1FP1。如下图
进入 Configuration->Parameter Setting 配置项,Counter Settings 配置栏下选项就是用来配置定时器的预分频系数,自动装载值,计数模式,时钟分频因子。如下图
同时右边的芯片引脚图会自动配置好PA2,默认情况下不需要用户更改配置。
LED和USART1的配置参考之前的文章。
进行完上面的操作之后,接下来我们便是生成工程代码。
通用定时器脉冲计数实验配置步骤
1.配置定时器基础工作参数
这里的代码为CubeMX配置。
//tim.c
TIM_HandleTypeDef htim9;
void MX_TIM9_Init(void)
{
TIM_SlaveConfigTypeDef sSlaveConfig = {0}; //从模式结构体
htim9.Instance = TIM9; //通用定时器9
htim9.Init.Prescaler = 0; //分频系数
htim9.Init.CounterMode = TIM_COUNTERMODE_UP; //向上计数器
htim9.Init.Period = 65535; //自动预加载值
htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//时钟分频因子
htim9.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;//失能自动装载值预装载
if (HAL_TIM_Base_Init(&htim9) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; //从模式
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1; //输入触发模式
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;//触发极性
sSlaveConfig.TriggerFilter = 0; //触发过滤器
if (HAL_TIM_SlaveConfigSynchro(&htim9, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM9_Init 2 */
HAL_TIM_IC_Start(&htim9, TIM_CHANNEL_1);
/* USER CODE END TIM9_Init 2 */
}
2.定时器输入捕获MSP初始化
这里的代码为CubeMX配置。
//tim.c
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(tim_baseHandle->Instance==TIM9)
{
/* TIM9 clock enable */
__HAL_RCC_TIM9_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM9 GPIO Configuration
PA2 ------> TIM9_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF3_TIM9;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
3.使能输入捕获并启动计数器
//tim.c
void MX_TIM9_Init(void)
{
/* MX CODE BEGIN */
//。。。。。。。。
/* MX CODE END */
/* USER CODE BEGIN */
HAL_TIM_IC_Start(&htim9, TIM_CHANNEL_1);
/* USER CODE END */
}
4.获取计数器的值
//main.c
int main(void)
{
/* USER CODE BEGIN */
uint16_t curcnt;
uint16_t oldcnt = 0;
uint8_t key;
/* USER CODE END */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM9_Init();
MX_USART1_UART_Init();
while (1)
{
/* USER CODE BEGIN */
key = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2);
if(key == GPIO_PIN_SET)
{
curcnt = __HAL_TIM_GET_COUNTER(&htim9) + 48;
// __HAL_TIM_SET_COUNTER(&htim9, 0); //设置计数值为0
}
if(oldcnt != curcnt)
{
oldcnt = curcnt;
HAL_UART_Transmit(&huart1, (uint8_t *)&oldcnt, 1, 1000);
}
HAL_GPIO_TogglePin(GPIOC, LED0_Pin);
HAL_Delay(500);
/* USER CODE END */
}
}
实验结果
每次按下按键,串口会接收一个脉冲数据并累加,如下图