基于HAL庫的STM32F103定時器主從模式輸出固定數(shù)量的PWM脈沖

1 硬件和軟件平臺

  • 硬件:自制STM32F103C8T6
  • 軟件:STM32CubeMX 6.1.0
  • 軟件:Keil V5.28.0.0
  • 硬件包:STM32Cube_FW_F1 V1.8.3

2 定時器介紹

STM32的定時器可以通過另外一個定時器的某一個條件被觸發(fā)而啟動榆浓,即同步的工作方式。發(fā)出觸發(fā)信號的定時器工作于主模式(Master)角雷,接受觸發(fā)信號而啟動的定時器工作于從模式(Slave)堕阔。它們之間通過TIM內(nèi)部觸發(fā)連接(ITR)瘦材。使用不同的主從定時器,使用的ITR不同,根據(jù)參考手冊(版本ENV20)可以知道對應(yīng)的ITR车要。


圖1 參考手冊中的高級定時器內(nèi)部觸發(fā)連接

圖2 參考手冊中的通用定時器內(nèi)部觸發(fā)連接

3 CubeMX配置

不再介紹CubeMX創(chuàng)建工程的方法。

3.1 設(shè)置時鐘

在RCC中配置高速時鐘厘熟,選擇外部晶振屯蹦。


圖3 高速時鐘的配置

在Clock Configuration中選擇HSE,并配置HCLK為72MHz绳姨。


圖4 Clock Configuration 配置

3.2 設(shè)置仿真模式

在SYS設(shè)置仿真模式登澜,此處我使用的是SW,根據(jù)情況自行選擇飘庄。


圖5 Debug配置

3.3 設(shè)置主定時器(Master)

此處我使用TIM2作為Master脑蠕,通道2輸出PWM。TIM1為Slave跪削。在CubeMX中選擇TIM2谴仙,配置主定時器。 Channel2選擇PWM Generation CH2碾盐。


圖6 Master TIM模式配置

預(yù)分頻系數(shù)為71(設(shè)置值不能大于65535)晃跺,計數(shù)器周期為9,這兩個配置控制PWM輸出的頻率毫玖。由于我們時鐘是72MHz掀虎,此處設(shè)置的PWM頻率為100kHz。


圖7 Master TIM參數(shù)配置

圖8 PWM頻率計算公式

設(shè)置Pulse為5付枫,該值和計數(shù)器周期共同控制PWM的占空比烹玉,此處為50%。
圖9 PWM占空比計算公式

使能主從模式阐滩,觸發(fā)事件選擇Update Event二打。禁用輸出比較預(yù)加載。輸出極性Low掂榔。

3.4 設(shè)置從定時器(Slave)

此處我選擇TIM1為Slave继效。由圖1可知症杏,TIM2為Master,TIM1為Slave時莲趣,使用ITR1鸳慈。在CubeMX中選擇TIM1。設(shè)置Slave Mode為Gated Mode喧伞,觸發(fā)源選擇ITR1(根據(jù)自己使用的定時器選擇)走芋,時鐘源選擇內(nèi)部時鐘。


圖10 Slave TIM模式配置

參數(shù)設(shè)置基本是保持默認潘鲫。


圖11 Slave TIM參數(shù)配置

使能從定時器的中斷翁逞。此處我使用的是高級定時器作為Slave,如果是通用定時器溉仑,只需使能定時器全局中斷即可挖函。
圖12 Slave TIM中斷配置

CubeMX配置完成,點擊GENERATE CODE生成代碼浊竟。

4 代碼

CubeMX已經(jīng)幫我們生成了初始化代碼怨喘,無需修改。
主定時器(此處是TIM2)初始化代碼:

/* TIM2 init function */
void MX_TIM2_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 71;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 9;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 5;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  __HAL_TIM_DISABLE_OCxPRELOAD(&htim2, TIM_CHANNEL_2);
  HAL_TIM_MspPostInit(&htim2);

}

從定時器(此處是TIM1)初始化代碼:

/* TIM1 init function */
void MX_TIM1_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 0;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 65535;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;
  sSlaveConfig.InputTrigger = TIM_TS_ITR1;
  if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

在main.c中定義標志位以指示PWM是否處于輸出狀態(tài)振定。

/* USER CODE BEGIN PV */
uint8_t PWM_OK = 0;
/* USER CODE END PV */

在main函數(shù)初始化完成后添加以下代碼必怜。

  /* USER CODE BEGIN 2 */
    HAL_TIM_Base_Start_IT(&htim1);
    HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_2);
    __HAL_TIM_SET_AUTORELOAD(&htim1, 0);
  /* USER CODE END 2 */

在stm32f1xx_it.c中添加外部變量引用和中斷回調(diào)函數(shù),也可以添加到其他文件中后频,根據(jù)自己習慣來梳庆。由于我們使能了TIM1的中斷,此處CubeMX會自動添加TIM1的引用卑惜,只需手動添加TIM2的引用即可膏执。

/* USER CODE BEGIN PV */
extern uint8_t PWM_OK;
/* USER CODE END PV */

/* USER CODE BEGIN EV */
extern TIM_HandleTypeDef htim2;
/* USER CODE END EV */

在中斷回調(diào)函數(shù)中清除中斷標志位,并停止PWM露久。

/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim == (&htim1))
    {
        if(__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_CC1) != RESET)
        {
            __HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC1);
            HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_2);
            HAL_TIM_Base_Stop_IT(&htim1);
        }
        PWM_OK = 1;
    }
}
/* USER CODE END 1 */

在main.c中封裝PWM輸出函數(shù)更米,并在main.h中聲明。

/**
  * @brief  The application outputs a specified number of pulses.
    * @param    num is the number of pulses.
  */
void OutPwm(uint32_t num)
{
    if(PWM_OK == 1)
    {
        PWM_OK = 0;
        __HAL_TIM_SET_AUTORELOAD(&htim1, num - 1);
        HAL_TIM_Base_Start_IT(&htim1);
        HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_2);
    }
}

在while(1)中輸出10個脈沖并延遲40ms毫痕。

  while (1)
  {
        HAL_Delay(40);
        OutPwm(10);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

5 測試結(jié)果

因為我的硬件中使用了緩沖器將PWM的電平提高到了5V壳快,因此測量結(jié)果都是5Vpp。
可以看到镇草,每40ms有脈沖輸出。


圖13 PWM脈沖輸出

放大細節(jié)可以看到得到100kHz的10個脈沖瘤旨,波形還不錯梯啤。


圖14 PWM輸出細節(jié)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市存哲,隨后出現(xiàn)的幾起案子因宇,更是在濱河造成了極大的恐慌七婴,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件察滑,死亡現(xiàn)場離奇詭異打厘,居然都是意外死亡,警方通過查閱死者的電腦和手機贺辰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門户盯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人饲化,你說我怎么就攤上這事莽鸭。” “怎么了吃靠?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵硫眨,是天一觀的道長。 經(jīng)常有香客問我巢块,道長礁阁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任族奢,我火速辦了婚禮姥闭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歹鱼。我一直安慰自己泣栈,他們只是感情好,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布弥姻。 她就那樣靜靜地躺著南片,像睡著了一般。 火紅的嫁衣襯著肌膚如雪庭敦。 梳的紋絲不亂的頭發(fā)上疼进,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機與錄音秧廉,去河邊找鬼伞广。 笑死,一個胖子當著我的面吹牛疼电,可吹牛的內(nèi)容都是我干的嚼锄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼蔽豺,長吁一口氣:“原來是場噩夢啊……” “哼区丑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沧侥,失蹤者是張志新(化名)和其女友劉穎可霎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宴杀,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡癣朗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了旺罢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旷余。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖主经,靈堂內(nèi)的尸體忽然破棺而出荣暮,到底是詐尸還是另有隱情,我是刑警寧澤罩驻,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布穗酥,位于F島的核電站,受9級特大地震影響惠遏,放射性物質(zhì)發(fā)生泄漏砾跃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一节吮、第九天 我趴在偏房一處隱蔽的房頂上張望抽高。 院中可真熱鬧,春花似錦透绩、人聲如沸翘骂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碳竟。三九已至,卻和暖如春狸臣,著一層夾襖步出監(jiān)牢的瞬間莹桅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工烛亦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诈泼,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓煤禽,卻偏偏與公主長得像铐达,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子檬果,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容