時間のSTM32ノート(タイマー)

EDITORIAL:
個人的な要約であるとして間違っては、私を修正してください場合は、この記事の目的は、将来の問い合わせを容易にするため、バックアップを要約する;加えて、インターネット、書籍、各種マニュアルの内容のほとんどは、侵害を通知し、すぐに削除投稿を喜ばなければなりません謝罪します。

 

ディレクトリ

タイマーブリーフ

第二に、高度な制御タイマ(TIM1&TIM8)

第三に、汎用タイマ(TIM2 - TIM5)

第四に、基本的なタイマー(TIM6&TIM7)

第五に、コードの実装


 

タイマーブリーフ

        STM32F103xxは、大容量含む2つの高度な制御タイマーの最大、4つの一般的なタイマーと二つの基本的なタイマー、ウォッチドッグタイマと2とシステムタイマー刻み、現在のターゲットに製品を強化しましたチップ(STM32F103VET6)は、大容量のシリーズであるので、タイプは、上記タイマを含みます

グラフによると、我々は分裂することができます

タイマー名 機能クラス
TIM1 高度な制御タイマ
TIM8
TIM2 汎用タイマ
TIM3
TIM4
TIM5
TIM6 基本的なタイマー
TIM7

 

第二に、高度な制御タイマ(TIM1&TIM8)

 

第三に、汎用タイマ(TIM2 - TIM5)

 

第四に、基本的なタイマー(TIM6&TIM7)

 

第五に、コードの実装

        このルーチンでは、一定のタイミングTIM2を使用する精密なタイミング操作を必要とするいくつかの物事に対処するために使用するスキャンタイマーを行い、いくつかの理由は、単にA(クロックを刻み)のSysTickを使用するのですが、また、再オープンしていない、尋ねることができますタイマー実行するタイミング基準時間を、私は読んでの事前のSysTick(刻む時計が)、CM3を提供されているハードウェア、知っている  (タイマーティック)のSysTickのSTM32ノートはまたのSysTick最高のRTOS機能はクロック・ティックを作ることであると述べましたまた、それは本当に十分ではありませんしない限り、非常に多くのタイマーは、使用しないので、不要に使用する革のタイミング事が可能です

bsp_time.cのソースファイル

#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のヘッダファイル

#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万+

おすすめ

転載: blog.csdn.net/qq_42992084/article/details/104099659