STM32 notes of Time (timer)

EDITORIAL:
This article aims to summarize the backup, to facilitate future inquiries, as is the personal summary, if wrong, please correct me; in addition, most of the content from the Internet, books, and various manuals, should please inform the infringement, immediately delete posts to apologize.

 

table of Contents

A timer brief

Second, the advanced control timer (TIM1 & TIM8)

Third, the general-purpose timer (TIM2 - TIM5)

Fourth, the basic timer (TIM6 & TIM7)

Fifth, code implementation


 

A timer brief

        STM32F103xx enhanced products in the large-capacity contain a maximum of two advanced control timers, four general timer and two basic timer, watchdog timer and two and a system timer tick, the current target chip (STM32F103VET6) is a large-capacity series, so the type described above includes a timer

According to the graph we can divide the

Timer name Functional class
TIM1 Advanced control timer
TIM8
TIM2 General Purpose Timer
TIM3
TIM4
TIM5
TIM6 Basic Timer
TIM7

 

Second, the advanced control timer (TIM1 & TIM8)

 

Third, the general-purpose timer (TIM2 - TIM5)

 

Fourth, the basic timer (TIM6 & TIM7)

 

Fifth, code implementation

        In this routine, use a fixed timing TIM2 do a scan timer, used to deal with some things that require precision timing operations; Some may ask, why not just use Systick (ticking clock) do, but also re-opened a timer timing reference time to do; you know Systick (ticking clock) is the hardware, which is provided CM3, before the thing I read  STM32 notes of Systick (tick timer) also said Systick best RTOS function is to make the clock tick Moreover, there are so many timers can be used, so no need to use leather timing thing, unless it is really not enough

bsp_time.c source file

#include "bsp_time.h"
#include "bsp_gpio.h"
#include "bsp_uart.h"


Time_TypeDef Time2;

/************************************************
函数名称 : Timer2_Config
功    能 : Timer2配置
参    数 : 无
返 回 值 : 无
*************************************************/
void Timer2_Config(void)
{
	uint16_t PrescalerValue = 0;
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

	/* Compute the prescaler value */
	PrescalerValue = (uint16_t)(SystemCoreClock / 1000000) - 1;		// us
	
	/* TIM2 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	/* Enable the TIM2 global Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	/* Time base configuration */
	TIM_TimeBaseStructure.TIM_Period = 1000 - 1;                    // 自动重装载寄存器的值
	TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;           // 时钟预分频数
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;         // 时钟分频因子
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     // 计数器计数模式
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;                // 重复计数器的值
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	
	/* Clear TIM2 update flag */
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);

	/* TIM2 IT enable */
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	/* Time2 counter enable */
	TIM_Cmd(TIM2, ENABLE);
}

/************************************************************************/
/*            STM32F10x Time Interrupt Handlers                         */
/************************************************************************/

/**
  * @brief  This function handles TIM2 global interrupt request.
  * @param  None
  * @retval None
  */
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) 
	{
		TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
		
		Time2.Time_ms++;                       // 毫秒计数
		if(1000 == Time2.Time_ms)
		{
			Time2.Time_ms = 0;                 // 秒计数
			Time2.Time_s++;
			if(Time2.Time_s > 60)
			{
				Time2.Time_s = 0;
			}
			GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, (BitAction)(1 - GPIO_ReadOutputDataBit(LED_GPIO_PORT, LED_GPIO_PIN)));  // LED每隔一秒闪烁
		}
		else if(0 == Time2.Time_ms % 50)       // 每隔 50ms检查
		{
			if(Usart1.Receiving_Time)
			{
				Usart1.Receiving_Time--;
				if(!Usart1.Receiving_Time)     // 接收超时
					Usart1.Frame_flag = 1;     // 串口一帧接收完成
			}
		}
	}		 	
}


/*---------------------------- END OF FILE ----------------------------*/


 

bsp_time.h header file

#ifndef __BSP_TIME_H
#define __BSP_TIME_H


#include "stm32f10x.h"

typedef struct
{
	uint16_t Time_ms;
	uint16_t Time_s;
}Time_TypeDef;
extern Time_TypeDef Time2;

void Timer2_Config(void);


#endif	/* __BSP_TIME_H */


/*---------------------------- END OF FILE ----------------------------*/

 

在 STM32库中,并没有提供像 C51那样 I/O位取反操作,所以想要利用库进行 I/O位取反,就只能像上面的 GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, (BitAction)(1 - GPIO_ReadOutputDataBit(LED_GPIO_PORT, LED_GPIO_PIN))) 操作,先把当前的 IO电平读出来再置反写入,当然,这样做会消耗点时间,毕竟只是为了实现一个功能就调用两个库函数;这里我们可以自己利用寄存器封装一个函数,毕竟 ST他不做,那我们就自己造,原理很简单,就像 C51那样,把对应的位取反就好了,先来看下与输出相关联的 IO寄存器先

所以我们就可以封装成下面的样子

/**
  * @brief  Reverse the selected data port bits.
  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
  * @param  GPIO_Pin: specifies the port bits to be written.
  *   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
  * @retval None
  */
void GPIO_PinReverse(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  
  GPIOx->ODR ^= GPIO_Pin;
}

 

发布了40 篇原创文章 · 获赞 14 · 访问量 1万+

Guess you like

Origin blog.csdn.net/qq_42992084/article/details/104099659