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

【正點原子STM32連載】第二十一章 高級定時器輸出指定個數(shù)PWM實驗 摘自【正點原子】APM32E103最小系統(tǒng)板使用指南

這篇具有很好參考價值的文章主要介紹了【正點原子STM32連載】第二十一章 高級定時器輸出指定個數(shù)PWM實驗 摘自【正點原子】APM32E103最小系統(tǒng)板使用指南。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1)實驗平臺:正點原子APM32E103最小系統(tǒng)板
2)平臺購買地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套實驗源碼+手冊+視頻下載地址: http://www.openedv.com/docs/boards/xiaoxitongban

第二十一章 高級定時器輸出指定個數(shù)PWM實驗

本章將介紹使用APM32E103高級定時器輸出指定個數(shù)的PWM。通過本章的學(xué)習(xí),讀者將學(xué)習(xí)到高級定時器重復(fù)計數(shù)器的使用。
本章分為如下幾個小節(jié):
21.1 硬件設(shè)計
21.2 程序設(shè)計
21.3 下載驗證

21.1 硬件設(shè)計
21.1.1 例程功能

  1. 按下KEY0按鍵,控制定時器8通過PC6引腳以2Hz的頻率輸出5個PWM脈沖
    21.1.2 硬件資源
  2. 按鍵
    KEY0 - PE4
  3. 定時器8
    通道1 - PC6
    21.1.3 原理圖
    本章實驗使用的定時器8為APM32E103的片上資源,因此沒有對應(yīng)的連接原理圖。
    21.2 程序設(shè)計
    21.2.1 Geehy標(biāo)準(zhǔn)庫的TMR驅(qū)動
    本章實驗將使用KEY0按鍵控制TMR8通過通道1(PC6引腳)輸出指定個數(shù)的PWM。對于高級定時器自動重裝載值、預(yù)分頻計數(shù)器數(shù)值等基本參數(shù)的配置,與基本定時器和通用定時器的配置基本一致;對于高級定時器輸出PWM,則于通用定時器輸出PWM的配置基本一致,不過于通用定時器不同的是,高級定時器使能輸出PWM需要將“剎車和死區(qū)寄存器(TMRx_BDT)”的MOEN位置1。要做到輸出指定個數(shù)的PWM,需要使用到高級定時器的重復(fù)計數(shù)寄存器,重復(fù)計數(shù)寄存器可以配置高級定時器產(chǎn)生多少次上溢或下溢(一次上溢或下溢對應(yīng)一個PWM)后才產(chǎn)生一次更新事件,其具體的配置步驟如下:
    ①:配置TMR8的自動重裝載值和預(yù)分頻器數(shù)值等參數(shù)
    ②:配置輸出比較通道1
    ③:使能TMR8的更新中斷
    ④:使能TMR8中斷,并配置其相關(guān)的中斷優(yōu)先級
    ⑤:使能TMR8
    ⑥:使能輸出比較通道1輸出
    ⑦:使能TMR8的PWM輸出
    ⑧:配置TMR8的重復(fù)計數(shù)寄存器
    在Geehy標(biāo)準(zhǔn)庫中對應(yīng)的驅(qū)動函數(shù)如下:
    ①:配置TMR
    請見第16.2.1小節(jié)中配置TMR的相關(guān)內(nèi)容。
    ②:配置輸出比較通道
    請見第18.2.1小節(jié)中配置輸出比較通道的相關(guān)內(nèi)容。
    ③:使能TMR指定中斷
    請見第16.2.1小節(jié)中使能TMR指定中斷的相關(guān)內(nèi)容。
    ④:配置TMR中斷
    請見第12.2.3小節(jié)中配置中斷的相關(guān)內(nèi)容。
    ⑤:使能TMR
    請見第16.2.1小節(jié)中使能TMR的相關(guān)內(nèi)容。
    ⑥:使能捕獲比較通道
    請見第18.2.1小節(jié)中使能捕獲比較通道的相關(guān)內(nèi)容。
    ⑦:使能高級定時器PWM輸出
    該函數(shù)用于使能高級定時器輸出PWM,其函數(shù)原型如下所示:
    void TMR_EnablePWMOutputs(TMR_T* tmr);
    該函數(shù)的形參描述,如下表所示:
    形參 描述
    tmr 指向高級TMR外設(shè)結(jié)構(gòu)體的指針
    例如:TMR1、TMR8(在apm32e10x.h文件中有定義)
    表21.2.1.1 函數(shù)TMR_EnablePWMOutputs()形參描述
    該函數(shù)的返回值描述,如下表所示:
    返回值 描述
    無 無
    表21.2.1.2 函數(shù)TMR_EnablePWMOutputs()返回值描述
    該函數(shù)的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_tmr.h"

void example_fun(void)
{
    /* 使能TMR8使出PWM */
    TMR_EnablePWMOutputs(TMR8);
}

⑧:配置重復(fù)計數(shù)寄存器
高級定時器的重復(fù)計數(shù)寄存器可以在配置TMR寄存器參數(shù)時,通過函數(shù)TMR_ConfigTimeBase()進(jìn)行配置,也可以通過寫寄存器的方式直接修改高級定時器重復(fù)計數(shù)寄存器的數(shù)值,示例如下所示:

#include "apm32e10x.h"

void example_fun(void)
{
    /* 配置TMR8的重復(fù)計數(shù)寄存器為5 */
    TMR8->REPCNT = 5;
}

21.2.2 高級定時器驅(qū)動
本章實驗的高級定時器驅(qū)動主要負(fù)責(zé)向應(yīng)用層提供高級定時器的初始化和輸出指定個數(shù)PWM的函數(shù),并實現(xiàn)高級定時器的中斷回調(diào)函數(shù)。本章實驗中,高級定時器驅(qū)動的驅(qū)動代碼包括atmr.c和atmr.h兩個文件。
高級定時器驅(qū)動中,對TMR、GPIO的相關(guān)宏定義,如下所示:
/* 高級定時器PWM輸出引腳定義 */

#define ATMRX_TMRX_NPWM_CHY_GPIO_PORT           GPIOC
#define ATMRX_TMRX_NPWM_CHY_GPIO_PIN            GPIO_PIN_6
#define ATMRX_TMRX_NPWM_CHY_GPIO_CLK_ENABLE()   do{ RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOC); }while(0)

/* 高級定時器定義 */
#define ATMRX_TMRX_NPWM                         TMR8
#define ATMRX_TMRX_NPWM_IRQn                    TMR8_UP_IRQn
#define ATMRX_TMRX_NPWM_IRQHandler              TMR8_UP_IRQHandler
#define ATMRX_TMRX_NPWM_CHY                     TMR_CHANNEL_1
#define ATMRX_TMRX_NPWM_CHY_CLK_ENABLE()        do{ RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR8); }while(0)
高級定時器驅(qū)動中TMR8的初始化函數(shù),如下所示:
/**
 * @brief       初始化高級定時器PWM輸出模式
 * @note
 *              高級定時器的時鐘來自APB2, 而PCLK2 = 120Mhz, 我們設(shè)置PPRE2不分頻, 因此
 *              高級定時器時鐘 = 120Mhz
 *              定時器溢出時間計算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定時器工作頻率,單位:Mhz
 *
 * @param       arr: 自動重裝值
 * @param       psc: 時鐘預(yù)分頻數(shù)
 * @retval      無
 */
void atmr_tmrx_npwm_chy_init(uint16_t arr, uint16_t psc)
{
    GPIO_Config_T gpio_init_struct;
    TMR_BaseConfig_T tmr_init_struct;
    TMR_OCConfig_T tmr_oc_init_struct;
    
    /* 使能時鐘 */
    ATMRX_TMRX_NPWM_CHY_GPIO_CLK_ENABLE();        /* 高級定時器通道I/O口時鐘使能 */
    ATMRX_TMRX_NPWM_CHY_CLK_ENABLE();             /* 高級定時器時鐘使能 */
    
    /* 配置PWM輸出引腳 */
    gpio_init_struct.pin = ATMRX_TMRX_NPWM_CHY_GPIO_PIN;   /* 通道y的GPIO口 */
    gpio_init_struct.mode = GPIO_MODE_AF_PP;               /* 推挽復(fù)用輸出 */
    gpio_init_struct.speed = GPIO_SPEED_50MHz;             /* 高速 */
    GPIO_Config(ATMRX_TMRX_NPWM_CHY_GPIO_PORT, &gpio_init_struct);/* 初始化GPIO*/
    
    /* 配置高級定時器 */
    tmr_init_struct.countMode = TMR_COUNTER_MODE_UP;       /* 遞增計數(shù)模式 */
    tmr_init_struct.clockDivision = TMR_CLOCK_DIV_1;       /* 時鐘分頻系數(shù) */
    tmr_init_struct.period = arr;                          /* 自動重裝載值 */
    tmr_init_struct.division = psc;                        /* 定時器分頻 */
    tmr_init_struct.repetitionCounter = 0;                 /* 重復(fù)計數(shù)器初始值 */
    TMR_ConfigTimeBase(ATMRX_TMRX_NPWM, &tmr_init_struct); /* 初始化PWM */
    
    /* 配置指定個PWM輸出 */
    tmr_oc_init_struct.mode = TMR_OC_MODE_PWM1;            /* 模式選擇PWM1 */
    tmr_oc_init_struct.outputState = TMR_OC_STATE_ENABLE;  /* 使能輸出比較狀態(tài) */
    tmr_oc_init_struct.outputNState = TMR_OC_NSTATE_ENABLE;/* 使能輸出比較N狀態(tài) */
    tmr_oc_init_struct.polarity = TMR_OC_POLARITY_HIGH;    /* 輸出比較極性為高 */
tmr_oc_init_struct.nPolarity = TMR_OC_NPOLARITY_HIGH;  /* 輸出比較N極性為高 */
/* 當(dāng)MOE=0,重置高級定時器輸出比較空閑狀態(tài) */
tmr_oc_init_struct.idleState = TMR_OC_IDLE_STATE_RESET;
/* 當(dāng)MOE=0,重置高級定時器輸出比較空閑狀態(tài) */
tmr_oc_init_struct.nIdleState = TMR_OC_NIDLE_STATE_RESET;
/* 設(shè)置比較值,此值用來確定占空比 */
    tmr_oc_init_struct.pulse = arr / 2;
    
    /* 配置高級定時器通道與重裝載 */
TMR_ConfigOC1(ATMRX_TMRX_NPWM, &tmr_oc_init_struct);   /* 配置高級定時器通道 */
/* 使能高級定時器在CCMx上的預(yù)裝 */
    TMR_ConfigOC1Preload(ATMRX_TMRX_NPWM, TMR_OC_PRELOAD_ENABLE);
    TMR_EnableAUTOReload(ATMRX_TMRX_NPWM);                 /* 配置重裝載寄存器 */
    
    /* 開啟高級定時器相對應(yīng)的通道以及相中斷 */
    NVIC_EnableIRQRequest(ATMRX_TMRX_NPWM_IRQn, 1, 0);     /* 開啟高級定時器中斷 */
    TMR_EnablePWMOutputs(ATMRX_TMRX_NPWM);                 /* 開啟高級定時器PWM輸出 */
TMR_EnableInterrupt(ATMRX_TMRX_NPWM, TMR_INT_UPDATE);  /* 允許更新中斷 */
/* 開啟對應(yīng)PWM通道 */
    TMR_EnableCCxChannel(ATMRX_TMRX_NPWM, ATMRX_TMRX_NPWM_CHY);
}

從上面的代碼中可以看出,本章實驗中對高級定時器的初始化于前面章節(jié)中使用通用定時器輸出PWM中對通用定時器的初始化配置是比較類似的,最大不同還是在高級定時器中斷服務(wù)函數(shù)中對高級定時器特有的重復(fù)計數(shù)寄存器的相關(guān)處理中。
高級定時器驅(qū)動中,開啟高級定時器輸出指定個數(shù)PWM的函數(shù),如下所示:

/**
 * @brief       高級定時器設(shè)置PWM個數(shù)
 * @param       rcr: PWM的個數(shù), 1~2^32次方個
 * @retval      無
 */
void atmr_tmrx_npwm_chy_set(uint32_t npwm)
{
    if (npwm == 0)
    {
        return;
    }
    g_npwm_remain = npwm;                                   /* 保存脈沖個數(shù) */
    TMR_GenerateEvent(ATMRX_TMRX_NPWM, TMR_EVENT_UPDATE);   /* 產(chǎn)生一次更新事件,在中斷里面處理脈沖輸出 */
    TMR_Enable(ATMRX_TMRX_NPWM);                            /* 使能高級定時器 */
}
該函數(shù)記錄下了需要產(chǎn)生的PWM個數(shù),因為會在TMR8的更新中斷中處理輸出PWM,因此手動產(chǎn)生了一次更新事件,由于初始化函數(shù)中開啟了TMR8的更新中斷,因此隨后會進(jìn)入TMR的中斷服務(wù)函數(shù)中。
高級定時器驅(qū)動中,TMR8的中斷回調(diào)函數(shù),如下所示:
/**
 * @brief       高級定時器NPWM中斷服務(wù)函數(shù)
 * @param       無
 * @retval      無
 */
void ATMRX_TMRX_NPWM_IRQHandler(void)
{
    uint16_t npwm = 0;
    
	/* 檢查通用定時器更新中斷是否發(fā)生 */
    if (TMR_ReadIntFlag(ATMRX_TMRX_NPWM, TMR_INT_UPDATE) != RESET)  
{
	/* 清除定時器溢出中斷標(biāo)志位 */
        TMR_ClearIntFlag(ATMRX_TMRX_NPWM, TMR_INT_UPDATE);
        
        if (g_npwm_remain > 256)              /* 還有大于256個脈沖需要發(fā)送 */
        {
            g_npwm_remain = g_npwm_remain - 256;
            npwm = 256;
        }
        else if (g_npwm_remain % 256)         /* 還有位數(shù)(不到256)個脈沖要發(fā)送 */
        {
            npwm = g_npwm_remain % 256;
            g_npwm_remain = 0;                /* 沒有脈沖了 */
        }
        
        if (npwm)                             /* 有脈沖要發(fā)送 */
        {
/* 設(shè)置重復(fù)計數(shù)寄存器值為npwm-1, 即npwm個脈沖 */
            ATMRX_TMRX_NPWM->REPCNT = npwm - 1;
            /* 產(chǎn)生一次更新事件,在中斷里面處理脈沖輸出 */
            TMR_GenerateEvent(ATMRX_TMRX_NPWM, TMR_EVENT_UPDATE);
            TMR_Enable(ATMRX_TMRX_NPWM);        /* 使能高級定時器 */
        }
        else
        {
            TMR_Disable(ATMRX_TMRX_NPWM);       /* 關(guān)閉高級定時器 */
        }
    }
}

因為高級定時器的重復(fù)計數(shù)寄存器只有低八位有效,因此需要在需要產(chǎn)生大于255個PWM的情況下做特殊處理,隨后將需要產(chǎn)生的PWM個數(shù)值減1寫入TMR8的重復(fù)計數(shù)寄存器,并且由于寫入重復(fù)計數(shù)寄存器的新值只有在下一次更新事件發(fā)生時才生效,因此需要手動產(chǎn)生一次更新事件,最后使能TMR8,這么一來,TMR8就會持續(xù)地輸出PWM直到重復(fù)計數(shù)寄存器的數(shù)值為0后,產(chǎn)生一次更新中斷,若此時已經(jīng)輸出完了指定個數(shù)的PWM,那么就會使用函數(shù)TMR_Disable()關(guān)閉高級定時器。
21.2.3 實驗應(yīng)用代碼
本實驗的應(yīng)用代碼,如下所示:

int main(void)
{
    uint8_t t = 0;
    uint8_t key = 0;
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4);  /* 設(shè)置中斷優(yōu)先級分組為組4 */
    sys_apm32_clock_init(15);                         /* 配置系統(tǒng)時鐘 */
    delay_init(120);                                  /* 初始化延時功能 */
    usart_init(115200);                               /* 初始化串口 */
    led_init();                                       /* 初始化LED */
    atmr_tmrx_npwm_chy_init(5000 - 1, 12000 - 1);     /* 初始化PWM輸出模式 */
    atmr_tmrx_npwm_chy_set(5);                        /* 高級定時器輸出PWM個數(shù) */
    
    while (1)
    {
        key = key_scan(0);
        
        if (key == KEY0_PRES)                         /* KEY0按下 */
        {
			/* 輸出5個PWM波(控制TMR8_CH1, 即PC6輸出5個脈沖) */
            atmr_tmrx_npwm_chy_set(5); 
        }
        t++;
        delay_ms(10);
        
        if (t > 50)
        {
            t = 0;
/* 控制LED0閃爍, 提示程序運行狀態(tài) */
            LED0_TOGGLE();
        }
    }
}

從上面的代碼中可以看到,TMR8的自動重裝載值配置為(5000-1),TMR8的預(yù)分頻器數(shù)值配置為(12000-1),并且TMR8的時鐘頻率為120MHz,因此TMR8的計數(shù)頻率為10KHz,且TMR8每計數(shù)5000次溢出一次,因此溢出頻率為2Hz,也就是輸出PWM的頻率為2Hz。
初始化完TMR8后,就重復(fù)地掃描按鍵,若KEY0按鍵被按下,則輸出5個PWM。
21.3 下載驗證
在完成編譯和燒錄操作后,按下KEY0按鍵,此時可以通過示波器或外接LED的方式觀察PC6引腳輸出了5個頻率為2Hz,占空比為50%的PWM。文章來源地址http://www.zghlxwxcb.cn/news/detail-834493.html

到了這里,關(guān)于【正點原子STM32連載】第二十一章 高級定時器輸出指定個數(shù)PWM實驗 摘自【正點原子】APM32E103最小系統(tǒng)板使用指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包