小熊派gd32f303学习之旅(7)—使用PWM实现LED呼吸灯
小熊派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呼吸灯相关推荐
- 小熊派gd32f303学习之旅(4)—使用DMA实现串口打印
小熊派gd32f303学习之旅(4)-使用DMA实现串口打印 一.前言 在上一篇文章(串口打印第一个Hello world程序)我们使用重定义fputc函数的方式实现了串口打印,但是这种方式本质上是在 ...
- 小熊派gd32f303学习之旅(3)—串口打印第一个Hello world程序
小熊派gd32f303学习之旅(3)-串口打印第一个Hello world程序 一.硬件连接 通过查看原理图我们可以看到,当[UART通信选择开关]拨向[AT-MCU]时,USB虚拟串口连接到MCU的 ...
- GD32F303的PWM实现LED呼吸灯的方法
GD32F303的PWM实现LED呼吸灯的方法 首先配置TIMER1,定义初始化结构体变量 static void ConfigTIMER1ForPWMPB10(unsigned short arr, ...
- 启明智显分享| ESP32学习笔记参考--PWM(脉冲宽度调制) 篇,配PWM控制 LED呼吸灯代码示例参考
提示:启明智显专为智能产品提供一站式彩屏显示+连接+云端服务+APP软件开发.维护等解决方案,帮厂商快速实现硬件的智能化.作为启明云端旗下方案公司,我们用心整理了开发小伙伴在开发过程中可能会遇到的问题 ...
- 嵌入式学习——使用定时器输出PWM波形,实现 LED呼吸灯的效果
嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 目录 嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 1. 任务要求 2 PWM波介绍, 2.1 什么是PWM(Pu ...
- android8 通知呼吸灯_android学习笔记----解决兼容8.0以上和8.0之前版本通知栏显示、振动、LED呼吸灯闪烁问题(真机验证)...
Android 8.0系统的通知栏适配文章讲解(郭霖大神的): 然后开始试验了: 模拟器: 真机(华为荣耀V9,8.0系统),下拉横幅需要手动打开,除非是厂家白名单,比如QQ.微信 我在oppo手机6 ...
- 嵌入式学习--使用定时器输出PWM波形,实现LED呼吸灯的效果
目录 1.任务要求 2.PWM介绍 关于PWM的定义 分频-计数时钟 计数器 定时器输出PWM的原理 定时器的初始化 3.配置STM32CubeMX 4.keil5的代码 5.运行结果 6.心得与体会 ...
- 【STM32学习笔记-LED呼吸灯】
STM32学习笔记-点亮LED灯 文章目录 STM32学习笔记-点亮LED灯 一.呼吸灯原理 二.呼吸灯代码 1.main.c 2.led.c 3.led.h 三.代码分析 一.呼吸灯原理 占空比:占 ...
- 小豆包的学习之旅:里程计运动模型
星球大战里面有2个非常出色的机器人一个是3PO,一个是R2.我的机器人呢就叫小豆包啦,代号FR2,不许侵犯它的署名哦. 常见的机器人运动模型包括:速度计运动模型,里程计运动模型和惯导运动模型.概率运动 ...
最新文章
- Vue以CDN方式调用Swiper轮播异常
- Solr安装并导入mysql数据
- debug工具_Jupyter官方神器:可视化 Debug 工具!
- MAVEN约定的目录结构
- 【转】SSM框架搭建流程与解析
- JUC锁-CountDownLatch(六)
- mysql中使用concat例子
- echo显示文字后不换行(sep /p 和 echo 命令的一些细节)
- hadoop 操作(二)
- WPF中ToolTip的自定义
- winform打包应用程序-setup安装包
- 化工行业ERP管理系统丨外贸软件
- MetroMusic音乐播放器开发心得
- java 虚函数表_虚函数表(vtable/virtual table/virtual method table)
- 视频画中画制作,一款简单好上手的软件
- python3中import time是什么意思_python3_time模块详解
- squeeze 、unsequeeze
- ubuntu Linux 终端的一些快捷键
- windows用Redis Desktop Manager无法通过6379端口连接ubuntu redis问题
- 如何再UOS/Ubuntu中创使用ufw设置防火墙
热门文章
- .net5 的Centos7 Docker容器构建
- SciPy中的optimize.minimize实现受限优化问题
- 在校大学生用Python当爬虫一个月能赚3000吗?
- python 判断当前系统是linux还是windows
- vasp phonopy消除虚频个人经验总结
- Oracle中对查询条件进行按拼音/笔画/部首order by排序
- 模型预测控制(MPC)解析(三):多输入多输出系统
- 【HTML】HTML网页设计---模仿化妆品官网
- python肖像画_U2NET人物肖像画模拟
- 代码随想录_二叉树_leetcode236