1. 程式人生 > >高階定時器—PWM互補輸出

高階定時器—PWM互補輸出

一、程式設計要點

1、初始化TMI相關GPIO

2、初始化時基結構體

3、初始化比較輸出結構體

4、初始化死區剎車結構體

5、編寫呼吸燈函式

二、結構體&庫函式

1、時基結構體 

typedef struct
{
  uint16_t TIM_Prescaler;         /*!<  預分頻器 配置TIMxPSC 暫存器    */
 
  uint16_t TIM_CounterMode;       /*!<  計數器模式 向上/向下    */
 
  uint16_t TIM_Period;            /*!<  定時週期  配置 ARR  (自動重灌載暫存器)   */ 
 
  uint16_t TIM_ClockDivision;     /*!<  時鐘分頻,設定定時器時鐘 CK_INT 頻率與數字濾波器取樣時鐘
                                        頻率分頻比,  */
 
  //uint8_t TIM_RepetitionCounter;  /*!<  重複計數器 高階定時器專屬 用於產生多少個PWM波    */
} TIM_TimeBaseInitTypeDef;

2、比較輸出結構體

typedef struct
{
  uint16_t TIM_OCMode;        /*!< 比較輸出模式 常用PWM1 PWM2 */

  uint16_t TIM_OutputState;   /*!< 比較輸出使能 */

  uint16_t TIM_OutputNState;  /*!< 互補比較輸出使能 */

  uint16_t TIM_Pulse;         /*!< 設定佔空比 CRR的值 0-65535 */

  uint16_t TIM_OCPolarity;    /*!< 比較輸出極性 */

  uint16_t TIM_OCNPolarity;   /*!< 互補比較輸出極性*/

  uint16_t TIM_OCIdleState;   /*!< 空閒狀態輸出狀態(高、低電平) */

  uint16_t TIM_OCNIdleState;  /*!< 互補空閒狀態輸出狀態(高、低電平)*/

} TIM_OCInitTypeDef;

3、初始化死區剎車結構體

typedef struct
{

  uint16_t TIM_OSSRState;        /*!< 執行模式下的關閉狀態選擇 */

  uint16_t TIM_OSSIState;        /*!< 空閒模式下的關閉狀態選擇 */

  uint16_t TIM_LOCKLevel;        /*!< 鎖定級別配置 */ 

  uint16_t TIM_DeadTime;         /*!<  死區時間 0-255  */

  uint16_t TIM_Break;            /*!< 斷路功能選擇  */

  uint16_t TIM_BreakPolarity;    /*!< 斷路輸出極性 */

  uint16_t TIM_AutomaticOutput;  /*!< 自動輸出使能 */
} TIM_BDTRInitTypeDef;

三、TIM相關計算

1、PWM波頻率計算

F = TIM_CLK/{(ARR+1)*(PSC+1)}
    TIM_CLK=72M   
    ARR(自動重灌載的值)-> TIM_Period
    PCS(時鐘預分頻器) -> TIM_Prescaler
2、佔空比計算
佔空比=TIM_Pulse/TIM_Period

四、程式原始碼

1、Advanced_TIM.h 檔案

#ifndef __ADVABCED_H
#define __ADVABCED_H
#include "stm32f10x.h"

#define RCC_APBx_CLOCK    RCC_APB2PeriphClockCmd
#define RCC_APBx_PERIPH   RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB
#define RCC_APB2_TIMxRCC_APB2Periph_TIM1

#define ADVANCED_TIMxTIM1

#define TIMx_PSC          (9-1)
#define TIMx_ARR          (80-1)
#define TIMx_Pulse     0

#define TIM_CH1_PIN GPIO_Pin_8
#define TIM_CH1_PORT GPIOA

#define TIM_CH1N_PIN GPIO_Pin_13
#define TIM_CH1N_PORT GPIOB

#define TIM_BKIN_PIN GPIO_Pin_12
#define TIM_BKINN_PORT GPIOB
void TIM_ADVANCED_Init(void);
#endif//__ADVABCED_H
2、Advanced_TIM.c 檔案
#include "Advanced_TIM.h"

static void ADVANCED_TIM_GPIOConfig(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	RCC_APBx_CLOCK(RCC_APBx_PERIPH,ENABLE);

	//輸出比較通道
	GPIO_InitStructure.GPIO_Pin = TIM_CH1_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TIM_CH1_PORT,&GPIO_InitStructure);	
	
	//輸出比較互補通道
	GPIO_InitStructure.GPIO_Pin = TIM_CH1N_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TIM_CH1N_PORT,&GPIO_InitStructure);	
	
	//輸出剎車通道
	GPIO_InitStructure.GPIO_Pin = TIM_BKIN_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TIM_BKINN_PORT,&GPIO_InitStructure);	
	
}

static void ADVANCED_TIM_MODE_Config(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;		//時基結構
	TIM_OCInitTypeDef TIM_OCStructure;			//輸出比較
	TIM_BDTRInitTypeDef TIM_BDTRStructure;			//剎車 死區
	
	RCC_APBx_CLOCK(RCC_APB2_TIMx,ENABLE);
	
	//時基配置
	TIM_TimeBaseStructure.TIM_Prescaler = TIMx_PSC;
	TIM_TimeBaseStructure.TIM_Period = TIMx_ARR;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit( ADVANCED_TIMx,&TIM_TimeBaseStructure );

	//比較輸出
	TIM_OCStructure.TIM_OCMode = TIM_OCMode_PWM1;			//pwm1模式
	TIM_OCStructure.TIM_OutputState = TIM_OutputState_Enable;        //輸出使能
	TIM_OCStructure.TIM_OutputNState = TIM_OutputNState_Enable;	//互補輸出使能
	TIM_OCStructure.TIM_Pulse = TIMx_Pulse;				//佔空比
	TIM_OCStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//比較輸出極性
	TIM_OCStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;		//互補比較輸出極性
	TIM_OCStructure.TIM_OCIdleState = TIM_OCIdleState_Set;		//空閒輸出電平
	TIM_OCStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;	//空閒互補輸出電平
	
	TIM_OC1Init(ADVANCED_TIMx , &TIM_OCStructure );
	TIM_OC1PreloadConfig(ADVANCED_TIMx, TIM_OCPreload_Enable);

	//剎車死區
	TIM_BDTRStructure.TIM_OSSIState = TIM_OSSIState_Enable;
	TIM_BDTRStructure.TIM_OSSRState = TIM_OSSRState_Enable;
	TIM_BDTRStructure.TIM_Break = TIM_Break_Enable;
	TIM_BDTRStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
	TIM_BDTRStructure.TIM_DeadTime = 11 ;
	TIM_BDTRStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;	
	TIM_BDTRStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
	TIM_BDTRConfig( ADVANCED_TIMx , &TIM_BDTRStructure );
		
	TIM_Cmd(ADVANCED_TIMx, ENABLE );
	
	TIM_CtrlPWMOutputs( ADVANCED_TIMx, ENABLE );	
}

void TIM_ADVANCED_Init(void)
{
	ADVANCED_TIM_GPIOConfig();
	ADVANCED_TIM_MODE_Config();
}
3、main.c檔案
#include "stm32f10x.h"  
#include "bsp_led.h"
#include "usart.h"
#include "Advanced_TIM.h"

int main(void)
{	
	uint32_t i;
	u8 STD=0,crr=0;
	
	USART_config();
	
	printf("串列埠測試\n");	
	TIM_ADVANCED_Init();
	
	TIM1->CCR1 = crr;
while(1)
  {                      
			
        TIM1->CCR1 = crr;

      if(STD==0)
        {
	    for(i=0x8ffff;i>0;i--);
	    crr++;
	    if(crr>=80)STD=1;
	}
	else
	{
	    for(i=0x8ffff;i>0;i--);
	    crr--;
	    if(crr<=0)STD=0;						
	}		
  }
}