GD32F303固件库开发.13----定时器TIM捕获PWM测量频率与占空比

  • 概述
  • 视频教学
  • csdn课程
  • 样品申请
  • 生成例程
  • keil配置
  • 使能串口
  • 串口重定向
  • 占空比与频率计算
  • GPIO初始化
  • 开启中断
  • TIM1输出PWM初始化
  • TIM2输入捕获设置
  • 中断
  • 初始化
  • 主程序
  • 测试结果

概述

本章配置GD32F303输出PWM,同时使用TIM测量PWM频率和正占空比。
查阅手册可以得知,PB11为定时器1的通道3,让其输出PWM,PA6为定时器2的通道0,让作为TIM定时器输入。
需要GD样片的可以加群申请:615061293 。

视频教学

https://www.bilibili.com/video/BV1tg411m7pb/

GD32F303固件库开发(13)----定时器TIM捕获PWM测量频率与占空比

csdn课程

课程更加详细。
https://download.csdn.net/course/detail/37144

样品申请

https://www.wjx.top/vm/wFGhGPF.aspx#

生成例程

这里准备了自己绘制的开发板进行验证。

管脚图如下所示。


keil配置

microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,如果要使用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);//重置串口0usart_baudrate_set(USART0, 115200U);//设置串口0的波特率为115200usart_word_length_set(USART0, USART_WL_8BIT);         // 帧数据字长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);//使能发送器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,此时就知道正占空比时间,当在产生上升沿时候,就可以计算出周期使用的时间。

GPIO初始化

/*!\brief      configure the GPIO ports\param[in]  none\param[out] none\retval     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-CH3gpio_pin_remap_config(GPIO_TIMER1_PARTIAL_REMAP1, ENABLE);gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_11);
}

开启中断

/*!\brief      configure the nested vectored interrupt controller\param[in]  none\param[out] none\retval     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 = 1MHzTIMER1 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 edgethe 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-1timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;//对齐模式timer_initpara.counterdirection  = TIMER_COUNTER_UP;//向上计数timer_initpara.period            = 65535;//重载值timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;//不分频timer_initpara.repetitioncounter = 0;//重复计数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;//上升沿计数
uint32_t time_dowm_num=0;//下降沿计数
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); // 计数清零,从头开始计}else if(IR_IN1==0&&time_dowm_flag==0)//下降{time_dowm_num = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_0)+1; // 读取捕获计数,这个时间即为上升沿持续的时间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;; // 读取捕获计数,这个时间即为上升沿持续的时间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); // 计数清零,从头开始计}}

初始化

    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("\ntime_frequency=%.2f,time_duty=%.2f",time_frequency,time_duty*100)  ;        delay_1ms(1000);                         }

测试结果

当输出1k频率,50%正占空比。

GD32F303固件库开发(13)----定时器TIM捕获PWM测量频率与占空比相关推荐

  1. GD32F303固件库开发

    GD32F303固件库开发 芯片申请 GD32F303固件库开发(1)----前期准备与烧录 GD32F303固件库开发(2)----读保护与写保护 GD32F303固件库开发(3)----使用固件库 ...

  2. GD32F303固件库开发(14)----IIC之配置OLED

    GD32F303固件库开发.13----定时器TIM捕获PWM测量频率与占空比 概述 视频教学 csdn课程 参考文档 时钟使能 初始化IO IIC初始化 配置IIC接口 修改IIC发送代码 OLED ...

  3. GD32F303固件库开发(16)----移植兆易创新SPI Nor Flash之GD25Q64Flash

    spi概述 SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的 ...

  4. GD32F303固件库开发(7)----printf打印配置

    GD32F303固件库开发.7----printf打印配置 概述 视频教学 csdn课程 样品申请 硬件准备 keil配置 串口初始化 最后 串口重定向 打印测试 测试结果 概述 本章主要配置prin ...

  5. GD32F303固件库开发(5)----GPIO输出模式,速率测试、开漏和输出说明

    GD32F303固件库开发.5----GPIO输出模式,速率测试.开漏和输出说明 概述 样品申请 视频教学 csdn课程 硬件准备 开发板管脚配置 不同速率对应的波形 GPIO_OSPEED_2MHZ ...

  6. GD32F303固件库开发(10)----双ADC轮询模式扫描多个通道

    GD32F303固件库开发.10----双ADC轮询模式扫描多个通道 概述 视频教学 csdn课程 样品申请 硬件准备 keil配置 使能串口 串口重定向 ADC通道设置 ADC0初始化 ADC0配置 ...

  7. GD32F303固件库开发(11)----ADC在DMA模式下扫描多个通道

    GD32F303固件库开发.11----双ADC轮询模式扫描多个通道 概述 视频教学 csdn课程 样品申请 硬件准备 keil配置 使能串口 串口重定向 ADC通道设置 DMA设置 ADC0初始化 ...

  8. GD32F303固件库开发(17)----内部Flash读写

    概述 本例程主要讲解如何对芯片自带Flash进行读写,用芯片内部Flash可以对一些需要断电保存的数据进行保存,无需加外部得存储芯片,本例程采用的是GD32F303ZET6主控,512K大小的Flas ...

  9. 【致敬未来的攻城狮计划】第2期定向赠书《RT-Thread设备驱动开发指南》+ 《GD32 MCU原理及固件库开发指南》

    开启攻城狮的成长之旅!这是我参与的由 CSDN博客专家 架构师李肯(超链接:http://yyds.recan-li.cn)和 瑞萨MCU (超链接:瑞萨电子 (Renesas Electronics ...

最新文章

  1. linux java maven_Linux——java+tomcat+maven 安装
  2. Oracle的使用和Oracle安装过程
  3. MySQL 索引与优化
  4. mqttnet 详解_MQTTnet 3.0.5学习笔记
  5. EJB与JAVA BEAN_J2EE的异步消息机制
  6. laravel路由无法访问,报404,No query results for model [App\Models\...]
  7. java indexof int_Java Stack indexOf(Object, int)用法及代码示例
  8. 面试官,你考我那么多基础知识干什么?
  9. 苹果官网区号怎么填?
  10. Training a classifier
  11. C# 4.0中对Office编程的预览和对可选参数的体验
  12. Windows下JDK开发环境搭建及环境变量配置
  13. 大数据学习入门难,中科天玑给初学者支几招
  14. 云知声-AI离线语音识别芯片模块系列方案介绍
  15. 瓜大NPUCTF-Misc、Crypto Write Up
  16. 【聚英云农】无线节水灌溉系统应用智慧农业
  17. 动态创建style标签样式
  18. 编程初学者快速上手实战套路
  19. 新电脑自带的office密钥在哪里?
  20. 大数据哪个省才是高考地狱_是一名数据科学家,确实是地狱附近最性感的工作...

热门文章

  1. 移动WEB开发之flex伸缩布局
  2. 操作系统:进程的基本状态及其转换
  3. 大数据助力农牧业转型升级
  4. PR —— 轨道操作(锁定、解锁、可见、不可见、恢复误删除音视频)
  5. 轻松玩转ConstraintLayout(二)示例篇
  6. 计算机学院学生会招新宣传语,学生会招新宣传语(3篇)
  7. vs2015编写python爬虫_使用Python抓取网页数据(一)
  8. 【深入kotlin】 - 范型
  9. excel自定公式的自动计算
  10. 如何偷窃局域网其它电脑文件_偷窃工作