小熊派gd32f303学习之旅(7)—使用PWM实现LED呼吸灯

一、前言

通过查看gd32f30x的参考手册,可以知道gd32f303的通用定时器和高级定时器可以硬件生成PWM波,然后我们查看gd32f303xx的数据手册,可以看到,小熊派上连接LED的引脚PB0在定时器2的通道2上,这样我们就可以使用其PWM功能产生呼吸灯的效果。

二、初始化定时器

首先,编写定时器2的初始化函数,将其通道2设置为PWM模式0

/* 通用定时器2初始化PWM函数* 参数:  psr:时钟预分频系数,预分频值=psr+1arr:自动重装载值,计数次数=arr+1* 返回值:无   */
void timer2_pwm_init(uint32_t psr, uint32_t arr, uint32_t duty)
{/* 定义一个定时器初始化结构体 */timer_parameter_struct timer_init_struct;/* 定义一个定时器输出比较参数结构体*/timer_oc_parameter_struct timer_oc_init_struct;/* 开启定时器时钟 */rcu_periph_clock_enable(RCU_TIMER2);/* 开启GPIOB时钟 */rcu_periph_clock_enable(RCU_GPIOB);/* 开启复用功能时钟 */rcu_periph_clock_enable(RCU_AF);/* 初始化PB0(TIMER2 CH2)为复用功能 */gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);/* 初始化定时器 */timer_deinit(TIMER2);timer_init_struct.prescaler           = psr; /* 预分频系数 */timer_init_struct.period         = arr; /* 自动重装载值 */timer_init_struct.alignedmode       = TIMER_COUNTER_EDGE;  /* 计数器对齐模式,边沿对齐 */timer_init_struct.counterdirection = TIMER_COUNTER_UP;        /* 计数器计数方向,向上 */timer_init_struct.clockdivision      = TIMER_CKDIV_DIV1;        /* DTS时间分频值  */timer_init_struct.repetitioncounter = 0;                    /* 重复计数器的值(定时器2无效)*/timer_init(TIMER2, &timer_init_struct);/* PWM初始化 */timer_oc_init_struct.outputstate  = TIMER_CCX_ENABLE;     /* 通道使能 */timer_oc_init_struct.outputnstate = TIMER_CCXN_DISABLE;      /* 通道互补输出使能(定时器2无效) */timer_oc_init_struct.ocpolarity   = TIMER_OC_POLARITY_HIGH;    /* 通道极性 */timer_oc_init_struct.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;/* 互补通道极性(定时器2无效)*/timer_oc_init_struct.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;/* 通道空闲状态输出(定时器2无效)*/timer_oc_init_struct.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;/*互补通道空闲状态输出(定时器2无效) */timer_channel_output_config(TIMER2, TIMER_CH_2, &timer_oc_init_struct);/* 通道2占空比设置 */timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_2, duty);/* PWM模式0 */timer_channel_output_mode_config(TIMER2,TIMER_CH_2,TIMER_OC_MODE_PWM0);/* 不使用输出比较影子寄存器 */timer_channel_output_shadow_config(TIMER2,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);   /* 自动重装载影子比较器使能 */timer_auto_reload_shadow_enable(TIMER2);  /* 使能Timer2 */timer_enable(TIMER2);
}

三、编写mian函数

接下来编写main函数,使其实现呼吸灯的功能。如下所示,将PWM波的周期设置为1ms,可改变的占空比步长为1us,每隔3ms改变一次LED亮度,使其呈现0-500-0的循环,另外,在LED熄灭时等待300ms,可以得到更好的呼吸灯效果。

int main(void)
{uint8_t dir = 0;uint32_t pwmval = 300;/* 配置系统时钟 */systick_config();/* 初始化LED */// led_init();/* 初始化USART0 */uart0_init(115200);/* 初始化定时器5 */timer2_pwm_init(120-1, 1000-1, 300);/* 通过串口打印 Hello world! */u1_printf("Hello world! ");u1_printf("I am William. \r\n");TIMER_CH2CV(TIMER2) =  pwmval;while(1){if(dir) pwmval++;              // dir==1  pwmval递增else pwmval--;                 // dir==0  pwmval递减if( pwmval>500 ) dir=0;            // pwmval到达500后,方向为递减if( pwmval==0 ) dir=1;           // pwmval递减到0后,方向改为递增TIMER_CH2CV(TIMER2) =  pwmval;     // 修改比较值,修改占空比if( pwmval==0 ) delay_1ms(300);delay_1ms(3);}
}

四、功能验证

编译链接烧录到小熊派开发板,然后观察LED的情况,可以看到呼吸灯的效果

五、代码优化

现在,我们使用的是在while循环中完成的呼吸灯效果,但是这样,就很难让CPU去做其他的事了,所以,结合之前的定时器中断,将PWM波形的改变放到定时器中断中去。
首先,初始化定时器5为3ms产生中断

 /* 初始化定时器5,3ms */timer5_init(1200-1, 300-1);

然后修改定时器5 的中断服务函数如下

/* TIMER5 中断服务函数* 参数:无* 返回值:无  */
void TIMER5_IRQHandler(void)
{static uint8_t led_flag = 1, dir = 0;;static uint32_t pwmval = 300;if(timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP)){/* 清除TIMER5 中断标志位 */timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_UP);if(led_flag == 1){if(dir) pwmval++;                /* dir==1  pwmval递增               */else pwmval--;                    /* dir==0  pwmval递减               */if( pwmval>500 ) dir=0;           /* pwmval到达500后,方向为递减        */if( pwmval==0 ) dir=1;         /* pwmval递减到0后,方向改为递增    */TIMER_CH2CV(TIMER2) =  pwmval;   /* 修改比较值,修改占空比           */if( pwmval==0 ){led_flag = 0;timer_counter_value_config(TIMER5, 30000-1);  /* 设置为300ms */}}else{led_flag = 1;timer_counter_value_config(TIMER5, 300-1);   /* 设置为3ms */}}
}

编译链接烧录到小熊派开发板,然后观察LED的情况,可以得到一样的效果

六、附录

完整代码我存放在码云,可以查看:https://gitee.com/william_william/BearPi-GD32F303RGT6.git
上一篇:小熊派gd32f303学习之旅(6)—使用基本定时器实现LED闪烁
下一篇:小熊派gd32f303学习之旅(8)— 使用软件模拟I2C读写EEPROM

小熊派gd32f303学习之旅(7)—使用PWM实现LED呼吸灯相关推荐

  1. 小熊派gd32f303学习之旅(4)—使用DMA实现串口打印

    小熊派gd32f303学习之旅(4)-使用DMA实现串口打印 一.前言 在上一篇文章(串口打印第一个Hello world程序)我们使用重定义fputc函数的方式实现了串口打印,但是这种方式本质上是在 ...

  2. 小熊派gd32f303学习之旅(3)—串口打印第一个Hello world程序

    小熊派gd32f303学习之旅(3)-串口打印第一个Hello world程序 一.硬件连接 通过查看原理图我们可以看到,当[UART通信选择开关]拨向[AT-MCU]时,USB虚拟串口连接到MCU的 ...

  3. GD32F303的PWM实现LED呼吸灯的方法

    GD32F303的PWM实现LED呼吸灯的方法 首先配置TIMER1,定义初始化结构体变量 static void ConfigTIMER1ForPWMPB10(unsigned short arr, ...

  4. 启明智显分享| ESP32学习笔记参考--PWM(脉冲宽度调制) 篇,配PWM控制 LED呼吸灯代码示例参考

    提示:启明智显专为智能产品提供一站式彩屏显示+连接+云端服务+APP软件开发.维护等解决方案,帮厂商快速实现硬件的智能化.作为启明云端旗下方案公司,我们用心整理了开发小伙伴在开发过程中可能会遇到的问题 ...

  5. 嵌入式学习——使用定时器输出PWM波形,实现 LED呼吸灯的效果

    嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 目录 嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 1. 任务要求 2 PWM波介绍, 2.1 什么是PWM(Pu ...

  6. android8 通知呼吸灯_android学习笔记----解决兼容8.0以上和8.0之前版本通知栏显示、振动、LED呼吸灯闪烁问题(真机验证)...

    Android 8.0系统的通知栏适配文章讲解(郭霖大神的): 然后开始试验了: 模拟器: 真机(华为荣耀V9,8.0系统),下拉横幅需要手动打开,除非是厂家白名单,比如QQ.微信 我在oppo手机6 ...

  7. 嵌入式学习--使用定时器输出PWM波形,实现LED呼吸灯的效果

    目录 1.任务要求 2.PWM介绍 关于PWM的定义 分频-计数时钟 计数器 定时器输出PWM的原理 定时器的初始化 3.配置STM32CubeMX 4.keil5的代码 5.运行结果 6.心得与体会 ...

  8. 【STM32学习笔记-LED呼吸灯】

    STM32学习笔记-点亮LED灯 文章目录 STM32学习笔记-点亮LED灯 一.呼吸灯原理 二.呼吸灯代码 1.main.c 2.led.c 3.led.h 三.代码分析 一.呼吸灯原理 占空比:占 ...

  9. 小豆包的学习之旅:里程计运动模型

    星球大战里面有2个非常出色的机器人一个是3PO,一个是R2.我的机器人呢就叫小豆包啦,代号FR2,不许侵犯它的署名哦. 常见的机器人运动模型包括:速度计运动模型,里程计运动模型和惯导运动模型.概率运动 ...

最新文章

  1. Vue以CDN方式调用Swiper轮播异常
  2. Solr安装并导入mysql数据
  3. debug工具_Jupyter官方神器:可视化 Debug 工具!
  4. MAVEN约定的目录结构
  5. 【转】SSM框架搭建流程与解析
  6. JUC锁-CountDownLatch(六)
  7. mysql中使用concat例子
  8. echo显示文字后不换行(sep /p 和 echo 命令的一些细节)
  9. hadoop 操作(二)
  10. WPF中ToolTip的自定义
  11. winform打包应用程序-setup安装包
  12. 化工行业ERP管理系统丨外贸软件
  13. MetroMusic音乐播放器开发心得
  14. java 虚函数表_虚函数表(vtable/virtual table/virtual method table)
  15. 视频画中画制作,一款简单好上手的软件
  16. python3中import time是什么意思_python3_time模块详解
  17. squeeze 、unsequeeze
  18. ubuntu Linux 终端的一些快捷键
  19. windows用Redis Desktop Manager无法通过6379端口连接ubuntu redis问题
  20. 如何再UOS/Ubuntu中创使用ufw设置防火墙

热门文章

  1. .net5 的Centos7 Docker容器构建
  2. SciPy中的optimize.minimize实现受限优化问题
  3. 在校大学生用Python当爬虫一个月能赚3000吗?
  4. python 判断当前系统是linux还是windows
  5. vasp phonopy消除虚频个人经验总结
  6. Oracle中对查询条件进行按拼音/笔画/部首order by排序
  7. 模型预测控制(MPC)解析(三):多输入多输出系统
  8. 【HTML】HTML网页设计---模仿化妆品官网
  9. python肖像画_U2NET人物肖像画模拟
  10. 代码随想录_二叉树_leetcode236