掌上实验室V8系列教程(四)定时器PWM输出
1 项目功能
三色RGB LED 通过PWM 调色
2 电路原理
我们可以通过3路PWM波分别调整RGB三个二极管的亮度,即调整RGB的比例,合成不同的颜色。
PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%。
当PA1输出“0”时,红色LED(R)亮;PA1输出“1”,红色LED灭。也就是说上述电路是低电平有效,上图的PWM波形周期为4ms,占空比为 3/4*100% = 75%。如果PA1输出占空比为75%的PWM波(低电平有效),红色LED的亮度就是最大亮度的75%。对于绿色LED(G)和蓝色LED(B),依次类推。
3 定时器功能
通用定时器 TMR2 包含一个支持向上、向下、双向计数的 16 位计数器、4 个捕获/比较寄存器、
4 组独立的通道。可实现输入捕获、可编程 PWM 输出。
TMR2 计数时钟可从内部时钟(CK_INT)、外部时钟(外部时钟模式 A、B)、内部触发输入(ISx)这些时钟源提供。
TMR 的输出部分由比较器和输出控制构成,用于编程输出信号的周期、占空比、极性,如下图所示。
配置 CxC[2:0]≠2’b00 将通道配置为输出可实现多种输出模式,此时,计数器计数值将与通道寄存器(TMRx_CxDT)值比较,并根据 CxOCTRL[2:0]位配置的输出模式,产生中间信号 CxORAW,再经过输出控制逻辑处理后输送到 IO。输出信号的周期由周期寄存器(TMRx_PR)值配置,占空比则由通道寄存器(TMRx_CxDT)值配置。TMR2有PWM、强制输出模式、输出比较模式、单周期模式和快速输出模式几种。本例中用到的是PWM模式。
PWM 模式:CxOCTRL=3’b110/111 时,开启 PWM 模式,每个通道可独立配置并输出
一路 PWM 信号。此时,输出信号的周期由 TMRx_PR 配置,占空比由 CxDT 值配置,计数
器值与通道寄存器(TMRx_CxDT)值进行比较,根据计数方向输出指定电平信号,关于 PWM
模式 A/B 详见 CxOCTRL[2:0]位描述。当计数模式为双向计数时,可根据 OWCDIR 位指示
计数方向。下图是向上计数下PWM模式A的例子
PR值是32,所以周期是33(0~32),通道寄存器值CxDT的值是3,所以计数3次之后C1ORAW翻转,引起输出引脚IO翻转。
TMR2最多可以输出4通道PWM,本例中采用了其中的三个通道(ch2,ch3,ch4)。
4 程序设计
4.1 驱动包选择
首先驱动包的选择如下图,本例用到的有crm、gpio、misc和tmr。
4.2 GPIO配置
PA2、PA3、PA4主功能是GPIO,需要把他们配置成多工功能。
void gpio_pins_init(void)
{crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);gpio_init_type gpio_init_struct;gpio_default_para_init(&gpio_init_struct);gpio_init_struct.gpio_pins = GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3;gpio_init_struct.gpio_mode = GPIO_MODE_MUX;gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init(GPIOA, &gpio_init_struct);
}
4.3 TMR2配置
定时器2共有四路输出,掌上实验室V8采用了TMR2的三个通道Ch2、Ch3、Ch4输出连接三色LED的RGB引脚。根据电路图可以看出,MCU输出低的时候,对应的LED会亮,所以PWM极性应该设置成低有效。
void tmr2_pwm_init(void)
{uint16_t tmr_pr = 254;uint16_t ccr2_val = 123;uint16_t ccr3_val = 123;uint16_t ccr4_val = 123;uint16_t prescaler_value = 0;crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);tmr_output_config_type tmr_oc_init_structure;prescaler_value = 0;/* tmr3 time base configuration */tmr_base_init(TMR2, tmr_pr, prescaler_value);tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);tmr_output_default_para_init(&tmr_oc_init_structure);tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;tmr_oc_init_structure.oc_idle_state = FALSE;tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;tmr_oc_init_structure.oc_output_state = TRUE;tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, ccr2_val);tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_2, TRUE);tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_3, ccr3_val);tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_3, TRUE);tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_4, ccr4_val);tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_4, TRUE);tmr_period_buffer_enable(TMR2, TRUE);/* tmr enable counter */tmr_counter_enable(TMR2, TRUE);
}
这里pr=255,所以周期是255+1=256个时钟周期。ccr2_val,ccr3_val,ccr4_val分别对应RGB的值,可以在0~255之间选择。
PWM周期对于本例不重要,所以没有做特别的计算。如果需要准确设置PWM周期,可以通过下列公式计算:
T = 1/fclk * (prescaler_value+1) * (tmr_pr+1)
fclk的计算可以参考:掌上实验室V8系列教程(五)定时器中断及应用
5 完整示例代码
#include "at32f403a_407_conf.h"void gpio_pins_init(void)
{crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);gpio_init_type gpio_init_struct;gpio_default_para_init(&gpio_init_struct);gpio_init_struct.gpio_pins = GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3;gpio_init_struct.gpio_mode = GPIO_MODE_MUX;gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init(GPIOA, &gpio_init_struct);
}void tmr2_pwm_init(void)
{uint16_t tmr_pr = 255;uint16_t ccr2_val = 255;uint16_t ccr3_val = 0;uint16_t ccr4_val = 0;uint16_t prescaler_value = 0;crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);tmr_output_config_type tmr_oc_init_structure;prescaler_value = 0;/* tmr3 time base configuration */tmr_base_init(TMR2, tmr_pr, prescaler_value);tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);tmr_output_default_para_init(&tmr_oc_init_structure);tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;tmr_oc_init_structure.oc_idle_state = FALSE;tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;tmr_oc_init_structure.oc_output_state = TRUE;tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, ccr2_val);tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_2, TRUE);tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_3, ccr3_val);tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_3, TRUE);tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_4, ccr4_val);tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_4, TRUE);tmr_period_buffer_enable(TMR2, TRUE);/* tmr enable counter */tmr_counter_enable(TMR2, TRUE);
}void delay_us(int us)
{SysTick->LOAD = us * system_core_clock/1000000; SysTick->VAL = 0;SysTick->CTRL = 0x5; //Systick采用系统时钟为时钟源,并启动while((SysTick->CTRL & (1<<16))==0);SysTick->CTRL = 0; //停止Systick
}void delay_ms(int ms)
{for(;ms>0;ms--)delay_us(1000);
}int main(void)
{gpio_pins_init();tmr2_pwm_init();for(;;){for(int r=0;r<255;r++){tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, r);delay_ms(10);}for(int g=0;g<255;g++){tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_3, g);delay_ms(10);}for(int b=0;b<255;b++){tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_4, b);delay_ms(10);}delay_ms(500);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, 0);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_3, 0);tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_4, 0);delay_ms(500);}
}
6 参考资源
《掌上实验室V8》 原理图
AT32F403A AT32F407 固件库2.0.2 应用说明
掌上实验室V8系列教程(四)定时器PWM输出相关推荐
- 掌上实验室V8系列教程(八)ADC模数转换
目录 1 项目功能 2 ADC工作原理 3 电路原理图 4 AT32 ADC应用 4.1 ADC基础操作流程 4.2 ADC触发 4.3 ADC采样和转换时间 4.4 读取ADC转换结果 5 示例程序 ...
- 掌上实验室V8系列教程(二)跑马灯
目录 1 项目功能 2 电路原理 3 软件流程 4 程序设计 5.参考资源 1 项目功能 循环点亮LED4, LED5, LED6, LED7 2 电路原理 根据硬件电路图,PC0输出"0& ...
- 掌上实验室V8系列教程(九)光电编码器转速测量
1 项目功能 通过光电编码器进行转速测量 2 光电编码器工作原理 光电编码器,是一种通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器.这是应用最多的传感器,光电编码器是由光源.光码盘和 ...
- 掌上实验室V8系列教程(七)I2C应用 HP203B
目录 1 项目功能 2 电路原理图 3 传感器HP203B 3.1 HP203B功能 3.2 HP203B技术指标 3.3 HP203B I2C总线接口命令 4 示例代码 1 项目功能 通过HB203 ...
- 掌上实验室V8系列教程(三)数码管动态显示
目录 1 项目功能 2 电路原理 3 动态显示原理 4 示例代码 6 扩展功能 7 参考资源 1 项目功能 4位数码管动态显示 2 电路原理 3 动态显示原理 一位八段式数码管内部有8个LED,习惯上 ...
- 掌上实验室V8系列教程(五)定时器中断及应用
1 项目目标 利用定时器产生周期为1ms的中断,作为系统时基.并在数码管上显示开机时间(分辨率为0.1秒):同时实现LED4.LED5.LED6和LED7分别以300ms.220ms.450ms和70 ...
- 基于雅特力AT32的 《掌上实验室》V8
1 项目介绍 掌上实验室V8是由中国计量大学现代科技学院和雅特力共同研发的一款ARM学习板,内置AT-Link-Ez仿真器. 主MCU采用雅特力AT32F407VGT7. 板上资源: 1.通信接口 1 ...
- 毕业设计-基于微信小程序的“掌上实验室” 安全教育与管理系统
目录 前言 课题背景与简介 实现设计思路 一."掌上实验室"安全教育与管理 平台功能架构 二."掌上实验室"的功能设计 三."掌上实验室"的 ...
- 史上最详细的Android Studio系列教程四--Gradle基础
史上最详细的Android Studio系列教程四--Gradle基础 转载于:https://www.cnblogs.com/zhujiabin/p/5125917.html
最新文章
- 帮我看看这个是什么意思 c++代码
- python 画风场 scipy_科学网-Python: 扩展库SciPy-刘洋洋的博文
- android 数据存储怎么保存图片_文章要保存为TXT文件,其中的图片要怎么办?Python帮你解决...
- 原型设计工具【收集转帖】
- 云笔记项目-过滤器与拦截器学习
- MySQL中的UNIX_TIMESTAMP函数使用总结
- Java最大公约数和最小公倍数的求法(辗转相除法)
- ajax静态加载图片,JQuery实现Ajax加载图片的方法
- Kotlin - 100%兼容java和android开发
- JVM Java内存区域 与 内存溢出 (系列号1)
- OpenCV调整图像的亮度
- Windows 8 Directx 开发学习笔记(五)山峰河谷模型的简单实现
- 图:[PPT双屏技术-知识竞赛方案策划]华中师范大学-城市与环境科学学院-城环学院地理知识竞赛胜利闭幕.
- Maven-Eclipse使用maven创建HelloWorld Java项目,maven常用的命令解析
- (一)Activiti 数据库25张表——一般数据2 (ACT_GE_PROPERTY)
- 2021011029王芯悦-实验1
- python爬取胡歌相关视频弹幕,分析并制作词云
- android 打开相机拍照功能吗,Android调用相机实现拍照功能
- ZXing生成二维码,条码,logo二维码
- 面试题目总结(CNN)
热门文章
- 如何在黑客马拉松中生存
- 苹果电脑全系换上自研芯片,除了不能打电话,比iPhone 12亮眼多了
- NovAtel GPS常用设置方法及注意事项
- 使用WTSGetActiveConsoleSessionId()的VISTA服务与桌面交互
- Scratch3.0——助力新进程序员理解程序(难度案例一、节奏大师)
- Dameware问题汇总
- 打印very good答案
- D3D渲染技术之混合案例
- 湖南省计算机专业职称,[湖南省人力资源和社会保障厅]关于调整全国专业技术人员计算机应用能力考试科目(模块)有关问题的通知湘人社函[2014]273号...
- 全国专业计算机应用能力,全国专业技术人员计算机应用能力考试「介绍」