STM32---通用定时器(二)相关实验

写在前面:前面我们学习了基本定时器、通用定时器的相关理论部分,了解到通用定时器的结构框图,总共包含六大模块:时钟源、控制器、时基单元、输入捕获、公共部分以及输出捕获。对相关模块的使用也做详细的讲解。本节我们主要是对上节的理论部分进行实验的操作,力争对理论部分有更好的掌握。

本节主要操作三个实验:

1、通用定时器中断实验;2通用定时器输出PWM波形;3、通用定时器输入捕获;

基本定时器回顾:STM32---基本定时器(含源码)小白可入_stm32简易定时器-CSDN博客

通用定时器基础回顾:STM32---通用定时器(一)理论基础-CSDN博客

一、通用定时器中断实验

1.1实验描述

        通过STM32的通用定时器完成计数,在中断中点亮LED灯;

        在主函数进行LED1进行亮灭翻转,在利用通用定时器进行中断,在中断中实现LED0的亮灭翻转。

1.2相关寄存器

        使用通用定时器之前,我们需要根据定时器的结构框图,确定以下的一些问题:

1、使用定时器的哪个时钟源?

2、是否使用通用定时器的输入捕获部分?

3、是否使用通用定时器的输出比较部分?

4、是否使用通用定时溢出后的中断?

        在这里我们确定,使用定时器的内部时钟源,不使用输入捕获,也不使用输出捕获,但是需要使用定时器溢出后的中断,因为在中断中我们需要进行点灯。

1.控制寄存器(TIMx_CR1)

(APRE)自动重载寄存器允许位:如果 ARPE 位置 1,ARR 起缓冲作用,即只有在更新事件发生时才会把 ARR的值写入其影子寄存器里;如果 ARPE 位置 0,那么修改自动重载寄存器的值时,该值会马上被写入其影子寄存器中,从而立即生效。

CMS[1:0]选择中央对齐模式:分为边沿对齐(即递增或递减技术模式)、中央对齐模式;

DIR :用于控制定时器的计数方向,递增计数或递减计数;

CEN 位:用于使能计数器的工作,必须要设置该位为 1,计数器才会开始计数。

2、从模式控制寄存器(TIMx_SMCR)

主要用于选择计数器输入的时钟来源; 

  SMS[2:0]位:我们设置 SMS[2:0]=000,禁止从模式,这样 PSC 预分频器的时钟就直接来自内部时钟(CK_INT),按照我们例程 sys_stm32_clock_init 函数的配置,频率为 72Mhz(APB1总线时钟频率的 2 倍)

3、DMA/中断使能寄存器(TIMx_DIER)

 该寄存器用于使能/失能触发 DMA 请求、捕获/比较中断以及更新中断。

4、状态寄存器(TIMx_SR) 

        在通用定时器中断实验我们用到更新中断标志位,当定时器更新中断到来后,位 0(UIF)会由硬件置 1,我们需要在中断服务函数里面把该位清零。

5、计数寄存器(TIMx_CNT) 

        TIM2/TIM3/TIM4/TIM5 的计数寄存器都是 16 位有效的,计数模式可以是递增计数模式、
递减计数模式和中心对齐计数模式,计数值范围 0~65535。可以直接写该寄存器设置计数的初
始值,也可以读取该寄存器获取计数器值 。

6、预分频寄存器(TIMx_PSC)

        定时器的预分频寄存器都是 16 位的,即写入该寄存器的数值范围是 0 到 65535,表示 1 到
65536 分频。

7、自动重载寄存器(TIMx_ARR) 

        自动重载寄存器是低 16 位有效。该寄存器可以由 APRE 位设置是否进行缓冲。计数器的
值会和自动重装寄存器影子寄存器进行比较,当两者相等,定时器就会溢出,从而发生更新事
件,如果打开了更新中断,还会发生更新中断。 

1.3 程序设计

程序源码

链接:https://pan.baidu.com/s/1cYrbkah9Awvf4TZ_-NrN0A 
提取码:1022

timer.c

#include "./BSP/TIMER/timer.h"
#include "./BSP/LED/led.h"
/**
* @brief通用定时器定时中断初始化函数
* @note
*通用定时器的时钟来自 APB1,当 PPRE1 ≥ 2 分频的时候
*通用定时器的时钟为 APB1 时钟的 2 倍, 而 APB1 为 36M, 所以定时器时钟 = 72Mhz
*定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
*              Ft=定时器工作频率,单位:Mhz
* @param       arr: 自动重装值。
* @param       prc: 时钟预分频数
* @retval无
*/
TIM_HandleTypeDef timer_handle;/* 定义句柄 */
void timer_init(uint16_t prc,uint16_t arr)/* 定义变量:1、arr自动重装值2、prc预分频系数*/
{timer_handle.Instance=TIM5;         /* 定时器TIM5基地址 */timer_handle.Init.Prescaler=prc;    /* 预分频系数 */timer_handle.Init.Period=arr;       /* 自动重装载值 */timer_handle.Init.CounterMode=TIM_COUNTERMODE_DOWN; /* 递减计数模式 */HAL_TIM_Base_Init(&timer_handle);     HAL_TIM_Base_Start_IT(&timer_handle);  /* 使能定时器以及使能定时器更新中断 */}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM5)/* 判断是否为TIM5 */{__HAL_RCC_TIM5_CLK_ENABLE();    /* 使能定时器时钟 */HAL_NVIC_EnableIRQ(TIM5_IRQn);  /* 使能定时器TIM5中断 */HAL_NVIC_SetPriority(TIM5_IRQn,2,2);/* 设置中断优先级 */}
}
/**
* @brief定时器中断服务函数
* @param无
* @retval无
*/
void TIM5_IRQHandler (void)
{HAL_TIM_IRQHandler(&timer_handle);  /* 定时器公共处理函数,会自动清除定时器溢出中断标志位 */}
/**
* @brief定时器溢出中断回调函数
* @param句柄
* @retval无
*/void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)    {if(htim->Instance==TIM5){HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);}}

led.c

#include "./BSP/LED/led.h"
void LED_init()//LED初始化
{__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitTypeDef gpio_init_struct;gpio_init_struct.Mode=GPIO_MODE_OUTPUT_PP;gpio_init_struct.Pin=GPIO_PIN_5;gpio_init_struct.Speed=GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &gpio_init_struct);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);__HAL_RCC_GPIOE_CLK_ENABLE();gpio_init_struct.Mode=GPIO_MODE_OUTPUT_PP;gpio_init_struct.Pin=GPIO_PIN_5;gpio_init_struct.Speed=GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOE, &gpio_init_struct);HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);}

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/timer.h"int main(void)
{HAL_Init();                              /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);      /* 设置时钟, 72Mhz */delay_init(72);                          /* 延时初始化 */LED_init();timer_init(7200-1,5000-1);              /* 设置预分频器系数,以及重装在寄存器的值 */while(1){ delay_ms(500);HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);}
}

1.4实验现象

通用定时器点灯

二、通用定时器输出PWM波形

2.1 实验描述

        使用通用定时器实现PWM波形的输出;PWM:脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。

        在此实验中,我们需要输出电平信号,所以我们需要用到输出比较,通过计数器的值同捕获/比较寄存器的值进行比较,输出信号,再通过控制输出比较部分的工作模式,有效电平,达到PWM波形的输出。

        上图为PWM波形产生的原理,确定一个自动重载寄存器的值,设定一个比较值,让计数器的值不断增加(递增模式),与比较值进行比较,当大于比较值时,输出一种电平信号,当小于比较值时,输出另一种电平信号(具体输出那种信号,由输出模式控制)。

        由此可见,影响PWM波形的周期参数为:自动重装载寄存器ARR的值,

                        影响PWM波形的占空比的参数为:捕获/比较寄存器CRR的值。

        定时器产生 PWM 的方式有许多种,下面我们以边沿对齐模式(即递增计数模式/递减计数
模式)为例,PWM 模式 1 或者 PWM 模式 2 产生 PWM 的示意图。

         使用 TIM3 通道 2(由 PB5 复用)输出 PWM, PB5 引脚连接了 LED0,从而实现 PWM 输
出控制 LED0 亮度,达到呼吸灯的效果。

2.2 相关寄存器

1.捕获/比较模式寄存器 1/2(TIMx_CCMR1/2)

        TIMx _CCMR1 和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 CH2,而 TIMx_CCMR2 控制CH3 和 CH4。

        OC2M[2:0]就是对应着通道 2 的模式设置,此部分由 3 位组成。总共可以配置成 8 种
模式,我们使用的是 PWM 模式,所以这 3 位必须设置为 110 或者 111,分别对应 PWM 模式 1
和 PWM 模式 2。两种 PWM 模式的区别就是输出有效电平的极性相反。

       OC2PE 控制输出比较通道 2 的预装载使能,实际就是控制 CCR2 寄存器是否进行缓冲。因为 CCR2 寄存器也是有影子寄存器的,影子寄存器才是真正起作用的寄存器。

        CC2S[1:0]用于设置通道 2 的方向(输入/输出)默认设置为 0,就是设置通道作为输出使用。

2.捕获/比较使能寄存器(TIMx_CCER)

该寄存器控制着各个输入输出通道的开关和极性。

         要让 TIM3 的 CH2 输出 PWM 波,这里我们要使能 CC2E 位,该位是通道 2 输入/输出使能位,要想 PWM 从 IO 口输出,这个位必须设置为 1。CC2P 位是设置通道2 的输出极性。

3.捕获/比较寄存器 1/2/3/4(TIMx_CCR1/2/3/4)  

        在输出模式下,捕获/比较寄存器影子寄存器的值与 CNT 的值比较,根据比较结果产生相
应动作,利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的占空比了。 

2.3程序设计

程序源码

链接:https://pan.baidu.com/s/1lsbm3VWhuhO4I5BEoQHNZQ 
提取码:1022

 pwm.c

#include "./BSP/PWM/pwm.h"TIM_HandleTypeDef btim_pwm_handle; /* 定义句柄 */ /*** @brief通用定时器 TIM3 通道2 PWM 输出初始化函数(使用 PWM 模式 1)
* @note*通用定时器的时钟来自 APB1,当 D2PPRE1≥2 分频的时候
*通用定时器的时钟为 APB1 时钟的 2 倍, 而 APB1 为 36M, 所以定时器时钟 = 72Mhz
*定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
*              Ft=定时器工作频率,单位:Mhz
* @param       arr: 自动重装值。
* @param       psc: 时钟预分频数
* @retval
*/void btim_pwm_init(uint16_t arr,uint16_t psc){  btim_pwm_handle.Instance=TIM3;   /* 定时器TIM3基地址 */btim_pwm_handle.Init.Period=arr; /* 自动重装载值 */btim_pwm_handle.Init.Prescaler=psc;/* 预分频系数 */btim_pwm_handle.Init.CounterMode=TIM_COUNTERMODE_UP;  /* 递增计数模式 */HAL_TIM_PWM_Init(&btim_pwm_handle); /* 初始化PWM */TIM_OC_InitTypeDef timx_oc_pwm_struct={0};/* 定义结构体,并赋初值为0,这一点是很重要的 */timx_oc_pwm_struct.OCMode=TIM_OCMODE_PWM1;/* 设置输出PWM模式,此处采用模式1 */timx_oc_pwm_struct.Pulse=arr/2;/* 设置捕获/比较寄存器的值,此处设置为自动重装载值的一半,则输出的PWM波形的占空比为50% */timx_oc_pwm_struct.OCPolarity=TIM_OCPOLARITY_LOW;/* 输出比较极性为低 */HAL_TIM_PWM_ConfigChannel(&btim_pwm_handle,&timx_oc_pwm_struct,TIM_CHANNEL_2);/* 定时器的 PWM 通道设置初始化函数 */HAL_TIM_PWM_Start(&btim_pwm_handle, TIM_CHANNEL_2);/* 定时器的 PWM 输出启动函数,参数1为句柄,参数2为通道数 */}/**
* @brief定时器底层驱动,时钟使能,引脚配置此函数会被 HAL_TIM_PWM_Init()调用
* @param       htim:定时器句柄
* @retval无
*/ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim){if(htim->Instance==TIM3)/* 判断是否为定时器3 */{__HAL_RCC_TIM3_CLK_ENABLE();/* 使能定时器时钟 */__HAL_RCC_GPIOB_CLK_ENABLE();/* 使能输出IO的时钟 */GPIO_InitTypeDef gpio_init_struct;gpio_init_struct.Mode=GPIO_MODE_AF_PP;gpio_init_struct.Pull = GPIO_PULLUP;gpio_init_struct.Pin=GPIO_PIN_5;gpio_init_struct.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &gpio_init_struct);__HAL_RCC_AFIO_CLK_ENABLE();/* 使能重映射时钟 */__HAL_AFIO_REMAP_TIM3_PARTIAL(); /* IO 口 REMAP 设置,设置重映射 */}}

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/PWM/pwm.h"
uint8_t dir=1;
uint16_t ccr=0;
int main(void)
{HAL_Init();                              /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);      /* 设置时钟, 72Mhz */delay_init(72);                          /* 延时初始化 */led_init();                              /* LED初始化 */btim_pwm_init(500-1,72-1);/* 72M/72=1M 的计数频率,自动重装载为 500,那么 PWM 频率为 1M/500=2kHZ */while(1){ delay_ms(10);if(dir) ccr++;else  ccr--;if(ccr>400)   dir=0;if(ccr==0) dir=1;__HAL_TIM_SET_COMPARE(&btim_pwm_handle,TIM_CHANNEL_2,ccr); /* 修改比较值控制占空比,达到呼吸灯的效果 */}
}

2.4实验现象

PWM呼吸灯

示波器测量PWM波形

三、通用定时器输入捕获实验

3.1 实验描述

        输入捕获模式可以用来测量脉冲宽度或者测量频率,我们用来测量脉冲的宽度,即给通用定时器的输入捕获端一个高电平,测量出高电平的时间(低电平相同)。

        使用 TIM5_CH1 来做输入捕获,捕获 PA0 上的高电平脉宽,并将脉宽时间通过串口打
印出来,然后通过按 WK_UP 按键,模拟输入高电平。

输入捕获脉宽测量原理:

t1 到 t2 的时间段,就是我们需要测量的高电平时间测量方法为:

        假设定时器的计数器工作在递增模式,设置输入通道为上升沿触发,则在t1时刻,由于上升沿的到来,就会发生捕获事件,在捕获事件中(中断),我们将计数器的值清零,并将触发方式改为下降沿触发。        

        这样在t2时刻,由于下降沿触发,就会再次发生捕获事件。捕获事件发生时,计数器的值会被所存放捕获/比较寄存器中。

        这样我们将捕获/比较寄存器中的值再加上一系列的溢出次数(溢出次数可以通过更新中断统计),就能算出高电平脉冲的时间。

计数个数=N*(ARR+1)+ CCRx2。N溢出次数,ARR自动重装载值,CCRx2时间t2点,捕获/比较寄存器的值.

高电平时间=计数个数*计数3.2器计1个数的时间;

3.2相关寄存器

TIMx_ARR、TIMx_PSC、TIMx_CCMR1、TIMx_CCER、TIMx_DIER、TIMx_CR1、TIMx_CCR1 这些寄存器在前面的章节都有提到。

1.捕获/比较模式寄存器 1/2(TIMx_CCMR1/2)

        该寄存器在输入模式和输出模式下,功能是不一样的,TIMx_CCMR1 寄存器对应于通道 1 和通道 2 的设置,CCMR2 寄存器对应通道 3和通道 4。

        CC1S[1:0],这两个位用于 CCR1 的通道配置,这里我们设置 IC1S[1:0]=01,也就是配
置 IC1 映射在 TI1 上。

        输入捕获 1 预分频器 IC1PSC[1:0],这个比较好理解。我们是 1 次边沿就触发 1 次捕获,所
以选择 00 就行了。

        输入捕获 1 滤波器 IC1F[3:0],这个用来设置输入采样频率和数字滤波器长度。一般不需要进行滤波

  2.捕获/比较使能寄存器(TIMx_CCER)

        使能输入捕获,必须设置 CC1E=1,而 CC1P 则根据自己的需要来配置。我们这里是保留默认设置值 0,即高电平触发捕获。 

此外我们需要开启DMA/中断使能寄存器:用于计数溢出次数。

3.3程序设计

链接:https://pan.baidu.com/s/1ZinCNBBShkMFLSA-bZlo6w 
提取码:1022

程序文件

timer.c

#include "./BSP/TIMER/timer.h"
#include "./BSP/LED/led.h"TIM_HandleTypeDef tim_ic_handled;/* 定义句柄*/
/*** @brief通用定时器 TIM5通道1输入捕获初始化函数
* @note
*通用定时器的时钟来自 APB1,当 PPRE1 ≥ 2 分频的时候
*通用定时器的时钟为 APB1 时钟的 2 倍, 而 APB1 为 36M, 所以定时器时钟 = 72Mhz
*定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
*              Ft=定时器工作频率,单位:Mhz
*
* @param       arr: 自动重装值
* @param       psc: 时钟预分频数
* @retval
无
*/
void tim_ic_init(uint16_t arr,uint16_t psc)
{tim_ic_handled.Instance=TIM5;                         /* 定时器基地址:定时器 5 */tim_ic_handled.Init.Period=arr;                       /* 自动重装载值:arr */  tim_ic_handled.Init.Prescaler=psc;                    /* 预分频系数:psc */  tim_ic_handled.Init.CounterMode=TIM_COUNTERMODE_UP;   /* 计数模式:向上计数 */        HAL_TIM_IC_Init(&tim_ic_handled); TIM_IC_InitTypeDef tim_ic_cap_csh_struct={0};tim_ic_cap_csh_struct.ICFilter=0;                            /* 通道配置滤波器:不滤波 */tim_ic_cap_csh_struct.ICPolarity=TIM_ICPOLARITY_RISING;      /* 通道捕获方式:上升沿捕获 */tim_ic_cap_csh_struct.ICPrescaler=TIM_ICPSC_DIV1;            /* 通道输入分频:不分频 */tim_ic_cap_csh_struct.ICSelection=TIM_ICSELECTION_DIRECTTI;  /* 通道映射 */  HAL_TIM_IC_ConfigChannel(&tim_ic_handled, &tim_ic_cap_csh_struct, TIM_CHANNEL_1);__HAL_TIM_ENABLE_IT(&tim_ic_handled, TIM_IT_UPDATE);    /* 使能更新中断 ,单独使能定时器中断*/ HAL_TIM_IC_Start_IT(&tim_ic_handled, TIM_CHANNEL_1);  /* 使能通道输入以及使能捕获中断 */}
/**
* @brief通用定时器输入捕获初始化接口HAL 库调用的接口,用于配置不同的输入捕获
* @param       htim:定时器句柄
* @note
此函数会被 HAL_TIM_IC_Init()调用
* @retval
无
*/
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{    if(htim->Instance==TIM5){__HAL_RCC_TIM5_CLK_ENABLE();                     /* 使能定时器5的时钟 */__HAL_RCC_GPIOA_CLK_ENABLE();                    /* 使能捕获IO的时钟 */GPIO_InitTypeDef gpio_init_struct; gpio_init_struct.Mode=GPIO_MODE_AF_PP;           /* IO的工作模式:复用推挽输出 */gpio_init_struct.Pin=GPIO_PIN_0;                 /* IO的引脚:PA0 */gpio_init_struct.Pull=GPIO_PULLDOWN;             /* IO上下拉电阻:下拉电阻 */gpio_init_struct.Speed=GPIO_SPEED_FREQ_HIGH;      /* IO输出速度:高速 */HAL_GPIO_Init(GPIOA, &gpio_init_struct);HAL_NVIC_SetPriority(TIM5_IRQn, 2, 2);           /* 设置中断优先级 */HAL_NVIC_EnableIRQ(TIM5_IRQn);                    /* 开启定时器5中断 */}}
uint8_t g_tim5csh_cap_sta =0;    /* 设置输入捕获状态 */
uint16_t g_tim5csh_cap_val=0;    /* 设置捕获值 */void TIM5_IRQHandler(void){HAL_TIM_IRQHandler(&tim_ic_handled);/*定时器公共处理函数 */}/**
* @brief定时器输入捕获中断处理回调函数
* @param       htim:定时器句柄指针
* @note该函数在 HAL_TIM_IRQHandler 中会被调用
* @retval无
*/void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){if(htim->Instance==TIM5){if((g_tim5csh_cap_sta & 0x80)==0)         /* 还没能成功捕获 */{if((g_tim5csh_cap_sta & 0x40))    /* 捕获到一个下降沿 */{  g_tim5csh_cap_sta |=0x80;      /* 标记捕获到一个下降沿 ,成功捕获到一个高电平脉冲 */g_tim5csh_cap_val = HAL_TIM_ReadCapturedValue(&tim_ic_handled,TIM_CHANNEL_1);  /* 获取捕获值 */TIM_RESET_CAPTUREPOLARITY(&tim_ic_handled,TIM_CHANNEL_1); /*清除之前的下降沿触发模式 */ TIM_SET_CAPTUREPOLARITY(&tim_ic_handled,TIM_CHANNEL_1, TIM_ICPOLARITY_RISING );/*设置新的触发方式:上升沿触发模式 */}else        /* 捕获到一个上升沿降沿 */{    g_tim5csh_cap_sta =0;    g_tim5csh_cap_val=0;g_tim5csh_cap_sta |=0x40;   /* 标记捕获到一个上升沿 */__HAL_TIM_DISABLE(&tim_ic_handled); /* 失能定时器5 */ __HAL_TIM_SET_COUNTER(&tim_ic_handled,0);/*计数器值清零 */ TIM_RESET_CAPTUREPOLARITY(&tim_ic_handled,TIM_CHANNEL_1); /*清除之前的上升沿触发模式 */ TIM_SET_CAPTUREPOLARITY(&tim_ic_handled,TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING );/*设置新的触发方式:下降沿触发模式 */__HAL_TIM_ENABLE(&tim_ic_handled);/* 使能定时器5 */ }     }}      }
/**
* @brief定时器输入捕获中断处理回调函数
* @param       htim:定时器句柄指针
* @note该函数在 HAL_TIM_IRQHandler 中会被调用
* @retval无
*/void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){if(htim->Instance==TIM5){if((g_tim5csh_cap_sta & 0x80)==0){if((g_tim5csh_cap_sta & 0x40))//非0和等于1是两码事{if((g_tim5csh_cap_sta & 0x3f)==0x3f){TIM_RESET_CAPTUREPOLARITY(&tim_ic_handled,TIM_CHANNEL_1); /*清除之前的下降沿触发模式 */ TIM_SET_CAPTUREPOLARITY(&tim_ic_handled,TIM_CHANNEL_1, TIM_ICPOLARITY_RISING );/*设置新的触发方式:上升沿触发模式 */                g_tim5csh_cap_sta |=0x80;g_tim5csh_cap_val=0xffff; }else{g_tim5csh_cap_sta++;}                }           }                   } }

led.c

#include "./BSP/LED/led.h"
void led_init()
{GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOE_CLK_ENABLE();gpio_init_struct.Mode=GPIO_MODE_OUTPUT_OD;gpio_init_struct.Pin=GPIO_PIN_5;gpio_init_struct.Speed=GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOE, &gpio_init_struct);__HAL_RCC_GPIOB_CLK_ENABLE();gpio_init_struct.Mode=GPIO_MODE_OUTPUT_OD;gpio_init_struct.Pin=GPIO_PIN_5;gpio_init_struct.Speed=GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &gpio_init_struct);}

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/timer.h"
uint32_t temp=0;
int main(void)
{HAL_Init();                              /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);      /* 设置时钟, 72Mhz */delay_init(72);                          /* 延时初始化 */led_init();                              /* LED初始化 */usart_init(115200);tim_ic_init(0xffff ,72-1);while(1){ if(g_tim5csh_cap_sta &0x80) /* 是否完成一次按键按下 */{temp=g_tim5csh_cap_sta &0x3f;temp*=65536;temp += g_tim5csh_cap_val;printf("HIGH:%d us\r\n", temp);g_tim5csh_cap_sta=0;}          HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);delay_ms(1000);}
}

3.4实验现象

20240309_175827

总结:本节我们结合上节的通用定时器的基础理论,分别实现了:通用定时器中断实验、通用定时器输出PWM实验、通用定时器输入捕获实验;进行代码书写以及实验测试。大家学习的时候,多多动手定有收获。

创作不易,还请大家多多点赞支持,有问题欢迎评论区讨论!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/272640.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【HarmonyOS】ArkTS-枚举类型

枚举类型 枚举类型是一种特殊的数据类型,约定变量只能在一组数据范围内选择值 定义枚举类型 定义枚举类型(常量列表) enum 枚举名 { 常量1 值, 常量2 值,......}enum ThemeColor {Red #ff0f29,Orange #ff7100,Green #30b30e}使用枚举…

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记05_共谋(中)

1. 默许共谋 1.1. 又称寡头价格协调(Oligopolistic Price Coordination)或有意识的平行行为(Conscious Parallelism) 1.1.1. 在条件允许的情况下,它会发生在市场集中度较高的行业当中 1.1.…

你还可以通过“nrm”工具,来自由管理“npm”的镜像

你还可以通过“nrm”工具,来自由管理“npm”的镜像 nrm(npm registry manager)是npm的镜像管理工具,有时候国外的资源太慢,使用这个就可以快速地在npm源间切换。 1.安装nrm 在命令行执行命令,npm install…

如何免费获得一个市全年的气象数据?降雨量气温湿度太阳辐射等等数据

气象数据一直是一个价值较高的数据,它被广泛用于各个领域的研究当中。气象数据包括有气温、气压、相对湿度、降水、蒸发、风向风速、日照等多种指标,但是包含了这些全部指标的气象数据却较难获取,即使获取到了也不能随意分享。 想要大规模爬取…

抽象的java发送邮箱2.0版本

优化了更多细节 SpringBoot3&#xff1a;前置框架 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframewo…

【工具】Git的24种常用命令

相关链接 传送门&#xff1a;>>>【工具】Git的介绍与安装<< 1.Git配置邮箱和用户 第一次使用Git软件&#xff0c;需要告诉Git软件你的名称和邮箱&#xff0c;否则无法将文件纳入到版本库中进行版本管理。 原因&#xff1a;多人协作时&#xff0c;不同的用户可…

Python匿名函数有知道的吗?

1.函数 按照函数是否有名字分为有名字的函数和匿名函数 匿名函数&#xff1a;定义函数时&#xff0c;不再使用def关键字声明函数&#xff0c;而是使用lambda表达式 匿名函数在需要执行简单的操作时非常有用&#xff0c;可以减少代码冗余 2.有名字的函数 def fn(n):return …

【Redis知识点总结】(二)——Redis高性能IO模型剖析

Redis知识点总结&#xff08;二&#xff09;——Redis高性能IO模型及其事件驱动框架剖析 IO多路复用传统的阻塞式IO同步非阻塞IOIO多路复用机制 Redis的IO模型Redis的事件驱动框架 IO多路复用 Redis的高性能的秘密&#xff0c;在于它底层使用了IO多路复用这种高性能的网络IO&a…

ARTS Week 20

Algorithm 本周的算法题为 1222. 可以攻击国王的皇后 在一个 下标从 0 开始 的 8 x 8 棋盘上&#xff0c;可能有多个黑皇后和一个白国王。 给你一个二维整数数组 queens&#xff0c;其中 queens[i] [xQueeni, yQueeni] 表示第 i 个黑皇后在棋盘上的位置。还给你一个长度为 2 的…

Linux上安装torch-geometric(pyg)1.7.2踩坑记录

重点&#xff1a;1.一定要在创建虚拟环境的时候设置好python版本。2.一定要先确定使用1.X还是2.X的pyg库&#xff0c;二者不兼容。3.一定要将cuda、torch、pyg之间的版本对应好。所以&#xff0c;先确定pyg版本&#xff0c;再确定torch和cuda的版本。 结论&#xff1a;如果在u…

【兔子机器人】修改GO电机id(软件方法、硬件方法)

一、硬件方法 利用上位机直接修改GO电机的id号&#xff1a; 打开调试助手&#xff0c;点击“调试”&#xff0c;查询电机&#xff0c;修改id号&#xff0c;即可。 但先将四个GO电机连接线拔掉&#xff0c;不然会将连接的电机一并修改。 利用24V电源给GO电机供电。 二、软件方…

UDP与TCP:了解这两种网络协议的不同之处

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

实验二(一):IPV4编址及IPV4路由基础实验

一实验介绍 1.关于本实验 IPv4( Internet Protocol Version 4)是 TCP/IP 协议族中最为核心的协议之一。 它工作在 TCP/IP参考模型的网际互联层&#xff0c;该层与 OSI参考模型的网络层相对应。 网络层提供了无连接数据传输服务&#xff0c;即网络在发送分组时不需要先建立连…

BDD - Python Behave log 为每个 Scenario 生成对应的 log 文件

BDD - Python Behave log 为每个 Scenario 生成对应的 log 文件 引言应用 Behave 官网 Log 配置文件项目 SetupFeature 文件steps 文件Log 配置文件environment.py 文件behave.ini 执行结果 直接应用 Python logging 模块方式 1&#xff1a;应用 log 配置文件log 配置文件envir…

ubuntu23.10安装搜狗拼音

1.添加fcitx仓库 sudo add-apt-repository ppa:fcitx-team/nightly 更新: sudo apt-get update 安装fcitx sudo apt-get install fcitx fcitx安装成功 切换输入系统为fcitx

git命令行提交——github

1. 克隆仓库至本地 git clone 右键paste&#xff08;github仓库地址&#xff09; cd 仓库路径&#xff08;进入到仓库内部准备提交文件等操作&#xff09; 2. 查看main分支 git branch&#xff08;列出本地仓库中的所有分支&#xff09; 3. 创建新分支&#xff08;可省…

Flink概述

1.什么是Flink 是一个框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行有状态计算。 官网&#xff1a;Flink 2.Flink的发展历史 Flink起源于一个叫作Stratosphere的项目&#xff0c;它是由3所地处柏林的大学和欧洲其他一些大学在2010~2014年共同进行的研究项目&a…

Yolov8模型用torch_pruning剪枝

目录 &#x1f680;&#x1f680;&#x1f680;订阅专栏&#xff0c;更新及时查看不迷路&#x1f680;&#x1f680;&#x1f680; 原理 遍历所有分组 高级剪枝器 &#x1f680;&#x1f680;&#x1f680;订阅专栏&#xff0c;更新及时查看不迷路&#x1f680;&#x1f680…

【重新定义matlab强大系列十七】Matlab深入浅出长短期记忆神经网络LSTM

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

NPP VIIRS卫星数据介绍及获取

VIIRS&#xff08;Visible infrared Imaging Radiometer&#xff09;可见光红外成像辐射仪。扫描式成像辐射仪&#xff0c;可收集陆地、大气、冰层和海洋在可见光和红外波段的辐射图像。它是高分辨率辐射仪AVHRR和地球观测系列中分辨率成像光谱仪MODIS系列的拓展和改进。VIIRS数…