通用定时器脉冲计数实验(STM32CubeMx配置)

原理了解

在这里插入图片描述
使用通用定时器进行脉冲计数实验需要用到图中红色框框出来的时基单元,通过选用外部时钟模式1中的通道一或通道二,这里以通道一为例,选择TI1FP1为触发信号(这里不选用TI1F_ED为触发信号的原因为其是双边沿捕获,而实验是一个脉冲数计数+1),配置从模式控制器为计数然后就可以实现脉冲计数。

STM32CubeMx配置

定时器及通道选择

脉冲计数实验前提是产生一个脉冲,所以这里需要用到一个按键,查看硬件原理图结合数据手册在这里插入图片描述
在这里插入图片描述
我们选用定时器2通道1作为我们的外部时钟模式一,同时作为按键使用,这里在增加一个按键PE4,作为等会清空脉冲计数使用,配置如下:
在这里插入图片描述
从模式选择外部时钟模式1,触发源选择TI1FP1,然后配置不分频,因为一个脉冲数计数器+1,接着是自动重装载值选择65335,因为这样能计的最大脉冲数则为65536个,接着就是触发极性配置为上升沿触发,接着就可以生成工程了。

工程生成及代码编写

工程文件

生成工程后我们可以看到左边已经有了相关代码:
在这里插入图片描述
来看一下脉冲计数实验中几个比较重要的函数:

void MX_TIM2_Init(void);				//定时器2初始化函数
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle);//相关时钟,IO口配置
HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);	//使能输入捕获并启动计数器
__HAL_TIM_GET_COUNTER(__HANDLE__);			//这是一个宏定义,用于获取计数器的值
__HAL_TIM_SET_COUNTER(__HANDLE__);			//这是一个宏定义,用于设置计数器的值

代码编写

首先打开tim.c文件:在这里插入图片描述

可以看到在void MX_TIM2_Init(void)函数中已经生成了我们刚刚STM32CubeMx配置的定时器设置,以及在void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)中开启了相对应的时钟及IO口配置,我们需要做的就是在用户代码区添加使能输入捕获并启动计数器函数,即:

HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_1);

key.c编写

由于添加了一个按键用于清空当前的脉冲计数值,所以独立写了一个按键函数:

#include "key.h"

uint8_t key_scan()
{
    static uint8_t key_sta = 1;
    uint8_t key_value = 0;
    
    if(key_sta && (KEY0 == 0))
    {
        HAL_Delay(10);
        key_sta = 0;
        
        if(KEY0 == 0)
            key_value = KEY0_PRESS;

    }
    else if(KEY0)
    {
        key_sta = 1;
    }
    
    return key_value;
}

key.h文件

#ifndef __KEY_H
#define __KEY_H

#include "main.h"

#define KEY0_PRESS 1        //PE4按下状态

#define KEY0 HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)      //读取当前PE4状态

uint8_t key_scan(void);

#endif

main.c编写

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
    uint16_t oldcnt = 0;        //记录旧脉冲计数
    uint16_t curcnt = 0;        //更新脉冲计数
    uint8_t key = 0;            //记录键值
    uint8_t t =0;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    key = key_scan();
    if(key == KEY0_PRESS)
    {
        __HAL_TIM_SET_COUNTER(&htim2, 0);
    }
    
    curcnt = __HAL_TIM_GET_COUNTER(&htim2);
    if(oldcnt != curcnt)
    {
        oldcnt = curcnt;
        printf("CNT = %d\r\n", oldcnt);
    }
    
    /*LED翻转证明程序正常工作*/
    t++;
    if(t > 20)
    {
        t = 0;
        HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);
    }
    HAL_Delay(10);
  }
  /* USER CODE END 3 */
}

这样脉冲计数实验就完成了,如果想试一下双边沿触发,则可将触发极性修改为双边沿触发,即在tim.c中修改如下两个设置即可:

  sSlaveConfig.InputTrigger = TIM_TS_TI1F_ED;
  sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_BOTHEDGE;

若想使脉冲计数的值可以达到更大,则打开更新中断,并定义多一个变量记录溢出次数即可。

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葛叶灬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值