0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

GD32F303固件庫(kù)開發(fā)(13)----定時(shí)器TIM捕獲PWM測(cè)量頻率與占空比

嵌入式單片機(jī)MCU開發(fā) ? 來源:嵌入式單片機(jī)MCU開發(fā) ? 作者:嵌入式單片機(jī)MCU開 ? 2022-12-07 10:19 ? 次閱讀

概述

本章配置GD32F303輸出PWM,同時(shí)使用TIM測(cè)量PWM頻率和正占空比。 查閱手冊(cè)可以得知,PB11為定時(shí)器1的通道3,讓其輸出PWM,PA6為定時(shí)器2的通道0,讓作為TIM定時(shí)器輸入。 需要GD樣片的可以加群申請(qǐng):615061293 。

在這里插入圖片描述

在這里插入圖片描述

生成例程

這里準(zhǔn)備了自己繪制的開發(fā)板進(jìn)行驗(yàn)證。

管腳圖如下所示。

在這里插入圖片描述

在這里插入圖片描述

keil配置

microlib 進(jìn)行了高度優(yōu)化以使代碼變得很小。 它的功能比缺省 C 庫(kù)少,并且根本不具備某些 ISO C 特性。 某些庫(kù)函數(shù)的運(yùn)行速度也比較慢,如果要使用printf(),必須開啟。

在這里插入圖片描述

使能串口

/* 使能GPI0A,用PA9、PA10為串口 */
    rcu_periph_clock_enable(RCU_GPIOA);

    /*使能串口0的時(shí)鐘 */
    rcu_periph_clock_enable(RCU_USART0);

    /*配置USARTx_Tx(PA9)為復(fù)用推挽輸出*/
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);

    /*配置USARTx_RxPA9)為浮空輸入 */
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

    /* USART 配置 */
    usart_deinit(USART0);//重置串口0
    usart_baudrate_set(USART0, 115200U);//設(shè)置串口0的波特率為115200
    usart_word_length_set(USART0, USART_WL_8BIT);          // 幀數(shù)據(jù)字長(zhǎng)
        usart_stop_bit_set(USART0, USART_STB_1BIT);               // 停止位1位
    usart_parity_config(USART0, USART_PM_NONE);           // 無奇偶校驗(yàn)位
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);//使能接收器
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);//使能發(fā)送器
    usart_enable(USART0);//使能USART

串口重定向

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART0, (uint8_t)ch);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    return ch;
}

串口重定向后就可以使用printf進(jìn)行打印。

占空比與頻率計(jì)算

占空比=(t1-t0)/(t2-t0) 頻率=(t2-t0)/時(shí)鐘頻率= =(t2-t0)/(120M/(psc+1))

在這里插入圖片描述

周期需要2個(gè)上升沿去判斷,設(shè)定第一個(gè)上升沿time_flag由0->1,下降沿time_dowm_flag由0->1,此時(shí)就知道正占空比時(shí)間,當(dāng)在產(chǎn)生上升沿時(shí)候,就可以計(jì)算出周期使用的時(shí)間。

在這里插入圖片描述

GPIO初始化

/*!
    rief      configure the GPIO ports
    param[in]  none
    param[out] none
    
etval     none
*/
void gpio_configuration(void)
{
        rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_AF);

    /*configure PA6 (TIMER2 CH0) as alternate function*/
    gpio_init(GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
        //TIMER1-CH3
        gpio_pin_remap_config(GPIO_TIMER1_PARTIAL_REMAP1, ENABLE);
        gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_11);        
}

開啟中斷

/*!
    rief      configure the nested vectored interrupt controller
    param[in]  none
    param[out] none
    
etval     none
*/
void nvic_configuration(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(TIMER2_IRQn, 1, 1);
}

TIM1輸出PWM初始化

PWM頻率計(jì)算如下所示。

在這里插入圖片描述

void timer1_config(void)
{
    /* -----------------------------------------------------------------------
    TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
    TIMER1CLK = SystemCoreClock / 120 = 1MHz

    TIMER1 channel0 duty cycle = (4000/ 16000)* 100  = 25%
    TIMER1 channel1 duty cycle = (8000/ 16000)* 100  = 50%
    TIMER1 channel2 duty cycle = (12000/ 16000)* 100 = 75%
    ----------------------------------------------------------------------- */
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER1);

    timer_deinit(TIMER1);

    /* TIMER1 configuration */
    timer_initpara.prescaler         = 119;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 1000;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER1,&timer_initpara);

    /* CH0,CH1 and CH2 configuration in PWM mode */
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
    timer_channel_output_config(TIMER1,TIMER_CH_3,&timer_ocintpara);

    /* CH3 configuration in PWM mode0,duty cycle 50% */
    timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_3,500);
    timer_channel_output_mode_config(TIMER1,TIMER_CH_3,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER1,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER1);
    /* auto-reload preload enable */
    timer_enable(TIMER1);
}

TIM2輸入捕獲設(shè)置

void timer2_config(void)
{
    /* TIMER2 configuration: input capture mode -------------------
    the external signal is connected to TIMER2 CH0 pin (PB4)
    the rising edge is used as active edge
    the TIMER2 CH0CV is used to compute the frequency value
    ------------------------------------------------------------ */
    timer_ic_parameter_struct timer_icinitpara;
    timer_parameter_struct timer_initpara;
        //開啟定時(shí)器時(shí)鐘
    rcu_periph_clock_enable(RCU_TIMER2);

    timer_deinit(TIMER2);

    /* TIMER2 configuration */
    timer_initpara.prescaler         = 120-1;//定時(shí)器的時(shí)鐘頻率是120MHz,預(yù)分頻120-1
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;//對(duì)齊模式
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;//向上計(jì)數(shù)
    timer_initpara.period            = 65535;//重載值
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;//不分頻
    timer_initpara.repetitioncounter = 0;//重復(fù)計(jì)數(shù)
    timer_init(TIMER2,&timer_initpara);

    /* TIMER2  configuration */
    /* TIMER2 CH0 input capture configuration */
    timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;//捕獲極性,上升沿捕獲
    timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;//通道輸入模式選擇
    timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;//分頻
    timer_icinitpara.icfilter    = 0x0;//濾波
    timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER2);//自動(dòng)重載使能
    /* clear channel 0 interrupt bit */
    timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH0);//CH0 通道中斷清除
    /* channel 0 interrupt enable */
    timer_interrupt_enable(TIMER2,TIMER_INT_CH0);//CH0 通道中斷使能

    /* TIMER2 counter enable */
    timer_enable(TIMER2);
}

中斷

#define IR_IN1  gpio_input_bit_get (GPIOA, GPIO_PIN_6)
uint8_t time_up_flag=0;//上升沿標(biāo)志位
uint8_t time_dowm_flag=0;//下降沿標(biāo)志位

uint32_t time_up_num=0;//上升沿計(jì)數(shù)
uint32_t time_dowm_num=0;//下降沿計(jì)數(shù)
float time_frequency;//頻率
float time_duty;//占空比


void TIMER2_IRQHandler(void)
{
            timer_ic_parameter_struct timer_icinitpara;
    timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
    timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
    timer_icinitpara.icfilter    = 0x0;        
 if(SET == timer_interrupt_flag_get(TIMER2,TIMER_INT_FLAG_CH0)){
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH0);        

        if(IR_IN1&&time_up_flag==0)//第一次上升
        {
            time_up_flag=1;
            timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING;  //設(shè)置為下降沿
            timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);    
            timer_counter_value_config(TIMER2 , 0); // 計(jì)數(shù)清零,從頭開始計(jì)

        }
        else if(IR_IN1==0&&time_dowm_flag==0)//下降
        {

            time_dowm_num = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_0)+1; // 讀取捕獲計(jì)數(shù),這個(gè)時(shí)間即為上升沿持續(xù)的時(shí)間
            timer_icinitpara.icpolarity = TIMER_IC_POLARITY_RISING;  //設(shè)置為上升沿
            timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);    
            time_dowm_flag=1;
        }        
        else if(IR_IN1&&time_dowm_flag==1)//第二次之后上升
        {        
            time_up_num = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_0)+1;; // 讀取捕獲計(jì)數(shù),這個(gè)時(shí)間即為上升沿持續(xù)的時(shí)間
                timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING;  //設(shè)置為下降沿
                timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);
            time_dowm_flag=0;
            timer_counter_value_config(TIMER2 , 0); // 計(jì)數(shù)清零,從頭開始計(jì)

        }



}

初始化

gpio_configuration(); 
    nvic_configuration();
    timer1_config();
    timer2_config();

主程序

while (1)
    {            
        time_frequency=1000000/time_up_num;//頻率
        time_duty = (float)time_dowm_num/(float)time_up_num;//占空比    
        printf("
time_frequency=%.2f,time_duty=%.2f",time_frequency,time_duty*100)    ;        
        delay_1ms(1000);                            
    }

測(cè)試結(jié)果

當(dāng)輸出1k頻率,50%正占空比。

在這里插入圖片描述

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • PWM
    PWM
    +關(guān)注

    關(guān)注

    114

    文章

    5118

    瀏覽量

    213157
  • 定時(shí)器
    +關(guān)注

    關(guān)注

    23

    文章

    3231

    瀏覽量

    114325
  • Tim
    Tim
    +關(guān)注

    關(guān)注

    0

    文章

    81

    瀏覽量

    17856
  • 固件庫(kù)
    +關(guān)注

    關(guān)注

    2

    文章

    97

    瀏覽量

    14918
  • gd32f303
    +關(guān)注

    關(guān)注

    4

    文章

    38

    瀏覽量

    3668
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    GD32F303固件庫(kù)開發(fā)(14)----IIC之配置OLED

    本章配置GD32F303使用IIC進(jìn)行驅(qū)動(dòng)SSD1306的12864OLED。
    的頭像 發(fā)表于 07-26 08:55 ?3515次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫(kù)</b><b class='flag-5'>開發(fā)</b>(14)----IIC之配置OLED

    GD32F303】星空派介紹

    GD32官方資料的基礎(chǔ)上,提供GD32F303的庫(kù)函數(shù)開發(fā)資料、例程講解、視頻課程等。同時(shí)還提供RT-Thread相關(guān)的驅(qū)動(dòng)開發(fā)、應(yīng)用開發(fā)、
    發(fā)表于 09-11 17:55

    關(guān)于GD32F303PWM輸入捕獲精度問題

    有大佬測(cè)過GD32F303最高能對(duì)多高頻率PWM進(jìn)行捕獲嗎?最近做的PWM輸入捕獲,對(duì)周期為1
    發(fā)表于 10-26 09:54

    gd32f303外部晶振使用25M,會(huì)對(duì)rt thread中的定時(shí)器精度造成影響嗎?

    大家好因?yàn)轫?xiàng)目需要gd32f303外部晶振使用25M,不知道會(huì)不會(huì)對(duì)rt thread中的定時(shí)器精度造成影響?如果造成影響應(yīng)該如何解決?大家好,咨詢個(gè)問題,因?yàn)楣δ苄枰?b class='flag-5'>gd32f303芯片外部晶振
    發(fā)表于 06-14 09:40

    GD32F30x系列固件庫(kù)

    GD32F30x系列固件庫(kù)包含GD32F303、GD32F305、GD32F307三個(gè)系列的最新
    發(fā)表于 08-21 09:00 ?165次下載

    stm32定時(shí)器輸入捕獲

    不同頻率、不同占空比的方波信號(hào)、PWM信號(hào),同時(shí)做為輸入捕獲功能時(shí),可以測(cè)量脈沖寬度、實(shí)現(xiàn)電容按鍵檢測(cè)等等。 一、輸入
    發(fā)表于 10-13 09:13 ?2.4w次閱讀
    stm32<b class='flag-5'>定時(shí)器</b>輸入<b class='flag-5'>捕獲</b>

    關(guān)于定時(shí)器輸出的PWM頻率范圍及占空比精度

    定時(shí)器輸出的PWM頻率范圍及占空比精度
    的頭像 發(fā)表于 03-12 10:37 ?1.3w次閱讀

    GD32F303固件庫(kù)開發(fā)(3)----使用固件庫(kù)點(diǎn)亮LED

    概述 在GD的官網(wǎng)中有許多的DEMO文件,可以使用開發(fā)板的案例或者對(duì)應(yīng)的MCU標(biāo)準(zhǔn)固件庫(kù)。需要樣片的可以加群申請(qǐng):6_15061293。 下圖是GD
    的頭像 發(fā)表于 11-23 17:36 ?2806次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫(kù)</b><b class='flag-5'>開發(fā)</b>(3)----使用<b class='flag-5'>固件</b><b class='flag-5'>庫(kù)</b>點(diǎn)亮LED

    GD32F303固件庫(kù)開發(fā)(5)----GPIO輸出模式,速率測(cè)試、開漏和輸出說明

    以STM32CUBEMX創(chuàng)建STM32F103工程,同時(shí)移植在GD32F303中,同時(shí)通過GD32303C_START開發(fā)板內(nèi)進(jìn)行驗(yàn)證。
    的頭像 發(fā)表于 11-25 15:32 ?3089次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫(kù)</b><b class='flag-5'>開發(fā)</b>(5)----GPIO輸出模式,速率測(cè)試、開漏和輸出說明

    STM32CUBEMX開發(fā)GD32F303(12)----輸出PWM及修改PWM頻率占空比

    本章STM32CUBEMX配置STM32F103,并且在GD32F303中進(jìn)行開發(fā),同時(shí)通過開發(fā)板內(nèi)進(jìn)行驗(yàn)證。 本章主要配置定時(shí)器輸出
    的頭像 發(fā)表于 11-30 14:40 ?3736次閱讀
    STM32CUBEMX<b class='flag-5'>開發(fā)</b><b class='flag-5'>GD32F303</b>(12)----輸出<b class='flag-5'>PWM</b>及修改<b class='flag-5'>PWM</b><b class='flag-5'>頻率</b>與<b class='flag-5'>占空比</b>

    GD32F303固件庫(kù)開發(fā)(12)----輸出PWM及修改PWM頻率占空比

    本章STM32CUBEMX配置STM32F103,并且在GD32F303中進(jìn)行開發(fā),同時(shí)通過開發(fā)板內(nèi)進(jìn)行驗(yàn)證。 本章主要配置定時(shí)器輸出
    的頭像 發(fā)表于 11-30 15:36 ?9132次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫(kù)</b><b class='flag-5'>開發(fā)</b>(12)----輸出<b class='flag-5'>PWM</b>及修改<b class='flag-5'>PWM</b><b class='flag-5'>頻率</b>與<b class='flag-5'>占空比</b>

    STM32CUBEMX開發(fā)GD32F30313)----定時(shí)器TIM捕獲PWM測(cè)量頻率占空比

    概述 本章STM32CUBEMX配置STM32F103,并且在GD32F303中進(jìn)行開發(fā),同時(shí)通過開發(fā)板內(nèi)進(jìn)行驗(yàn)證。 本章STM32CUBEMX配置STM32
    的頭像 發(fā)表于 12-07 10:15 ?3403次閱讀
    STM32CUBEMX<b class='flag-5'>開發(fā)</b><b class='flag-5'>GD32F303</b>(<b class='flag-5'>13</b>)----<b class='flag-5'>定時(shí)器</b><b class='flag-5'>TIM</b><b class='flag-5'>捕獲</b><b class='flag-5'>PWM</b><b class='flag-5'>測(cè)量</b><b class='flag-5'>頻率</b>與<b class='flag-5'>占空比</b>

    GD32F303固件庫(kù)開發(fā)(15)----外部中斷EXTI

    本章配置GD32F303使用EXTI進(jìn)行驅(qū)動(dòng)LED。
    的頭像 發(fā)表于 07-26 15:56 ?1387次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫(kù)</b><b class='flag-5'>開發(fā)</b>(15)----外部中斷EXTI

    GD32F303固件庫(kù)開發(fā)

    的可以加群申請(qǐng):615061293 。 GD32F303固件庫(kù)開發(fā)(1)----前期準(zhǔn)備與燒錄 使用GDLINK、jlink、串口下載程序到GD
    的頭像 發(fā)表于 07-27 09:27 ?1083次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫(kù)</b><b class='flag-5'>開發(fā)</b>

    GD32 MCU 移植教程】2、從 GD32F303 移植到 GD32F503

    GD32E503 系列是 GD 推出的 Cortex_M33 系列產(chǎn)品,該系列資源上與 GD32F303 兼容度非常高,本應(yīng)用筆記旨在幫助您快速將應(yīng)用程序從 GD32F303 系列微控
    的頭像 發(fā)表于 08-31 09:36 ?1306次閱讀
    【<b class='flag-5'>GD</b>32 MCU 移植教程】2、從 <b class='flag-5'>GD32F303</b> 移植到 <b class='flag-5'>GD32F</b>503