1. 程式人生 > >STM32F103ZET6 之 通用定時器單脈衝模式實驗

STM32F103ZET6 之 通用定時器單脈衝模式實驗

由於前面買的核心板,供電老有問題,使得我現在的專案又改用了以前用的F103ZET6微控制器!

1、實驗目的

1)產生脈寬任意可調的單脈衝(在允許的範圍內)

2、硬體:通用定時器3、通用定時器4

3、單脈衝模式介紹

單脈衝模式允許計數器響應一個激勵,並在一個程式可控的延時之後,產生一個脈寬可程式控制的脈衝。

可以通過從模式控制器啟動計數器,在輸出比較模式或者PWM模式下產生波形。設定TIMx_CR1 暫存器中的OPM 位將選擇單脈衝模式,這樣可以讓計數器自動的產生下一個更新

事情UEV時停止。

僅當比較值與計數器的初始值不同時,才能產生一個脈衝。啟動之前(當定時器正在等待觸發),必須配置如下:

向上計數方式:CNT (計數器暫存器) < CCRx (比較暫存器)< ARR(自動裝載暫存器)

向下計數方式:CNT > CCRx。


需要在從TI2輸入腳上檢測到一個上升沿開始,延遲tDELAY 之後,在OC1上產生一個長度為tPULSE 的正脈衝。

具體的可以看參考手冊。

4、軟體設計

/**
  ******************************************************************************
  * @file    timonepulse.c 
  * @author  Cawen
  * @version V1.0
  * @date    2015-12-22
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include"timonepulse.h"

/* Private variables ---------------------------------------------------------*/
uint16_t PrescalerValue = 0;

/*
 * Function Name  : GPIO_Configuration
 * Description    : Configure the GPIOD Pins.
 * Input          : None
 * Output         : None
 * Return         : None
 * Attention		  : None
 */
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* TIM4_CH1 pin (PB.06) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* TIM4_CH2 pin (PB.07) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/*
 * Function Name  : TIM4_Configuration
 * Description    : TIM4 configuration: One Pulse mode
									 The external signal is connected to TIM4_CH2 pin (PB.07), 
									 The Rising edge is used as active edge,
									 The One Pulse signal is output on TIM4_CH1 pin (PB.06)
									 The TIM_Pulse defines the delay value 
									 The (TIM_Period -  TIM_Pulse) defines the One Pulse value.
									 TIM2CLK = SystemCoreClock, we want to get TIM2 counter clock at 24 MHz:
									 - Prescaler = (TIM2CLK / TIM2 counter clock) - 1
									 The Autoreload value is 65535 (TIM4->ARR), so the maximum frequency value 
									 to trigger the TIM4 input is 24000000/65535 = 300 Hz.

									 The TIM_Pulse defines the delay value, the delay value is fixed 
									 to 682.6 us:
									 delay =  CCR1/TIM4 counter clock = 682.6 us. 
									 The (TIM_Period - TIM_Pulse) defines the One Pulse value, 
									 the pulse value is fixed to 2.048 ms:
									 One Pulse value = (TIM_Period - TIM_Pulse) / TIM4 counter clock = 2.048 ms.
 * Input          : None
 * Output         : None
 * Return         : None
 * Attention		  : None
 */
void TIM4_Configuration(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_ICInitTypeDef  			 TIM_ICInitStructure;
	TIM_OCInitTypeDef  			 TIM_OCInitStructure;
	
	
	/* TIM4 and GPIOB clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	/* Compute the prescaler value */
  PrescalerValue = (uint16_t) (72000000 / 10000) - 1;
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 5999;
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

  /* TIM4 PWM2 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 2000;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM4, &TIM_OCInitStructure);

  /* TIM4 configuration in Input Capture Mode */

  TIM_ICStructInit(&TIM_ICInitStructure);//恢復預設值

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;//選擇輸入端IC2對映到TI2上
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿捕獲
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//對映到TI2上
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//配置輸入分頻,不分頻
  TIM_ICInitStructure.TIM_ICFilter = 0;//配置輸入濾波,不濾波

  TIM_ICInit(TIM4, &TIM_ICInitStructure);

  /* 單脈衝模式選擇 */
  TIM_SelectOnePulseMode(TIM4, TIM_OPMode_Single);//生成單一的脈衝:計數器在下一個更新事件停止

  /* 選擇 TIM 輸入觸發源 */
  TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);//TIM 經濾波定時器輸入2

  /* 選擇 TIM 從模式 */
  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Trigger);	//計數器在觸發的上升沿開始
}

/*
 * Function Name  : TIM3_PWM_Init(u16 arr,u16 psc)
 * Description    : TIM3 PWM部分初始化 
										PWM輸出初始化
										arr:自動重灌值
										psc:時鐘預分頻數
 * Input          : None
 * Output         : None
 * Return         : None
 * Attention		  : None
 */

void TIM3_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;	

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定時器3時鐘
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIO外設時鐘
	
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷

	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中斷
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先佔優先順序0級
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優先順序3級
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根據NVIC_InitStruct中指定的引數初始化外設NVIC暫存器
	
   //設定該引腳為複用輸出功能,輸出TIM3 CH2的PWM脈衝波形	GPIOA7
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //複用推輓輸出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //設定在下一個更新事件裝入活動的自動重灌載暫存器週期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //設定用來作為TIMx時鐘頻率除數的預分頻值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設定時鐘分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的引數初始化TIMx的時間基數單位
	
	//初始化TIM3 Channel2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2
	TIM_OCInitStructure.TIM_Pulse = 5000;
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根據T指定的引數初始化外設TIM3 OC2

	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的預裝載暫存器
	
	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
}

//定時器3中斷服務程式
void TIM3_IRQHandler(void)   //TIM3中斷
{
	
		if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查指定的TIM中斷髮生與否:TIM 中斷源 
		{
			TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIMx的中斷待處理位:TIM 中斷源 
		  TIM_Cmd(TIM3, DISABLE);  //失能TIM3				         
		}
}