STM32 高級定時器 輸出PWM (用DHT11測得的溫度去調節RGB燈的亮度)

開發平臺

  • 野火STM32F429開發板
  • 使用標準庫開發

高級定時器

  • 高級定時器其實就是基本定時器加上輸入捕獲、輸出比較和斷路死區,所以有四個初始化函數:
  • 定時器時基初始化函數
    TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
  • 輸出比較初始化函數
    TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
  • 輸入捕獲初始化函數
    TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
  • 死區初始化函數
    TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);

編程思路

  1. 初始化RGB燈的引腳
  2. 驅動DHT11(上一篇)
  3. 定時器時基初始
  4. 定時器輸出比較初始化
  • 配置基本定時器:

      		 void BASE_Tim_Config (void)
      		{
      			TIM5_CLK_ENABLE();
      
     			TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
      			TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
      			TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
      			TIM_TimeBaseInitStruct.TIM_Period=100-1;(定時器週期,實際上就是ARR重裝載值)
      			TIM_TimeBaseInitStruct.TIM_Prescaler=90-1;
         		TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
      			TIM_TimeBaseInit(TIMX,&TIM_TimeBaseInitStruct);
      
     			TIM_Cmd(TIMX,ENABLE);
      		 }
    

(1) 基本定時器只有向上計數
(2) 配置ARR的值
(3) 配置分頻係數
(4) 基本定時器沒有重複計數器
(5)使能定時器

  • 配置高級定時器的輸出比較:

      	 void TIM_OC_Config(void)
      	{
     		    TIM_OCInitTypeDef TIM_OCInitStruct;
      			TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
      			TIM_OCInitStruct.TIM_Pulse=0;
      			TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
      			TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_Low;
    
      			TIM_OC3Init(TIMX,&TIM_OCInitStruct);
      			TIM_CtrlPWMOutputs(TIMX,ENABLE);
      			TIM_ARRPreloadConfig(TIMX,ENABLE);
      
      			TIM_Cmd(TIMX,ENABLE);
    

    }

(1) 選擇PWM模式
(2) 脈寬初始化爲0,是決定佔空比
(3) 設置極性決定定時器通道有效電平
(4) 比較輸出使能
(5) 主動輸出使能
(6) 使能ARR重裝載
(7)使能定時器

補充:

初始化輸出比較函數有四個,每個定時器的通道不一樣,所要選擇的初始化函數也不一樣,要查看手冊(這裏用的是TIM5,通道爲CH3)
定時器週期:T=(ARR+1)*(PSC+1)/TCK
佔空比:脈寬/ARR重裝載的值

代碼如下:

PWM.h

#ifndef __PWM__H
#define __PWM__H

#include "stm32f4xx.h"
#include "DHT11.h"

#define GPIOH_CLK_ENABLE()      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE)
#define TIM5_CLK_ENABLE()       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE)


#define LED_R_PIN               GPIO_Pin_10
#define LED_G_PIN               GPIO_Pin_11
#define LED_B_PIN               GPIO_Pin_12
#define LED_R_S_PIN             GPIO_PinSource10
#define LED_G_S_PIN             GPIO_PinSource11
#define LED_B_S_PIN             GPIO_PinSource12
#define LED_R_PORT              GPIOH
#define LED_G_PORT              GPIOH
#define LED_B_PORT              GPIOH
#define TIMX                    TIM5



void GPIO_Config(void);
void BASE_Tim_Config (void);
void TIM_OC_Config(void);
void TIMx_Config(void);


#endif 

PWM.c

#include "PWM.h"

void GPIO_Config(void)
{
    GPIOH_CLK_ENABLE();
    
    //GPIO_PinAFConfig(LED_R_PORT,LED_R_S_PIN,GPIO_AF_TIM5);    GPIO_PinAFConfig(LED_G_PORT,LED_G_PIN,GPIO_AF_TIM5);
    GPIO_PinAFConfig(LED_B_PORT,LED_B_S_PIN,GPIO_AF_TIM5);


    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
    
    //GPIO_InitStruct.GPIO_Pin=LED_R_PIN;
    //GPIO_Init(LED_R_PORT,&GPIO_InitStruct);
    
    //GPIO_InitStruct.GPIO_Pin=LED_G_PIN;
    //GPIO_Init(LED_G_PORT,&GPIO_InitStruct);
    
    GPIO_InitStruct.GPIO_Pin=LED_B_PIN;
    GPIO_Init(LED_B_PORT,&GPIO_InitStruct);
    
}

void BASE_Tim_Config (void)
{
    TIM5_CLK_ENABLE();
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInitStruct.TIM_Period=100-1;
    TIM_TimeBaseInitStruct.TIM_Prescaler=90-1;
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIMX,&TIM_TimeBaseInitStruct);
    
    TIM_Cmd(TIMX,ENABLE);
}

void TIM_OC_Config(void)
{
    TIM_OCInitTypeDef TIM_OCInitStruct;
    TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_Pulse=0;
    TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_Low;
  
    TIM_OC3Init(TIMX,&TIM_OCInitStruct);
    //TIM_OC3PreloadConfig(TIMX,TIM_OCPreload_Enable);
    TIM_CtrlPWMOutputs(TIMX,ENABLE);
    TIM_ARRPreloadConfig(TIMX,ENABLE);
    
    TIM_Cmd(TIMX,ENABLE);
}

void TIMx_Config(void)
{
    BASE_Tim_Config ();
    TIM_OC_Config();
    
}   

main.c

#include "stm32f4xx.h"
#include "DHT11.h"
#include "USART.h"
#include "stdio.h"
#include "systick.h"
#include "PWM.h"


int main(void)
{
    GPIO_Config();
    USART_config();
    Systick_Init ();
    TIMx_Config();
    printf("溫度傳感器控制led亮滅\n");
    while(1)    
    {
        TIM_SetCompare3(TIMX,(DHT11_Data()-25)*6);
        DELAY_us(1500000);
    }
     
 
}
發佈了17 篇原創文章 · 獲贊 20 · 訪問量 5210
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章