STM32F4 TIM1 7路PWM信號輸出

【實驗目的】

輸出7路佔空比不同的PWM信號是各個版本ST庫必備的例子。本實驗的主要目的不是表現ST芯片PWM功能的強大,而是要完成輸出的精確計算。

【實驗內容】

輸出7路PWM信號,並用示波器測量輸出。

【實驗原理】

1、時基單元初始化

TIM1和TIM8使用內部時鐘時,時鐘由APB2提供。但是定時器的時鐘並不是直接由APB2提供,而是來自於輸入爲APB2的一個倍頻器。當APB2的與分頻係數爲1時,這個倍頻器不起作用,定時器時鐘頻率等於APB2時鐘。當APB2預分頻係數爲其他時這個倍頻器起作用。定時器的輸入頻率等於APB2的2倍。本實驗中,APB2時鐘被設置成了84M是對系統時鐘進行2分頻。因此定時器的輸入時鐘是84M×2 = 168M = SYSCLK。(PS:這個倍頻我在ST的手冊上邊沒有找到,是網上搜索得到的結果,與實際結果對比是正確的)

TIM_Prescaler 爲預分頻值,爲0時分頻係數爲1.

TIM_Period 爲每個週期計數值,從0開始計數所以其值應爲計數次數減去1。

TIM_RepetitionCounter是F4新增的一個東西,只有高級定時器TIM1和TIM8有效,對應寄存器RCR。意思就是每TIM_RepetitionCounter+1個技術週期產生一次中斷。

我定義的時基如下,將產生頻率爲20K的即使基準:

TimerPeriod = (SystemCoreClock / 20000 ) - 1;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
//時基初始化
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //死區控制用。
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //計數器方向
TIM_TimeBaseInitStructure.TIM_Prescaler = 0;   //Timer clock = sysclock /(TIM_Prescaler+1) = 168M
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInitStructure.TIM_Period = TimerPeriod - 1;    //Period = (TIM counter clock / TIM output clock) - 1 = 20K
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);

2、計時輸出

ccr1、2、3、4爲各個技術週期的TIM_Pulse。即每當計數到這些個值的時候,PWM波形就會反轉。

ccr1 = TimerPeriod / 2;  //佔空比1/2 = 50%
ccr2 = TimerPeriod / 3;  //佔空比1/3 = 33%
ccr3 = TimerPeriod / 4;  //佔空比1/4 = 25%
ccr4 = TimerPeriod / 5;  //佔空比1/5 = 20%

定義輸出部分:

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = ccr1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;//輸出同相,TIM_OCNPolarity_High時輸出反相
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

TIM_OC1Init(TIM1,&TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = ccr2;
TIM_OC2Init(TIM1,&TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = ccr3;
TIM_OC3Init(TIM1,&TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = ccr4;
TIM_OC4Init(TIM1,&TIM_OCInitStructure);

TIM_Cmd(TIM1,ENABLE);
TIM_CtrlPWMOutputs(TIM1,ENABLE);

3、到這裏就完成了定時器的配置,下邊是GPIO引腳的配置

使用GPIOE的8、9、10、11、12、13、14引腳進行PWM輸出。配置如下:

void TIM1_GPIO_Config(void)
{
  //PE 8 9 10 11 12 13 14輸出
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11
                                | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOE,&GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1);
}

輸出波形圖:

同相輸出時候:

OC1/OC1N

IMAG2200

OC2/OC2N

IMAG2201

OC3/OC3/N

IMAG2202

OC4

IMAG2203

反相輸出

OC1/OC1N

IMAG2204

OC2/OC2N

IMAG2205

OC3/OC3/N

IMAG2206

OC4

IMAG2207

完整的應用代碼:

使用時只主要兩行即可

//主函數調用

   TIM1_GPIO_Config();
   Tim1_Config();

//定時器輸出引腳初始化

void TIM1_GPIO_Config(void)
{
  //PE 8 9 10 11 12 13 14輸出
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11
                                | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOE,&GPIO_InitStructure);
  
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1);
    
}

//TIM1做PWM輸出
void Tim1_Config(void)
{
  TimerPeriod =  (SystemCoreClock / 20000 ) - 1;
  ccr1 = TimerPeriod / 2;  //佔空比1/2 = 50%
  ccr2 = TimerPeriod / 3;  //佔空比1/3 = 33%
  ccr3 = TimerPeriod / 4;  //佔空比1/4 = 25%
  ccr4 = TimerPeriod / 5;  //佔空比1/5 = 20%
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
  //時基初始化
  TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //死區控制用。
  TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //計數器方向
  TIM_TimeBaseInitStructure.TIM_Prescaler = 0;   //Timer clock = sysclock /(TIM_Prescaler+1) = 168M
  TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInitStructure.TIM_Period = TimerPeriod - 1;    //Period = (TIM counter clock / TIM output clock) - 1 = 20K
  TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);

  
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_Pulse = ccr1;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  
  TIM_OC1Init(TIM1,&TIM_OCInitStructure);

  TIM_OCInitStructure.TIM_Pulse = ccr2;
  TIM_OC2Init(TIM1,&TIM_OCInitStructure);
  
  TIM_OCInitStructure.TIM_Pulse = ccr3;
  TIM_OC3Init(TIM1,&TIM_OCInitStructure);
  
  TIM_OCInitStructure.TIM_Pulse = ccr4;
  TIM_OC4Init(TIM1,&TIM_OCInitStructure);
  
  TIM_Cmd(TIM1,ENABLE);
  TIM_CtrlPWMOutputs(TIM1,ENABLE);
}

原文地址:http://www.cnblogs.com/zyqgold/archive/2013/05/26/3100377.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章