国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32 MCU 定時(shí)器詳解(3)--高級(jí)定時(shí)器

這篇具有很好參考價(jià)值的文章主要介紹了STM32 MCU 定時(shí)器詳解(3)--高級(jí)定時(shí)器。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


一、高級(jí)定時(shí)器(TIM1/TIM8)簡(jiǎn)介

1.1 主要特性

  • 16位遞增、遞減、中心對(duì)齊計(jì)數(shù)器(計(jì)數(shù)值:0~65535)
  • 16位預(yù)分頻器(分頻系數(shù):1~65536)
  • 可用于觸發(fā)DAC、ADC
  • 在更新事件、觸發(fā)事件、輸入捕獲、輸出比較時(shí),會(huì)產(chǎn)生中斷/DMA請(qǐng)求
  • 4個(gè)獨(dú)立通道,可用于:輸入捕獲、輸出比較、輸出PWM、單脈沖模式
  • 使用外部信號(hào)控制定時(shí)器且可實(shí)現(xiàn)多個(gè)定時(shí)器互連的同步電路
  • 支持編碼器和霍爾傳感器電路等
  • 重復(fù)計(jì)數(shù)器
  • 死區(qū)時(shí)間帶可編程的互補(bǔ)輸出
  • 斷路輸入,用于將定時(shí)器的輸出信號(hào)置于用戶可選的安全配置中

1.2 框圖

stm32高級(jí)定時(shí)器,單片機(jī),stm32,嵌入式硬件

  • 重復(fù)計(jì)數(shù)器
    重復(fù)計(jì)數(shù)器功能在基本和通用定時(shí)器中的作用稍有不同。在具備重復(fù)計(jì)數(shù)器功能的定時(shí)器中,定時(shí)器不會(huì)在每次上溢或下溢時(shí)立即觸發(fā)更新事件。相反,定時(shí)器的重復(fù)計(jì)數(shù)器會(huì)在每次上溢或下溢時(shí)遞減其值,直到計(jì)數(shù)器值降至零。僅當(dāng)重復(fù)計(jì)數(shù)器的值減到零后,下一次定時(shí)器上溢或下溢時(shí),才會(huì)觸發(fā)更新事件。因此,如果重復(fù)計(jì)數(shù)器的設(shè)置值為N,定時(shí)器需要經(jīng)歷N+1次上溢或下溢才能觸發(fā)一次更新事件。
    需要注意的是,重復(fù)計(jì)數(shù)器寄存器具有影子寄存器機(jī)制,即RCR寄存器的值在更新事件發(fā)生時(shí)才會(huì)更新到影子寄存器并生效,RCR寄存器本身僅作為緩沖使用。
  • 輸出比較
    高級(jí)定時(shí)器輸出比較部分和通用定時(shí)器相比,多了帶死區(qū)控制的互補(bǔ)輸出功能。上面的框圖中,第②部分的TIMx_CH1N、TIMx_CH2N和TIMx_CH3N分別是定時(shí)器通道1、通道2和通道3的互補(bǔ)輸出通道,通道4是沒(méi)有互補(bǔ)輸出通道的。DTG是死區(qū)發(fā)生器,死區(qū)時(shí)間有DTG[7:0]位來(lái)配置。如果不使用互補(bǔ)通道和死區(qū)時(shí)間控制,那么高級(jí)定時(shí)器TIM1和TIM8和通用定時(shí)器的輸出比較部分使用方法基本一樣,只是要注意MOE位得置1定時(shí)器才能輸出。
  • 斷路功能
    斷路功能,也被稱為剎車功能,是電機(jī)控制中用于實(shí)現(xiàn)剎車的一項(xiàng)技術(shù)。斷路的觸發(fā)源可以是外部的剎車輸入引腳(標(biāo)記位TIMx_BKIN)或內(nèi)部的時(shí)鐘失敗事件。這種時(shí)鐘失敗通常是由復(fù)位時(shí)鐘控制器內(nèi)的時(shí)鐘安全系統(tǒng)檢測(cè)并觸發(fā)的。在系統(tǒng)經(jīng)歷復(fù)位后,斷路功能默認(rèn)是關(guān)閉狀態(tài),這可以從MOE位的低電平狀態(tài)中看出。
    要啟動(dòng)斷路功能,用戶需要配置TIMx_BDTR寄存器。具體操作是將該寄存器的BKE位設(shè)置為1,這樣就能使能斷路功能。此外,剎車輸入引腳TIMx_BKIN的有效電平是可配置的,可通過(guò)TIMx_BDTR寄存器中的BKP位進(jìn)行設(shè)置。
    一旦剎車功能被激活,它將通過(guò)多個(gè)寄存器位來(lái)控制輸出狀態(tài),包括TIMx_BDTR寄存器的MOE、OSSI和OSSR位,TIMx_CR2寄存器的OISx和OISxN位,以及TIMx_CCER寄存器和CCxE和CCxNE位。這些控制位確保在任何情況下,輸出比較通道OCx和OCxN的輸出狀態(tài)都不會(huì)同時(shí)為有效電平。
    當(dāng)發(fā)生斷路輸入后,會(huì)怎么樣?
    1、MOE位被異步地清零,OCx和OCxN為無(wú)效、空閑或復(fù)位狀態(tài)(由OSSI位選擇)。
    2、OCx和OCxN的狀態(tài):由相關(guān)控制位狀態(tài)決定,當(dāng)使用互補(bǔ)輸出時(shí):根據(jù)情況自動(dòng)控制輸出電平。
    3、BIF位置1,如果使能了BIE位,還會(huì)產(chǎn)生剎車中斷;如果使能了TDE位,會(huì)產(chǎn)生DMA請(qǐng)求。
    4、如果AOE位置1,在下一個(gè)更新事件UEV時(shí),MOE位被自動(dòng)置1。

二、高級(jí)定時(shí)器輸出指定個(gè)數(shù)PWM

2.1 實(shí)驗(yàn)原理

stm32高級(jí)定時(shí)器,單片機(jī),stm32,嵌入式硬件

  • 配置邊沿對(duì)齊模式輸出PWM
  • 指定輸出N個(gè)PWM,則把N-1個(gè)寫入RCR
  • 在更新中斷內(nèi),關(guān)閉計(jì)數(shù)器

2.2 配置步驟

  • 配置定時(shí)器基礎(chǔ)工作參數(shù):HAL_TIM_PWM_Init()
  • 定時(shí)器PWM輸出MSP初始化:HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置PWM模式/比較值等:HAL_TIM_PWM_ConfigChannel()
  • 設(shè)置優(yōu)先級(jí),使能中斷:HAL_NVIC_SetPriority()、HAL_NVIC_EnableRQ()
  • 使能定時(shí)器更新中斷:__HAL_TIM_ENABLE_IT()
  • 使能輸出、主輸出、計(jì)數(shù)器:HAL_TIM_PWM_Start()
  • 編寫中斷服務(wù)函數(shù):TIMx_IRQHandler()
  • 編寫更新中斷回調(diào)函數(shù):HAL_TIM_PeriodElapsedCallback()

2.3 程序示例

頭文件定義如下:

#include "./SYSTEM/sys/sys.h"

/******************************************************************************************/
/* 高級(jí)定時(shí)器 定義 */

 /* TIMX 輸出指定個(gè)數(shù)PWM 定義 
 * 這里輸出的PWM通過(guò)PC6(TIM8_CH1)輸出, 我們用杜邦線連接PC6和PE5, 然后在程序里面將PE5設(shè)置成浮空輸入
 * 就可以 看到TIM8_CH1控制LED1(GREEN)的亮滅, 亮滅一次表示一個(gè)PWM波
 * 默認(rèn)使用的是TIM8_CH1.
 * 注意: 通過(guò)修改這幾個(gè)宏定義, 可以支持TIM1/TIM8定時(shí)器, 任意一個(gè)IO口輸出指定個(gè)數(shù)的PWM
 */
#define ATIM_TIMX_NPWM_CHY_GPIO_PORT            GPIOC
#define ATIM_TIMX_NPWM_CHY_GPIO_PIN             GPIO_PIN_6
#define ATIM_TIMX_NPWM_CHY_GPIO_CLK_ENABLE()    do{  __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口時(shí)鐘使能 */

#define ATIM_TIMX_NPWM                          TIM8
#define ATIM_TIMX_NPWM_IRQn                     TIM8_UP_IRQn
#define ATIM_TIMX_NPWM_IRQHandler               TIM8_UP_IRQHandler
#define ATIM_TIMX_NPWM_CHY                      TIM_CHANNEL_1                           /* 通道Y,  1<= Y <=4 */
#define ATIM_TIMX_NPWM_CHY_CCRX                 TIM8->CCR1                  /* 通道Y的輸出比較寄存器 */
#define ATIM_TIMX_NPWM_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM8_CLK_ENABLE(); }while(0)  /* TIM8 時(shí)鐘使能 */

/******************************************************************************************/

void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc);   /* 高級(jí)定時(shí)器 輸出指定個(gè)數(shù)PWM初始化函數(shù) */
void atim_timx_npwm_chy_set(uint32_t npwm);                 /* 高級(jí)定時(shí)器 設(shè)置輸出PWM的個(gè)數(shù) */

定時(shí)器源文件代碼如下:

#include "./BSP/TIMER/atim.h"
#include "./BSP/LED/led.h"


TIM_HandleTypeDef g_timx_npwm_chy_handle;     /* 定時(shí)器x句柄 */

/* g_npwm_remain表示當(dāng)前還剩下多少個(gè)脈沖要發(fā)送
 * 每次最多發(fā)送256個(gè)脈沖
 */
static uint32_t g_npwm_remain = 0;

/**
 * @brief       高級(jí)定時(shí)器TIMX 通道Y 輸出指定個(gè)數(shù)PWM 初始化函數(shù)
 * @note
 *              高級(jí)定時(shí)器的時(shí)鐘來(lái)自APB2, 而PCLK2 = 72Mhz, 我們?cè)O(shè)置PPRE2不分頻, 因此
 *              高級(jí)定時(shí)器時(shí)鐘 = 72Mhz
 *              定時(shí)器溢出時(shí)間計(jì)算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定時(shí)器工作頻率,單位:Mhz
 *
 * @param       arr: 自動(dòng)重裝值
 * @param       psc: 時(shí)鐘預(yù)分頻數(shù)
 * @retval      無(wú)
 */
void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc)
{
    GPIO_InitTypeDef gpio_init_struct;
    TIM_OC_InitTypeDef timx_oc_npwm_chy;   /* 定時(shí)器輸出 */
    ATIM_TIMX_NPWM_CHY_GPIO_CLK_ENABLE();  /* TIMX 通道IO口時(shí)鐘使能 */
    ATIM_TIMX_NPWM_CHY_CLK_ENABLE();       /* TIMX 時(shí)鐘使能 */

    g_timx_npwm_chy_handle.Instance = ATIM_TIMX_NPWM;                  /* 定時(shí)器x */
    g_timx_npwm_chy_handle.Init.Prescaler = psc;                       /* 定時(shí)器分頻 */
    g_timx_npwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;      /* 遞增計(jì)數(shù)模式 */
    g_timx_npwm_chy_handle.Init.Period = arr;                          /* 自動(dòng)重裝載值 */
    g_timx_npwm_chy_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /*使能TIMx_ARR進(jìn)行緩沖 */
    g_timx_npwm_chy_handle.Init.RepetitionCounter = 0;                 /* 重復(fù)計(jì)數(shù)器初始值 */
    HAL_TIM_PWM_Init(&g_timx_npwm_chy_handle);                         /* 初始化PWM */

    gpio_init_struct.Pin = ATIM_TIMX_NPWM_CHY_GPIO_PIN;                /* 通道y的CPIO口 */
    gpio_init_struct.Mode = GPIO_MODE_AF_PP;                           /* 復(fù)用推完輸出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                               /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;                     /* 高速 */
    HAL_GPIO_Init(ATIM_TIMX_NPWM_CHY_GPIO_PORT, &gpio_init_struct);

    timx_oc_npwm_chy.OCMode = TIM_OCMODE_PWM1;                         /* 模式選擇PWM 1*/
    timx_oc_npwm_chy.Pulse = arr / 2;                                  /* 設(shè)置比較值,此值用來(lái)確定占空比 */
                                                                       /* 這里默認(rèn)設(shè)置比較值為自動(dòng)重裝載值的一半,即占空比為50% */
    timx_oc_npwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH;                 /* 輸出比較極性為高 */
    HAL_TIM_PWM_ConfigChannel(&g_timx_npwm_chy_handle, &timx_oc_npwm_chy, ATIM_TIMX_NPWM_CHY); /* 配置TIMx通道y */

    HAL_NVIC_SetPriority(ATIM_TIMX_NPWM_IRQn, 1, 3);                   /* 設(shè)置中斷優(yōu)先級(jí),搶占優(yōu)先級(jí)1,子優(yōu)先級(jí)3 */
    HAL_NVIC_EnableIRQ(ATIM_TIMX_NPWM_IRQn);                           /* 開啟ITMx中斷 */

    __HAL_TIM_ENABLE_IT(&g_timx_npwm_chy_handle, TIM_IT_UPDATE);       /* 允許更新中斷 */
    HAL_TIM_PWM_Start(&g_timx_npwm_chy_handle, ATIM_TIMX_NPWM_CHY);    /* 開啟對(duì)應(yīng)PWM通道 */
}

/**
 * @brief       高級(jí)定時(shí)器TIMX NPWM設(shè)置PWM個(gè)數(shù)
 * @param       rcr: PWM的個(gè)數(shù), 1~2^32次方個(gè)
 * @retval      無(wú)
 */
void atim_timx_npwm_chy_set(uint32_t npwm)
{
    if (npwm == 0) return;

    g_npwm_remain = npwm;                                                   /* 保存脈沖個(gè)數(shù) */
    HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE); /* 產(chǎn)生一次更新事件,在中斷里面處理脈沖輸出 */
    __HAL_TIM_ENABLE(&g_timx_npwm_chy_handle);                              /* 使能定時(shí)器TIMX */
}

/**
 * @brief       高級(jí)定時(shí)器TIMX NPWM中斷服務(wù)函數(shù)
 * @param       無(wú)
 * @retval      無(wú)
 */
void ATIM_TIMX_NPWM_IRQHandler(void)
{
    uint16_t npwm = 0;

    /* 以下代碼沒(méi)有使用定時(shí)器HAL庫(kù)共用處理函數(shù)來(lái)處理,而是直接通過(guò)判斷中斷標(biāo)志位的方式 */
    if(__HAL_TIM_GET_FLAG(&g_timx_npwm_chy_handle, TIM_FLAG_UPDATE) != RESET)
    {
        if (g_npwm_remain >= 256)           /* 還有大于256個(gè)脈沖需要發(fā)送 */
        {
            g_npwm_remain = g_npwm_remain - 256;
            npwm = 256;
        }
        else if (g_npwm_remain % 256)       /* 還有位數(shù)(不到256)個(gè)脈沖要發(fā)送 */
        {
            npwm = g_npwm_remain % 256;
            g_npwm_remain = 0;              /* 沒(méi)有脈沖了 */
        }

        if (npwm) /* 有脈沖要發(fā)送 */
        {
            ATIM_TIMX_NPWM->RCR = npwm - 1;                                         /* 設(shè)置重復(fù)計(jì)數(shù)寄存器值為npwm-1, 即npwm個(gè)脈沖 */
            HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE); /* 產(chǎn)生一次更新事件,在中斷里面處理脈沖輸出 */
            __HAL_TIM_ENABLE(&g_timx_npwm_chy_handle);                              /* 使能定時(shí)器TIMX */
        }
        else
        {
            ATIM_TIMX_NPWM->CR1 &= ~(1 << 0); /* 關(guān)閉定時(shí)器TIMX,使用HAL Disable會(huì)清除PWM通道信息,此處不用 */
        }

        __HAL_TIM_CLEAR_IT(&g_timx_npwm_chy_handle, TIM_IT_UPDATE);  /* 清除定時(shí)器溢出中斷標(biāo)志位 */
    }
}

主函數(shù)代碼如下:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/TIMER/atim.h"


int main(void)
{
    uint8_t key = 0;
    uint8_t t = 0;
    GPIO_InitTypeDef gpio_init_struct;

    HAL_Init();                         /* 初始化HAL庫(kù) */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時(shí)鐘, 72Mhz */
    delay_init(72);                     /* 延時(shí)初始化 */
    usart_init(115200);                 /* 串口初始化為115200 */
    led_init();                         /* 初始化LED */
    key_init();                         /* 初始化按鍵 */

    /* 將 LED1 引腳設(shè)置為輸入模式, 避免和PC6沖突 */
    gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引腳 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                /* 設(shè)置為輸入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引腳 */

    atim_timx_npwm_chy_init(5000 - 1, 7200 - 1);            /* 10Khz的計(jì)數(shù)頻率,2hz的PWM頻率. */

    ATIM_TIMX_NPWM_CHY_CCRX = 2500; /* 設(shè)置PWM占空比,50%,這樣可以控制每一個(gè)PWM周期,LED1(BLUE)
                                     * 有一半時(shí)間是亮的,一半時(shí)間是滅的,LED1亮滅一次,表示一個(gè)PWM波
                                     */
    atim_timx_npwm_chy_set(5);      /* 輸出5個(gè)PWM波(控制LED1(BLUE)閃爍5次) */

    while (1)
    {
        key = key_scan(0);

        if (key == KEY0_PRES)           /* KEY0按下 */
        {
            atim_timx_npwm_chy_set(5); /* 輸出5個(gè)PWM波(控制TIM8_CH1, 即PC6輸出5個(gè)脈沖) */
        }

        t++;
        delay_ms(10);

        if (t > 50)                   /* 控制LED0閃爍, 提示程序運(yùn)行狀態(tài) */
        {
            t = 0;
            LED0_TOGGLE();
        }
    }
}

三、高級(jí)定時(shí)器互補(bǔ)輸出帶死區(qū)控制

3.1 捕獲/比較通道的輸出部分

stm32高級(jí)定時(shí)器,單片機(jī),stm32,嵌入式硬件

3.2 死區(qū)時(shí)間計(jì)算

死區(qū)時(shí)間是由TIMx_CR1寄存器的CKD[1:0]位和TIMx_BDTR寄存器的DTG[7:0]位來(lái)設(shè)置,如下圖所示。
stm32高級(jí)定時(shí)器,單片機(jī),stm32,嵌入式硬件

  • 通過(guò)CKD[1:0]位確定tDTS。
    t D T S = 2 C K D [ 1 : 0 ] T c l k tDTS = \frac{2^{CKD[1:0]}}{Tclk} tDTS=Tclk2CKD[1:0]?
    其中:
    CKD[1:0],CKD[1:0]位設(shè)置的值
    Tclk:定時(shí)器的時(shí)鐘源頻率(單位為MHz)
    假設(shè)定時(shí)器時(shí)鐘源頻率是72MHz,我們?cè)O(shè)置CKD[1:0]位的值為2,代入上面的式子可得:
    t D T S = 2 C K D [ 1 : 0 ] T c l k = 2 2 72000000 = 4 72000000 = 55.56 n s tDTS = \frac{2^{CKD[1:0]}}{Tclk} = \frac{2^{2}}{72000000} = \frac{4}{72000000} = 55.56ns tDTS=Tclk2CKD[1:0]?=7200000022?=720000004?=55.56ns
  • 根據(jù)DTG[7:5]選擇公式
  • 代入選擇的公式計(jì)算

3.3 配置步驟

  • 配置定時(shí)器基礎(chǔ)工作參數(shù):HAL_TIM_PWM_Init()
  • 定時(shí)器PWM輸出MSP初始化:HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置PWM模式/比較值等:HAL_TIM_PWM_ConfigChannel()
  • 配置剎車功能、死區(qū)時(shí)間等:HAL_NVIC_ConfigBreakDeadTime()
  • 使能輸出、主輸出、計(jì)數(shù)器:HAL_TIM_PWM_Start()
  • 使能互補(bǔ)輸出、主輸出、計(jì)數(shù)器:HAL_TIMEx_PWMN_Start()

3.4 程序示例

頭文件定義:

#include "./SYSTEM/sys/sys.h"

/* TIMX 互補(bǔ)輸出模式 定義 
 * 這里設(shè)置互補(bǔ)輸出相關(guān)硬件配置, CHY即正常輸出, CHYN即互補(bǔ)輸出
 * 修改CCRx可以修改占空比.
 * 默認(rèn)是針對(duì)TIM1
 * 注意: 通過(guò)修改這些宏定義,可以支持TIM1/TIM8定時(shí)器, 任意一個(gè)IO口輸出互補(bǔ)PWM(前提是必須有互補(bǔ)輸出功能)
 */

/* 輸出通道引腳 */
#define ATIM_TIMX_CPLM_CHY_GPIO_PORT            GPIOE
#define ATIM_TIMX_CPLM_CHY_GPIO_PIN             GPIO_PIN_9
#define ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口時(shí)鐘使能 */

/* 互補(bǔ)輸出通道引腳 */
#define ATIM_TIMX_CPLM_CHYN_GPIO_PORT           GPIOE
#define ATIM_TIMX_CPLM_CHYN_GPIO_PIN            GPIO_PIN_8
#define ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口時(shí)鐘使能 */

/* 剎車輸入引腳 */
#define ATIM_TIMX_CPLM_BKIN_GPIO_PORT           GPIOE
#define ATIM_TIMX_CPLM_BKIN_GPIO_PIN            GPIO_PIN_15
#define ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口時(shí)鐘使能 */

/* TIMX REMAP設(shè)置
 * 因?yàn)镻E8/PE9/PE15, 默認(rèn)并不是TIM1的復(fù)用功能腳, 必須開啟完全重映射, 才可以將: TIM1_CH1->PE9; TIM1_CH1N->PE8; TIM1_BKIN->PE15;
 * 這樣, PE8/PE9/PE15, 才能用作TIM1的CH1N/CH1/BKIN功能.
 * 因此, 必須實(shí)現(xiàn)ATIM_TIMX_CPLM_CHYN_GPIO_REMAP, 通過(guò)sys_gpio_remap_set函數(shù)設(shè)置重映射
 * 如果我們使用默認(rèn)的復(fù)用功能輸出, 則不用設(shè)置重映射, 是可以不需要該函數(shù)的! 根據(jù)具體需要來(lái)實(shí)現(xiàn).
 */
#define ATIM_TIMX_CPLM_CHYN_GPIO_REMAP()        do{__HAL_RCC_AFIO_CLK_ENABLE();\
                                                   __HAL_AFIO_REMAP_TIM1_ENABLE();\
                                                }while(0)                     /* 通道REMAP設(shè)置, 該函數(shù)不是必須的, 根據(jù)需要實(shí)現(xiàn) */

/* 互補(bǔ)輸出使用的定時(shí)器 */
#define ATIM_TIMX_CPLM                          TIM1            
#define ATIM_TIMX_CPLM_CHY                      TIM_CHANNEL_1            
#define ATIM_TIMX_CPLM_CHY_CCRY                 ATIM_TIMX_CPLM->CCR1        
#define ATIM_TIMX_CPLM_CLK_ENABLE()             do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)    /* TIM1 時(shí)鐘使能 */

/******************************************************************************************/
void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc);   /* 高級(jí)定時(shí)器 互補(bǔ)輸出 初始化函數(shù) */
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg);     /* 高級(jí)定時(shí)器 互補(bǔ)輸出 設(shè)置輸出比較值 & 死區(qū)時(shí)間 */

定時(shí)器源文件代碼如下:

#include "./BSP/TIMER/atim.h"
#include "./BSP/LED/led.h"

TIM_HandleTypeDef g_timx_cplm_pwm_handle;                              /* 定時(shí)器x句柄 */
TIM_BreakDeadTimeConfigTypeDef g_sbreak_dead_time_config = {0};        /* 死區(qū)時(shí)間設(shè)置 */

/**
 * @brief       高級(jí)定時(shí)器TIMX 互補(bǔ)輸出 初始化函數(shù)(使用PWM模式1)
 * @note
 *              配置高級(jí)定時(shí)器TIMX 互補(bǔ)輸出, 一路OCy 一路OCyN, 并且可以設(shè)置死區(qū)時(shí)間
 *
 *              高級(jí)定時(shí)器的時(shí)鐘來(lái)自APB2, 而PCLK2 = 72Mhz, 我們?cè)O(shè)置PPRE2不分頻, 因此
 *              高級(jí)定時(shí)器時(shí)鐘 = 72Mhz
 *              定時(shí)器溢出時(shí)間計(jì)算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定時(shí)器工作頻率,單位:Mhz
 *
 * @param       arr: 自動(dòng)重裝值。
 * @param       psc: 時(shí)鐘預(yù)分頻數(shù)
 * @retval      無(wú)
 */

void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc)
{
    GPIO_InitTypeDef gpio_init_struct = {0};
    TIM_OC_InitTypeDef tim_oc_cplm_pwm = {0};

    ATIM_TIMX_CPLM_CLK_ENABLE();            /* TIMx 時(shí)鐘使能 */
    ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE();   /* 通道X對(duì)應(yīng)IO口時(shí)鐘使能 */
    ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE();  /* 通道X互補(bǔ)通道對(duì)應(yīng)IO口時(shí)鐘使能 */
    ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE();  /* 通道X剎車輸入對(duì)應(yīng)IO口時(shí)鐘使能 */
  
    gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHY_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_AF_PP; 
    gpio_init_struct.Pull = GPIO_PULLUP;
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH ;
    HAL_GPIO_Init(ATIM_TIMX_CPLM_CHY_GPIO_PORT, &gpio_init_struct);

    gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHYN_GPIO_PIN;
    HAL_GPIO_Init(ATIM_TIMX_CPLM_CHYN_GPIO_PORT, &gpio_init_struct);

    gpio_init_struct.Pin = ATIM_TIMX_CPLM_BKIN_GPIO_PIN;
    HAL_GPIO_Init(ATIM_TIMX_CPLM_BKIN_GPIO_PORT, &gpio_init_struct);
    
    ATIM_TIMX_CPLM_CHYN_GPIO_REMAP();     /* 映射定時(shí)器IO,PE不是本例程所用定時(shí)器的默認(rèn)IO,需要復(fù)用 */

    g_timx_cplm_pwm_handle.Instance = ATIM_TIMX_CPLM;                       /* 定時(shí)器x */
    g_timx_cplm_pwm_handle.Init.Prescaler = psc;                            /* 定時(shí)器預(yù)分頻系數(shù) */
    g_timx_cplm_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP;           /* 遞增計(jì)數(shù)模式 */
    g_timx_cplm_pwm_handle.Init.Period = arr;                               /* 自動(dòng)重裝載值 */
    g_timx_cplm_pwm_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4;     /* CKD[1:0] = 10, tDTS = 4 * tCK_INT = Ft / 4 = 18Mhz */
    g_timx_cplm_pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* 使能影子寄存器TIMx_ARR */
    HAL_TIM_PWM_Init(&g_timx_cplm_pwm_handle);

    tim_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1;                               /* PWM模式1 */
    tim_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_LOW;                        /* OCy 低電平有效 */
    tim_oc_cplm_pwm.OCNPolarity = TIM_OCNPOLARITY_LOW;                      /* OCyN 低電平有效 */
    tim_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_SET;                      /* 當(dāng)MOE=0,OCx=1 */
    tim_oc_cplm_pwm.OCNIdleState = TIM_OCNIDLESTATE_SET;                    /* 當(dāng)MOE=0,OCxN=1 */
    HAL_TIM_PWM_ConfigChannel(&g_timx_cplm_pwm_handle, &tim_oc_cplm_pwm, ATIM_TIMX_CPLM_CHY);

    /* 設(shè)置死區(qū)參數(shù),開啟死區(qū)中斷 */
    g_sbreak_dead_time_config.OffStateRunMode = TIM_OSSR_DISABLE;           /* 運(yùn)行模式的關(guān)閉輸出狀態(tài) */
    g_sbreak_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE;          /* 空閑模式的關(guān)閉輸出狀態(tài) */
    g_sbreak_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF;                /* 不用寄存器鎖功能 */
    g_sbreak_dead_time_config.BreakState = TIM_BREAK_ENABLE;                /* 使能剎車輸入 */
    g_sbreak_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_HIGH;       /* 剎車輸入有效信號(hào)極性為高 */
    g_sbreak_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; /* 使能AOE位,允許剎車結(jié)束后自動(dòng)恢復(fù)輸出 */
    HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config);

    HAL_TIM_PWM_Start(&g_timx_cplm_pwm_handle, ATIM_TIMX_CPLM_CHY);         /* 使能OCy輸出 */
    HAL_TIMEx_PWMN_Start(&g_timx_cplm_pwm_handle, ATIM_TIMX_CPLM_CHY);      /* 使能OCyN輸出 */
}

/**
 * @brief       定時(shí)器TIMX 設(shè)置輸出比較值 & 死區(qū)時(shí)間
 * @param       ccr: 輸出比較值
 * @param       dtg: 死區(qū)時(shí)間
 *   @arg       dtg[7:5]=0xx時(shí), 死區(qū)時(shí)間 = dtg[7:0] * tDTS
 *   @arg       dtg[7:5]=10x時(shí), 死區(qū)時(shí)間 = (64 + dtg[6:0]) * 2  * tDTS
 *   @arg       dtg[7:5]=110時(shí), 死區(qū)時(shí)間 = (32 + dtg[5:0]) * 8  * tDTS
 *   @arg       dtg[7:5]=111時(shí), 死區(qū)時(shí)間 = (32 + dtg[5:0]) * 16 * tDTS
 *   @note      tDTS = 1 / (Ft /  CKD[1:0]) = 1 / 18M = 55.56ns
 * @retval      無(wú)
 */
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg)
{
    g_sbreak_dead_time_config.DeadTime = dtg;       /* 死區(qū)時(shí)間設(shè)置 */
    HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config);  /* 重設(shè)死區(qū)時(shí)間 */
    __HAL_TIM_MOE_ENABLE(&g_timx_cplm_pwm_handle);  /* MOE=1,使能主輸出 */
    ATIM_TIMX_CPLM_CHY_CCRY = ccr;                  /* 設(shè)置比較寄存器 */
}

主函數(shù)代碼如下:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-854101.html

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/TIMER/atim.h"


int main(void)
{
    uint8_t t = 0;

    HAL_Init();                                /* 初始化HAL庫(kù) */
    sys_stm32_clock_init(RCC_PLL_MUL9);        /* 設(shè)置時(shí)鐘, 72Mhz */
    delay_init(72);                            /* 延時(shí)初始化 */
    usart_init(115200);                        /* 串口初始化為115200 */
    led_init();                                /* 初始化LED */
    atim_timx_cplm_pwm_init(1000 - 1, 72 - 1); /* 1Mhz的計(jì)數(shù)頻率 1Khz的周期. */
    atim_timx_cplm_pwm_set(300, 100);          /* 占空比:7:3, 死區(qū)時(shí)間 100 * tDTS */

    while (1)
    {
        delay_ms(10);
        t++;

        if (t >= 20)
        {
            LED0_TOGGLE(); /* LED0(RED)閃爍 */
            t = 0;
        }
    }
}

到了這里,關(guān)于STM32 MCU 定時(shí)器詳解(3)--高級(jí)定時(shí)器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32——高級(jí)定時(shí)器輸出比較模式實(shí)驗(yàn)

    STM32——高級(jí)定時(shí)器輸出比較模式實(shí)驗(yàn)

    1,配置定時(shí)器基礎(chǔ)工作參數(shù) HAL_TIM_OC_Init() 2,定時(shí)器PWM輸出MSP初始化 HAL_TIM_OC_MspInit() 配置NVIC、CLOCK、GPIO等 3,配置PWM模式/比較值等 HAL_TIM_OC_ConfigChannel() 4,使能通道預(yù)裝載 __HAL_TIM_ENABLE_OCxPRELOAD() 5,使能輸出、主輸出、計(jì)數(shù)器 HAL_TIM_OC_Start() 6,修改捕獲/比較寄存器的值 _HAL

    2024年02月02日
    瀏覽(55)
  • STM32TIM定時(shí)器PWM輸出比較(適用于通用,高級(jí)定時(shí)器)

    STM32TIM定時(shí)器PWM輸出比較(適用于通用,高級(jí)定時(shí)器)

    在定時(shí)器中我們最常用的功能就是輸出PWM,大多是用在電機(jī)控制方面,目前網(wǎng)絡(luò)上相關(guān)資料也有很多,但是,很多不利于我們“現(xiàn)搜現(xiàn)用”我這里不是說(shuō)我寫的有多好,而是你搜索到此類文章時(shí)大部分是急于解決目前的問(wèn)題,一段相關(guān)代碼和講解就行,當(dāng)然不是學(xué)習(xí)背后的原

    2024年01月25日
    瀏覽(21)
  • STM32高級(jí)定時(shí)器輸出指定數(shù)量PWM(STM32CubeMx配置)

    STM32高級(jí)定時(shí)器輸出指定數(shù)量PWM(STM32CubeMx配置)

    高級(jí)定時(shí)器中有一個(gè)重復(fù)計(jì)數(shù)器,本實(shí)驗(yàn)輸出指定個(gè)數(shù)PWM就是利用了重復(fù)計(jì)數(shù)器的特性,先來(lái)看看重復(fù)計(jì)數(shù)器的特性是什么: 計(jì)數(shù)器每次上溢或下溢都能使重復(fù)計(jì)數(shù)器減1,減到0時(shí),再發(fā)生一次溢出就會(huì)產(chǎn)生更新事件 這是什么意思呢,這里舉個(gè)例子比如說(shuō)我設(shè)定重復(fù)計(jì)數(shù)器的

    2024年02月02日
    瀏覽(23)
  • STM32單片機(jī)(六)TIM定時(shí)器 -> 第二節(jié):TIM定時(shí)中斷練習(xí)(定時(shí)器定時(shí)中斷和定時(shí)器外部時(shí)鐘)

    STM32單片機(jī)(六)TIM定時(shí)器 -> 第二節(jié):TIM定時(shí)中斷練習(xí)(定時(shí)器定時(shí)中斷和定時(shí)器外部時(shí)鐘)

    ?? 專欄簡(jiǎn)介:本專欄記錄了從零學(xué)習(xí)單片機(jī)的過(guò)程,其中包括51單片機(jī)和STM32單片機(jī)兩部分;建議先學(xué)習(xí)51單片機(jī),其是STM32等高級(jí)單片機(jī)的基礎(chǔ);這樣再學(xué)習(xí)STM32時(shí)才能融會(huì)貫通。 ?? 專欄適用人群 :適用于想要從零基礎(chǔ)開始學(xué)習(xí)入門單片機(jī),且有一定C語(yǔ)言基礎(chǔ)的的童鞋

    2024年02月09日
    瀏覽(31)
  • stm32專題二十六:高級(jí)定時(shí)器介紹

    stm32專題二十六:高級(jí)定時(shí)器介紹

    高級(jí)定時(shí)器 STM32F103有 2 個(gè)高級(jí)定時(shí)器 TIM1 和 TIM8,高級(jí)定時(shí)器的功能主要有定時(shí)、輸入捕獲、輸出比較、互補(bǔ)輸出等。 高級(jí)定時(shí)器簡(jiǎn)介: 計(jì)數(shù)器16bit,上 / 下 / 兩邊 計(jì)數(shù),TIM1和TIM8,還有一個(gè)重復(fù)計(jì)數(shù)器RCR,獨(dú)有; 有4個(gè)GPIO,其中通道1 ~ 3還有互補(bǔ)輸出GPIO; 時(shí)鐘來(lái)自PCLK2,為

    2024年02月20日
    瀏覽(21)
  • STM32F407高級(jí)定時(shí)器-死區(qū)時(shí)間研究-STM32CubeMX

    STM32F407高級(jí)定時(shí)器-死區(qū)時(shí)間研究-STM32CubeMX

    距離上次寫筆記,已經(jīng)過(guò)去好長(zhǎng)時(shí)間了 中間也折騰過(guò)不少東西,但是都沒(méi)咋整理,主要是這中間都是在干活兒,不是自己想要研究的,也沒(méi)想著要寫。 從去年10月份開始想要學(xué)習(xí)FOC,10月份研究了一個(gè)月,到11月初,實(shí)現(xiàn)了SVPWM驅(qū)動(dòng)BLDC電機(jī),使用串口實(shí)現(xiàn)開環(huán)下轉(zhuǎn)速和力矩調(diào)

    2023年04月23日
    瀏覽(27)
  • STM32使用高級(jí)定時(shí)器輸出互補(bǔ)pwm波

    STM32使用高級(jí)定時(shí)器輸出互補(bǔ)pwm波

    最近做的一個(gè)項(xiàng)目用到stm32,網(wǎng)上查了很多資料,也踩了很多坑,這里記錄一下配置的步驟和說(shuō)明 硬件使用的是stm32h750vbt6; 軟件用到了stm32cubemx和keil5; 打開Debug模式方便調(diào)試,可以忽略,不影響代碼運(yùn)行 在用cube配置時(shí)鐘源時(shí),有下面三個(gè)選項(xiàng) Disable(禁用) BYPASS Clock Sou

    2024年02月16日
    瀏覽(20)
  • 【單片機(jī)】STM32單片機(jī)的各個(gè)定時(shí)器的定時(shí)中斷程序,標(biāo)準(zhǔn)庫(kù)

    【單片機(jī)】STM32單片機(jī)的各個(gè)定時(shí)器的定時(shí)中斷程序,標(biāo)準(zhǔn)庫(kù)

    高級(jí)定時(shí)器和普通定時(shí)器的區(qū)別(https://zhuanlan.zhihu.com/p/557896041): TIM1是高級(jí)定時(shí)器,使用的時(shí)鐘總線是RCC_APB2Periph_TIM1,和普通定時(shí)器不一樣。 timer.c timer.h 調(diào)用 timer.c timer.h 調(diào)用 timer.c timer.h 調(diào)用 timer.c timer.h 調(diào)用 timer.c timer.h 調(diào)用

    2024年02月11日
    瀏覽(25)
  • STM32定時(shí)器-定時(shí)器中斷功能詳解

    STM32定時(shí)器-定時(shí)器中斷功能詳解

    STM32的眾多定時(shí)器中我們使用最多的是高級(jí)定時(shí)器和通用定時(shí)器,而高級(jí)定時(shí)器一般也是用作通用定時(shí)器的功能,下面我們就以通用定時(shí)器為例進(jìn)行講解,其功能和特點(diǎn)包括: 通用與基本定時(shí)器(2~7)位于低速的APB1總線上 高級(jí)定時(shí)器(1、8)位于高速的APB2總線上 自動(dòng)裝載計(jì)

    2024年02月08日
    瀏覽(108)
  • STM32實(shí)戰(zhàn)-高級(jí)定時(shí)器帶死區(qū)的互補(bǔ)PWM輸出

    STM32實(shí)戰(zhàn)-高級(jí)定時(shí)器帶死區(qū)的互補(bǔ)PWM輸出

    前言: 平時(shí)我們?cè)O(shè)計(jì)點(diǎn)擊驅(qū)動(dòng)電路時(shí),一般會(huì)采用npn和pnp三極管,來(lái)控制電機(jī)的導(dǎo)通和關(guān)閉,但是三級(jí)管內(nèi)部自帶電容,斷電后不會(huì)立馬斷掉,會(huì)經(jīng)過(guò)很小的一段時(shí)間才會(huì)放電完畢,這時(shí)候要留有死區(qū)給電容放電,這就有了互補(bǔ)pwm波。 ? 同時(shí),當(dāng)電機(jī)出現(xiàn)故障,如果利用軟

    2024年02月08日
    瀏覽(21)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包