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.mzph.cn/news/733809.shtml

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

相关文章

Day33-计算机基础3

Day33-计算机基础3 1.根据TCP/IP进行Linux内核参数优化1.1 例1:调整访问服务端的【客户端】的动态端口范围 ,LVS(10-50万并发),NGINX负载,SQUID缓存服务,1.2 企业案例:DOS攻击的案例&#xff1a…

[备赛笔记]——5G大唐杯(5G考试等级考考试基础试题)

个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…

redis缓存满了的话会发生什么?

线上问题 未及时加监控,导致线上redis被逐出,业务有损 示例: 一个key临时存储在redis等缓存中,如果该key在一段时间内有很大作用 比如一次业务请求,上游服务写入一个value,时长1小时,下游服务…

Matlab|考虑源荷两侧不确定性的含风电电力系统低碳调度

目录 1 主要内容 目标函数: 约束条件: 程序亮点总结: 2 代码问题与程序测试 设备出力运行结果: 3 下载链接 1 主要内容 本程序是对《考虑源荷两侧不确定性的含风电电力系统低碳调度》的方法复现,主要实现了基…

【QT+QGIS跨平台编译】之七十六:【QGIS_Native+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、QGIS_Native介绍二、QGIS下载三、文件分析四、pro文件五、编译实践一、QGIS_Native介绍 QGIS_Native模块是QGIS软件的核心部分,提供了许多基本功能和核心组件,主要用于处理与底层操作系统的关系。 二、QGIS下载 QGIS网址: QGIS Source Download 三、文件分析…

Django学习笔记

Django学习笔记 一、Django整体流程跑通 1.1安装 pip install django //安装 import django //在python环境中导入django django.get_version() //获取版本号,如果能获取到,说明安装成功Django目录结构 Python310-Scripts\django-admi…

前端框架的发展历程

文章目录 前言 一、静态页面时代 二、JavaScript的兴起 三、jQuery的出现 四、前端框架的崛起 1.AngularJS 2.React 3.Vue.js 五、面向组件化的发展趋势 总结 前言 前端框架的发展史就是一个不断进化的过程,它的发展和进化一定程度…

力扣刷题Days14第二题--80删除数组中重复元素||(js)

目录 1,题目-中等 2,代码 双指针 3,学习与总结 思路学习与整理 1,题目-中等 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组…

区块链和人工智能的关系以及经典案例

目录 1.区块链与人工智能的关系 2.应用案例:基于区块链的医疗数据共享平台 2.1背景 2.2方案 2.3优势 2.4挑战 区块链技术和人工智能(AI)是两种不同的技术,但它们之间存在着互补关系。区块链技术提供了一种安全、透明、去中心…

Android Studio下载gradle超时问题解决

方法一 1. 配置根目录的setting.gradle.kts文件 pluginManagement {repositories {maven { urluri ("https://www.jitpack.io")}maven { urluri ("https://maven.aliyun.com/repository/releases")}maven { urluri ("https://maven.aliyun.com/repos…

Open-Sora:开源 Sora 复现方案,成本降低 46%

Colossal-AI 开源了完整的 Sora 复现架构方案 Open-Sora,声称可降低 46% 复现成本,并将模型训练输入序列长度扩充至 819K patches。 演示站点: https://ai.uaai.cn UAAI 官方论坛: www.jingyuai.com京娱AI Sora 算法复现方案 在 …

springboot256基于springboot+vue的游戏交易系统

游戏交易系统设计与实现 摘 要 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对游戏交…

[LeetCode][LCR143]树的子结构判断——递归

题目 LCR 143. 子结构判断 给定两棵二叉树 tree1 和 tree2,判断 tree2 是否以 tree1 的某个节点为根的子树具有相同的结构和节点值。注意,空树不会是以 tree1 的某个节点为根的子树具有相同的结构和节点值。 示例: 输入:tree1 …

3.9Code

基于顺序存储结构的图书信息表的图书去重 #include<iostream> #include<stdlib.h> #include<string.h>typedef int status;#define OK 1using namespace std;typedef struct{char no[50];char name[50];float price; }Book;typedef struct{Book* elem;int …

鸿蒙App动画、弹窗

动画 属性动画 https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-animatorproperty-0000001478181445-V3 组件的某些通用属性变化时&#xff0c;可以通过属性动画实现渐变过渡效果&#xff0c;提升用户体验。支持的属性包括width、height、backg…

【软件工程】软件工程定义、软件危机以及软件生命周期

&#x1f338;博主主页&#xff1a;釉色清风&#x1f338;文章专栏&#xff1a;软件工程&#x1f338; 今日语录&#xff1a;What matters isn’t how others think of your ambitions but how fervently you cling to them. 软件工程系列&#xff0c;主要根据老师上课所讲提及…

【ubuntu】安装 Anaconda3

目录 一、Anaconda 说明 二、操作记录 2.1 下载安装包 2.1.1 官网下载 2.1.2 镜像下载 2.2 安装 2.2.1 安装必要的依赖包 2.2.2 正式安装 2.2.3 检测是否安装成功 方法一 方法二 方法三 2.3 其他 三、参考资料 3.1 安装资料 3.2 验证是否成功的资料 四、其他 …

基于机器学习的工业用电量预测完整代码数据

视频讲解: 毕业设计:算法+系统基于机器学习的工业用电量预测完整代码数据_哔哩哔哩_bilibili 界面展示: 结果分析与展示: 代码: from sklearn import preprocessing import random from sklearn.model_selection import train_test_split from sklearn.preprocessing…

vue element plus Typography 排版

我们对字体进行统一规范&#xff0c;力求在各个操作系统下都有最佳展示效果。 字体# 字号# LevelFont SizeDemoSupplementary text12px Extra SmallBuild with ElementBody (small)13px SmallBuild with ElementBody14px BaseBuild with ElementSmall Title16px MediumBuild w…

个人健康管理系统|基于微信小程序的个人健康管理系统设计与实现(源码+数据库+文档)

个人健康管理小程序目录 目录 基于微信小程序的个人健康管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、用户信息管理 2 运动教程管理 3、公告信息管理 4、论坛信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设…