概述
本章配置GD32F303輸出PWM,同時使用TIM測量PWM頻率和正占空比。 查閱手冊可以得知,PB11為定時器1的通道3,讓其輸出PWM,PA6為定時器2的通道0,讓作為TIM定時器輸入。 需要GD樣片的可以加群申請:615061293 。
生成例程
這里準備了自己繪制的開發(fā)板進行驗證。
管腳圖如下所示。
keil配置
microlib 進行了高度優(yōu)化以使代碼變得很小。 它的功能比缺省 C 庫少,并且根本不具備某些 ISO C 特性。 某些庫函數(shù)的運行速度也比較慢,如果要使用printf(),必須開啟。
使能串口
/* 使能GPI0A,用PA9、PA10為串口 */
rcu_periph_clock_enable(RCU_GPIOA);
/*使能串口0的時鐘 */
rcu_periph_clock_enable(RCU_USART0);
/*配置USARTx_Tx(PA9)為復用推挽輸出*/
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);//設置串口0的波特率為115200
usart_word_length_set(USART0, USART_WL_8BIT); // 幀數(shù)據(jù)字長
usart_stop_bit_set(USART0, USART_STB_1BIT); // 停止位1位
usart_parity_config(USART0, USART_PM_NONE); // 無奇偶校驗位
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進行打印。
占空比與頻率計算
占空比=(t1-t0)/(t2-t0) 頻率=(t2-t0)/時鐘頻率= =(t2-t0)/(120M/(psc+1))
周期需要2個上升沿去判斷,設定第一個上升沿time_flag由0->1,下降沿time_dowm_flag由0->1,此時就知道正占空比時間,當在產(chǎn)生上升沿時候,就可以計算出周期使用的時間。
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頻率計算如下所示。
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輸入捕獲設置
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;
//開啟定時器時鐘
rcu_periph_clock_enable(RCU_TIMER2);
timer_deinit(TIMER2);
/* TIMER2 configuration */
timer_initpara.prescaler = 120-1;//定時器的時鐘頻率是120MHz,預分頻120-1
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;//對齊模式
timer_initpara.counterdirection = TIMER_COUNTER_UP;//向上計數(shù)
timer_initpara.period = 65535;//重載值
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;//不分頻
timer_initpara.repetitioncounter = 0;//重復計數(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);//自動重載使能
/* 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;//上升沿標志位
uint8_t time_dowm_flag=0;//下降沿標志位
uint32_t time_up_num=0;//上升沿計數(shù)
uint32_t time_dowm_num=0;//下降沿計數(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; //設置為下降沿
timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);
timer_counter_value_config(TIMER2 , 0); // 計數(shù)清零,從頭開始計
}
else if(IR_IN1==0&&time_dowm_flag==0)//下降
{
time_dowm_num = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_0)+1; // 讀取捕獲計數(shù),這個時間即為上升沿持續(xù)的時間
timer_icinitpara.icpolarity = TIMER_IC_POLARITY_RISING; //設置為上升沿
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;; // 讀取捕獲計數(shù),這個時間即為上升沿持續(xù)的時間
timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING; //設置為下降沿
timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);
time_dowm_flag=0;
timer_counter_value_config(TIMER2 , 0); // 計數(shù)清零,從頭開始計
上一篇:關于GD32F350R8的家庭環(huán)境智能控制系統(tǒng)的介紹和應用
下一篇:【GD32F303紅楓派開發(fā)板使用手冊】第二十講 SPI-SPI NAND FLASH讀寫實驗
推薦閱讀最新更新時間:2025-07-01 09:08






設計資源 培訓 開發(fā)板 精華推薦
- FAN6224同步整流控制器正激續(xù)流整流典型應用
- LTC3621EMS8E-2 1.2Vout、同步至 600kHz、強制連續(xù)模式同步降壓型穩(wěn)壓器的典型應用
- MC34071ADR2G快速建立逆變器的典型應用
- LT3970EMS-3.3 5V 降壓轉(zhuǎn)換器的典型應用
- LT1171HVIT、2.5A 高效恒流充電器的典型應用
- 具有輕負載效率的 NCP5252 2.0 A、1.0 MHz 集成同步降壓穩(wěn)壓器的典型應用
- DC124,使用 LTC1416 高速 14 位、400Ksps 模數(shù)轉(zhuǎn)換器的演示板
- AD8618ARZ-REEL單電源緩沖DAC輸出運算放大器典型應用電路
- 使用 MaxLinear, Inc 的 SPX385AS-1.2/TR 的參考設計
- 使用 NXP Semiconductors 的 MC34SB0410AE 的參考設計
- 貿(mào)澤授權(quán)代理Texas Instruments 豐富多樣的產(chǎn)品
- 美國為何恢復英偉達H20對華銷售?白宮AI負責人回應
- Cadence 率先推出業(yè)內(nèi)首款 LPDDR6/5X 14.4Gbps 內(nèi)存 IP,為新一代 AI 基礎架構(gòu)助力
- 手把手教你從零設計一款算力超過 1000Tops 的智能駕駛芯片
- OrangeBox汽車連接域控制器(CDC)開發(fā)平臺
- 采用反激式轉(zhuǎn)換器進行高功率應用設計
- Vishay推出PLCC-6封裝RGB LED通過獨立控制紅色、綠色和藍色芯片實現(xiàn)寬色域
- 芯對話 | CBMG719單刀雙擲模擬開關:高精度信號切換低阻高速寬溫
- 大聯(lián)大詮鼎集團推出基于Qualcomm和Thundercomm產(chǎn)品的AI電子圍欄方案
- AMD:AI加速卡MI308將恢復出貨,許可證申請將被推進至審核流程