天天看點

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

一、PWM簡介

脈沖寬度調制(PWM),是英文“Pulse Width Modulation”的縮寫,簡稱脈寬調試。 是利用微處理器的數字輸出來對模拟電路進行控制的一種非常有效的技術。廣泛應用在從測量、通信到功率控制與變換的許多領域中。
STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項
例如上圖中,圖b)是微處理輸出的數字信号,實際上他接到電機等功率裝置上時,效果相當于圖a)。這就是PWM調制。例如輸出占空比為50%,頻率為10Hz的脈沖,高電平為3.3V.則其輸出的模拟效果相當于輸出一個1.65V的高電平。脈沖調制有兩個重要的參數,第一個就是輸出頻率,頻率越高,則模拟的效果越好。第二個就是占空比。占空比就是改變輸出模拟效果的電壓大小。占空比越大則模拟出的電壓越大。

二、定時器簡介

STM32F1 系列中,除了互聯型的産品,共有

8

個定時器,分為基本定時器,通用定時器和進階定時器。

基本定時器

TIM6

TIM7

是一個 16 位的隻能向上計數的定時器,隻能定時,沒有外部 IO。

通用定時器

TIM2/3/4/5

是一個 16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,每個定時器有四個外部 IO。

進階定時器

TIM1/8

是一個 16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,還可以有三相電機互補輸出信号,每個定時器有 8 個外部 IO。

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

STM32 的定時器除了

TIM6

TIM7

(基本定時器)。其他的定時器都可以用來産生 PWM 輸出。其中進階定時器

TIM1

TIM8

可以同時産生多達

7

路的 PWM 輸出。而通用定時器

TIM2/3/4/5

也能同時産生多達

4

路的 PWM 輸出。這樣,STM32 最多可以同時産生 30 路 PWM 輸出。

每個定時器有四個通道,每一個通道都有一個捕獲比較寄存器,将寄存器值和計數器值比較,通過比較結果輸出高低電平,便可以實作脈沖寬度調制模式(PWM信号)。

三、建立工程

1. 打開 STM32CubeMX 軟體,點選“建立工程”

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

2. 選擇 MCU 和封裝

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

3. 配置時鐘

RCC 設定,選擇 HSE(外部高速時鐘) 為 Crystal/Ceramic Resonator(晶振/陶瓷諧振器)

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

選擇 Clock Configuration,配置系統時鐘 SYSCLK 為 72MHz

修改 HCLK 的值為 72 後,輸入回車,軟體會自動修改所有配置

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

4. 配置調試模式

非常重要的一步,否則會造成第一次燒錄程式後續無法識别調試器

SYS 設定,選擇 Debug 為 Serial Wire

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

四、TIM3通用定時器

4.1 選擇定時器

由于 LED 燈所在引腳為

PB1

,在右邊圖中找到 LED 燈對應引腳,選擇

TIM3_CH4

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

4.2 參數配置

Timers

中選擇

TIM3

設定,指定時鐘源為

Internal Clock

内部時鐘,通道4選擇

PWM Generation CH4

PWM輸出。

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

Parameter Settings

進行具體參數配置。

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項
  • Counter setting
  • Prescaler(時鐘預分頻數):1024-1
  • Counter Mode(計數模式):Up(向上計數模式)
  • Counter Period(自動重裝載值):200-1
  • Internal Clock Division(CKD)(時鐘分頻因子):No Division(不分頻)
  • auto-reload preload(自動重裝載):Enable(使能)
  • TRGO Output (TRGO) Parameters

    TRGO:在定時器的定時時間到達的時候輸出一個信号(如:定時器更新産生TRGO信号來觸發ADC的同步轉換)

  • Master/Slave Mode(MSM bit):不使能
  • Trigger Event Selection:Reset(UG bit from TIMx_EGR)
  • PWM Generation Channel 4
  • Mode(定時模式):PWM mode 1

    設定定時器計數器與比較值相等時輸出引腳的狀态

  • Pulse(計數比較值):0

    這裡建議設定為0,在中斷中改變比較寄存器的值

  • Output compare preload(輸出比較預加載):Enable(使能)

    作用和 auto-reload preload 類似

  • Fast Mode(脈沖快速模式):Disable(不使能)

    與我們配置無關不使能

  • CH Polarity(輸出極性):Low

    當定時器計數值小于 CCR1_Val 時,輸出低電平

4.2 配置GPIO

GPIO Settings

配置速度為高速。

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

4.3 配置NVIC

使能定時器中斷

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

4.4 生成代碼

輸入項目名和項目路徑

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

選擇應用的 IDE 開發環境 MDK-ARM V5

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

每個外設生成獨立的

’.c/.h’

檔案

不勾:所有初始化代碼都生成在 main.c

勾選:初始化代碼生成在對應的外設檔案。 如 GPIO 初始化代碼生成在 gpio.c 中。

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

點選 GENERATE CODE 生成代碼

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

4.5 添加全局變量

main.c

頭部添加 PWM 表

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim3;

/* USER CODE BEGIN PV */
uint16_t indexWave[] = {
1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4,
4, 5, 5, 6, 7, 8, 9, 10, 11, 13,
15, 17, 19, 22, 25, 28, 32, 36,
41, 47, 53, 61, 69, 79, 89, 102,
116, 131, 149, 170, 193, 219, 250,
284, 323, 367, 417, 474, 539, 613,
697, 792, 901, 1024, 1024, 901, 792,
697, 613, 539, 474, 417, 367, 323,
284, 250, 219, 193, 170, 149, 131, 
116, 102, 89, 79, 69, 61, 53, 47, 41,
36, 32, 28, 25, 22, 19, 17, 15, 13, 
11, 10, 9, 8, 7, 6, 5, 5, 4, 4, 3, 3,
2, 2, 2, 2, 1, 1, 1, 1	
};

uint16_t POINT_NUM = sizeof(indexWave)/sizeof(indexWave[0]); 
/* USER CODE END PV */
           

并在

stm32f1xx_it.c

中聲明

/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim3;

/* USER CODE BEGIN EV */
extern  uint16_t indexWave[];
extern uint16_t  POINT_NUM;    /*PWM表中的點數*/
/* USER CODE END EV */
           

4.6 修改中斷回調函數

打開

stm32f1xx_it.c

中斷服務函數檔案,找到 TIM3 中斷的服務函數

TIM3_IRQHandler()

中斷服務函數裡面就調用了定時器中斷處理函數

HAL_TIM_IRQHandler()

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

打開

stm32f1xx_hal_tim.c

檔案,找到定時器中斷處理函數原型

HAL_TIM_IRQHandler()

,其主要作用就是判斷是哪個定時器産生哪種事件中斷,清除中斷辨別位,然後調用中斷回調函數

HAL_TIM_PeriodElapsedCallback()

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項
這個函數不應該被改變,如果需要使用回調函數,請重新在使用者檔案中實作該函數。

HAL_TIM_PeriodElapsedCallback()

按照官方提示我們應該再次定義該函數,

__weak

是一個弱化辨別,帶有這個的函數就是一個弱化函數,就是你可以在其他地方寫一個名稱和參數都一模一樣的函數,編譯器就會忽略這一個函數,而去執行你寫的那個函數;而

UNUSED(htim)

,這就是一個防報錯的定義,當傳進來的定時器号沒有做任何處理的時候,編譯器也不會報出警告。其實我們在開發的時候已經不需要去理會中斷服務函數了,隻需要找到這個中斷回調函數并将其重寫即可而這個回調函數還有一點非常便利的地方這裡沒有展現出來,就是當同時有多個中斷使能的時候,STM32CubeMX會自動地将幾個中斷的服務函數規整到一起并調用一個回調函數,也就是無論幾個中斷,我們隻需要重寫一個回調函并判斷傳進來的定時器号即可。

接下來我們就在

stm32f1xx_it.c

這個檔案的最下面添加

HAL_TIM_PeriodElapsedCallback()

/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  static uint8_t pwm_index = 1;        /* 用于PWM查表 */
  static uint8_t period_cnt = 0;       /* 用于計算周期數 */

  period_cnt++;
  /* 若輸出的周期數大于20,輸出下一種脈沖寬的PWM波 */
  if(period_cnt >= 20)										
  {
    /* 根據PWM表修改定時器的比較寄存器值 */
    __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_4, indexWave[pwm_index]);
    
    /* 标志PWM表的下一個元素 */
    pwm_index++;												
    /* 若PWM脈沖表已經輸出完成一遍,重置PWM查表标志 */
    if( pwm_index >=  POINT_NUM)								
    {
      pwm_index=0;								
    }
    /* 重置周期計數标志 */
    period_cnt=0;												
  }
}
/* USER CODE END 1 */
           
其中 pwm_index 比較容易了解,它用于訓示目前要使用 PWM 表中的哪個元素,進而 在“BRE_TIMx->BRE_CCRx = indexWave[pwm_index];‖語句中可以給 CCRx 賦予正确的數值,而且當 PWM 表中的資料都使用一遍時,pwm_index 将重新指向 PWM 表的開頭,開始下一次呼吸循環。在本實驗的單次呼吸循環中,每個 PWM 表元素都會使用 20 次,代碼中利用 period_cnt 變量訓示目前使用的次數,當 period_cnt> period_class 時(即period_cnt>10 時),pwm_index 才會指向下一個元素。每個 PWM 表元素使用多次,主要是為了在 TIMPeriod、PWM 表的點數、TIM_Prescaler 都固定的情況下,通過調整每個元素的重複次數可以調整整個拟合波形的周期。如把代碼中的比較值 period_class 改為 200,每個 PWM 表周遊一次的時間就變為原來配置的 10 倍,其拟合的呼吸周期也就相應地改變了。圖 40-7 說明了 period =3 和 period=1 時輸出的 PWM 波形。
STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

4.7 添加定時器啟動函數

現在進入 main 函數并在 while 循環前加入開啟定時器函數

HAL_TIM_Base_Start_IT()

和 PWM 開啟函數

HAL_TIM_PWM_Start()

,這裡所傳入的 htim3 就是剛剛定時器初始化後的結構體。

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim3);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); 
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
           

4.8 HAL庫與标準庫代碼比較

STM32CubeMX 使用 HAL 庫生成的代碼:

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 1023;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 199;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  static uint8_t pwm_index = 1;			/* 用于PWM查表 */
	static uint8_t period_cnt = 0;		/* 用于計算周期數 */

  period_cnt++;
  /* 若輸出的周期數大于20,輸出下一種脈沖寬的PWM波 */
  if(period_cnt >= 20)										
  {
    /* 根據PWM表修改定時器的比較寄存器值 */
    __HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_4,indexWave[pwm_index]);
    
    /* 标志PWM表的下一個元素 */
    pwm_index++;												
    /* 若PWM脈沖表已經輸出完成一遍,重置PWM查表标志 */
    if( pwm_index >=  POINT_NUM)								
    {
      pwm_index=0;								
    }
    /* 重置周期計數标志 */
    period_cnt=0;												
  }
}

HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
           

使用 STM32 标準庫的代碼:

/**
  * @brief  配置TIM複用輸出PWM時用到的I/O
  * @param  無
  * @retval 無
  */
static void TIMx_GPIO_Config(void) 
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /*  clock enable */
  RCC_APB2PeriphClockCmd(BRE_TIM_GPIO_CLK, ENABLE); 
  BRE_TIM_GPIO_APBxClock_FUN  ( BRE_TIM_GPIO_CLK, ENABLE );
		
	BRE_GPIO_REMAP_FUN();  

  /* 配置呼吸燈用到的引腳 */
  GPIO_InitStructure.GPIO_Pin =  BRE_TIM_LED_PIN ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	// 複用推挽輸出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init( BRE_TIM_LED_PORT, &GPIO_InitStructure );
}


/**
  * @brief  配置嵌套向量中斷控制器NVIC
  * @param  無
  * @retval 無
  */
static void NVIC_Config_PWM(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* 配置TIM3_IRQ中斷為中斷源 */
  NVIC_InitStructure.NVIC_IRQChannel = BRE_TIMx_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  配置TIM輸出的PWM信号的模式,如周期、極性
  * @param  無
  * @retval 無
  */

static void TIMx_Mode_Config(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;																				
	
	
	/* 設定TIM3CLK 時鐘 */
	BRE_TIM_APBxClock_FUN ( BRE_TIM_CLK, ENABLE ); 
	
	/* 基本定時器配置 ,配合PWM表點數、中斷服務函數中的period_cnt循環次數設定*/	
	
	/* 設定使得整個呼吸過程為3秒左右即可達到很好的效果 */	
	
	//要求:
	//TIM_Period:與PWM表中數值範圍一緻
	//TIM_Prescaler:越小越好,可減輕閃爍現象
	//PERIOD_CLASS:中斷服務函數中控制單個點循環的次數,調整它可控制拟合曲線的周期
	//POINT_NUM:PWM表的元素,它是PWM拟合曲線的采樣點數

	/*************本實驗中的配置***************/	
	/***********************************************
	#python計算腳本	count.py
	#PWM點數
	POINT_NUM = 110

	#周期倍數
	PERIOD_CLASS = 10

	#定時器定時周期
	TIMER_TIM_Period = 2**10
	#定時器分頻
	TIMER_TIM_Prescaler = 200

	#STM32系統時鐘頻率和周期
	f_pclk = 72000000
	t_pclk = 1/f_pclk

	#定時器update事件周期
	t_timer = t_pclk*TIMER_TIM_Prescaler*TIMER_TIM_Period

	#每個PWM點的時間
	T_Point = t_timer * PERIOD_CLASS

	#整個呼吸周期
	T_Up_Down_Cycle = T_Point * POINT_NUM

	print ("呼吸周期:",T_Up_Down_Cycle)
	
	#運作結果:
	
	呼吸周期:3.12888
	************************************************************/

  /* 基本定時器配置 */		  
  TIM_TimeBaseStructure.TIM_Period = (1024-1);;       							  //當定時器從0計數到 TIM_Period+1 ,為一個定時周期
  TIM_TimeBaseStructure.TIM_Prescaler = (200-1);	    							//設定預分頻
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;			//設定時鐘分頻系數:不分頻(這裡用不到)
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  	//向上計數模式
  TIM_TimeBaseInit(BRE_TIMx, &TIM_TimeBaseStructure);

  /* PWM模式配置 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	    				//配置為PWM模式1
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//使能輸出
  TIM_OCInitStructure.TIM_Pulse = 0;				 						  			//設定初始PWM脈沖寬度為0	
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;  	  //當定時器計數值小于CCR1_Val時為低電平

  BRE_TIM_OCxInit ( BRE_TIMx, &TIM_OCInitStructure );	 									//使能通道
	

  BRE_TIM_OCxPreloadConfig ( BRE_TIMx, TIM_OCPreload_Enable );						//使能預裝載	

  TIM_ARRPreloadConfig(BRE_TIMx, ENABLE);			 										//使能TIM重載寄存器ARR

  /* TIM3 enable counter */
  TIM_Cmd(BRE_TIMx, ENABLE);                   										//使能定時器	
	
	TIM_ITConfig(BRE_TIMx, TIM_IT_Update, ENABLE);										//使能update中斷
		
	NVIC_Config_PWM();																					//配置中斷優先級		
}

void BRE_TIMx_IRQHandler(void)
{	
	static uint16_t pwm_index = 0;			//用于PWM查表
	static uint16_t period_cnt = 0;		//用于計算周期數
	
	if (TIM_GetITStatus(BRE_TIMx, TIM_IT_Update) != RESET)	//TIM_IT_Update
 	{			
			period_cnt++;
			
			BRE_TIMx->BRE_CCRx = indexWave[pwm_index];	//根據PWM表修改定時器的比較寄存器值

			//每個PWM表中的每個元素使用period_class次
			if(period_cnt > period_class)				 				
			{				

				pwm_index++;												//标志PWM表指向下一個元素
				

				//若PWM表已到達結尾,重新指向表頭
				if( pwm_index >=  POINT_NUM)			
				{
					pwm_index=0;								
				}
				
				period_cnt=0;											//重置周期計數标志
			}	
			else
			{
			}	
		
		TIM_ClearITPendingBit (BRE_TIMx, TIM_IT_Update);	//必須要清除中斷标志位
	}
}
           

MX_TIM3_Init();

對應

TIMx_GPIO_Config();NVIC_Config_PWM();TIMx_Mode_Config();

HAL_TIM_PWM_Init(&htim3)

對應

TIM_TimeBaseInit(BRE_TIMx, &TIM_TimeBaseStructure)

HAL_TIM_Base_Start_IT(&htim3);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);

對應

TIM_Cmd(BRE_TIMx, ENABLE);TIM_ITConfig(BRE_TIMx, TIM_IT_Update, ENABLE);

五、注意事項

使用者代碼要加在

USER CODE BEGIN N

USER CODE END N

之間,否則下次使用 STM32CubeMX 重新生成代碼後,會被删除。

STM32CubeMX學習筆記(13)——PWM輸出(呼吸燈)使用一、PWM簡介二、定時器簡介三、建立工程四、TIM3通用定時器五、注意事項

• 由 Leung 寫于 2021 年 2 月 3 日

• 參考:STM32CubeMX系列教程4:PWM

    《嵌入式-STM32開發指南》第二部分 基礎篇 - 第5章 PWM(HAL庫)

    STM32CubeMX實戰教程(五)——通用定時器(PWM輸出)

    【STM32】HAL庫 STM32CubeMX教程七—PWM輸出(呼吸燈)

繼續閱讀