STM32实战③RGB渐变
1 简介
- 本实验实现RGB灯的颜色渐变,从红慢慢过渡到绿,再慢慢过渡到蓝,再慢慢过渡到红。其原理是通过查表的方法给三个通道不同的pwm,从而改变颜色。
2 硬件
使用野火指南者开发板。
2.1 RGB
- RGB灯由红蓝绿三个小灯构成,使用PWM控制是可以混合成256种不同的颜色。STM32的三个引脚需要选择具有定时器输出通道功能,而不是任意的GPIO口。本次实验使用PB5、PB0及PB1引脚,分别是定时器TIM3的通道2,3,4。
- PB5对应红色R,PB0对应绿色G,PB1对应蓝色B。
3 软件设计
- 首先我们需要知道三个通道的值对应的颜色。例如,红色为(255,0,0),绿色为(0,255,0),蓝色为(0,0,255)。知道值对应的颜色就可以对RGB进行颜色的控制。
RGB颜色表查询网站:https://tool.oschina.net/commons?type=3
3.1 GPIO初始化
//初始化PB5和PE5为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* GPIO clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); /*IO设置*/GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); /* 配置LED灯用到的引脚 *///红GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//绿GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;GPIO_Init(GPIOB, &GPIO_InitStructure);//蓝GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;GPIO_Init(GPIOB, &GPIO_InitStructure);
}
- 由于本实验直接使用定时器输出通道的脉冲信号控制RGB灯,此处代码把GPIO相关的引脚都配置成了复用推挽输出模式。
- 由于红灯使用的引脚需要用到第二功能,本代码使用COLOR_GPIO_REMAP_FUN()进行了该引脚的功能重定义操作。
- 红灯为B5引脚,绿灯为B0引脚,蓝灯为B1引脚。
3.2 TIM3定时器初始化
void TIM3_Int_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能TIM_TimeBaseStructure.TIM_Period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500msTIM_TimeBaseStructure.TIM_Prescaler = psc-1; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位/* PWM模式配置 */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能输出TIM_OCInitStructure.TIM_Pulse = 0; //设置初始PWM脉冲宽度为0 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //当定时器计数值小于CCR_Val时为低电平//RGB通道TIM_OC2Init ( TIM3, &TIM_OCInitStructure ); TIM_OC2PreloadConfig ( TIM3, TIM_OCPreload_Enable ); //使能预装载 TIM_OC3Init ( TIM3, &TIM_OCInitStructure ); TIM_OC3PreloadConfig ( TIM3, TIM_OCPreload_Enable ); //使能预装载 TIM_OC4Init ( TIM3, &TIM_OCInitStructure ); TIM_OC4PreloadConfig ( TIM3, TIM_OCPreload_Enable ); //使能预装载 TIM_ARRPreloadConfig(TIM3, ENABLE);TIM_Cmd(TIM3, ENABLE); //使能TIMx外设TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
3.3 RGB渐变
uint16_t rgb_led_time=20;
const uint16_t R[] = {255, 226, 198, 170, 141, 113, 85, 56, 28, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 28, 56, 85, 113, 141, 170, 198, 226, 255
};
const uint16_t G[] = {0, 28, 56, 85, 113, 141, 170, 198, 226, 255,255, 226, 198, 170, 141, 113, 85, 56, 28, 0,0, 0, 0, 0, 0, 0, 0, 0, 0,0
};
const uint16_t B[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 28, 56, 85, 113, 141, 170, 198, 226, 255,255, 226, 198, 170, 141, 113, 85, 56, 28, 0
};
//定时器3中断服务程序
void TIM3_IRQHandler(void) //TIM3中断
{static uint16_t pwm_index = 0; //用于PWM查表static uint16_t amplitude_cnt = 0; //持续时间if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 {TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源 amplitude_cnt++;// 每个颜色持续的时间if(amplitude_cnt>rgb_led_time) { pwm_index++; //标志PWM表指向下一个元素//若PWM表已到达结尾,重新指向表头if( pwm_index > (30-1)) {pwm_index=0; }amplitude_cnt=0; //重置计数标志}else{ TIM3->CCR2 = R[pwm_index]; // PWMTIM3->CCR3 = G[pwm_index]; // PWMTIM3->CCR4 = B[pwm_index]; // PWM} }
}
- 要实现RGB灯渐变,需要通过在不同时刻给其三个通道不同的PWM值,从而产生不同的颜色。因此,我制定了一个含有30个元素的数组,分别为R[30],G[30],B[30]。每个时刻t的RGB灯的颜色为[R[t],G[t],B[t]],从而实现了RGB颜色从红慢慢过渡到绿,再慢慢过渡到蓝,再慢慢过渡到红。
- RGB渐变由于需要控制其渐变周期,所以我将其写在TIM3定时器中断中。
- 该算法的思路:假设设置定时器的周期为 t ms,R,G,B三张表拥有30个PWM数值,其每个数值会持续rgb_led_time个t,因此RGB循环一次的周期为T=(30 * rgb_led_time * t)/1000 s。若rgb_led_time=10,t=10ms,则RGB循环一次的周期为T=3s。
3.4 主函数
int main(void)
{ delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //LED端口初始化TIM3_Int_Init(1000,72); //不分频。PWM频率=72000000/72=1000Khz 1us*1000=1mswhile(1){} }
STM32实战③RGB渐变相关推荐
- STM32实战(1):搭建模板工程
" 从今天起我会更新一个STM32实战系列教程,以STM32F103RCT6核心板为例由浅至深的向大家介绍嵌入式软件开发的学习过程,计划是先从最基础的搭建工程开始,到裸机开发,再到各种中间件 ...
- STM32实战六 PWM加移相正交
这一章编写PWM程序,使用TIM3以两个通道,完全映射到PC6和PC7,除普通PWM输出外,增加移相正交PWM功能,为后面的编码器计数模式提供信号源. PWM.h #ifndef __PWM__ #d ...
- STM32实战总结:HAL之GUI
在TFT上简单的显示字符.数字.汉字.图形.图片等,都是一些简单的显示.如果想要进行较为复杂的显示,就推荐使用GUI. 市面上常见的嵌入式GUI有LVGL,emWin(ucGUI),TouchGFX, ...
- RGB渐变LED,实现停止在任意颜色
在发布的第一篇文章使用RGB共阳极LED,基于Arduino实现七彩渐变_默以思的博客-CSDN博客_arduino rgb灯渐变 中,讲解了可以连续变换的RGB灯光效果,实际上,从试着使LED间断变 ...
- 【STM32实战】机械臂快递分拣系统(二)——机械臂控制程序(上位机)编写
[STM32实战]机械臂快递分拣系统(二)--机械臂控制程序(上位机)编写 前言 题目分析 蓝牙模块的使用 上位机程序的编写 连接阿里云 测试 前言 近期回校上最后一门课,刚好是做机械臂有关的题目,所 ...
- 【STM32实战】机械臂快递分拣系统(一)——机械臂控制程序(下位机)编写
[STM32实战]机械臂快递分拣系统(一)--机械臂控制程序(下位机)编写 前言 题目分析 工程模板生成 蓝牙模块的使用 蓝牙接收数据解析与机械臂控制 测试 前言 近期回校上最后一门课,刚好是做机械臂 ...
- STM32实战总结:HAL之电机
电机基础知识参考: 51单片机外设篇:电机_路溪非溪的博客-CSDN博客 无刷电机和有刷电机 先详细了解有刷电机: 带你了解(有刷)电机工作原理_哔哩哔哩_bilibili 再详细了解无刷电机: 无刷 ...
- STM32实战 1 | STM32Cube生态系统认识与介绍
STM32实战 1 | STM32Cube生态系统认识与介绍 一.STM32Cube Ecosystem STM生态系统 二.PC软件工具套 三.STM32Cube MCU Packages(STM3 ...
- qt串口采用队列_基于STM32的RGB调色器——STM32程序和Qt上位机全开源
前言 uFUN开发板1.0版本评测时,基于Qt写了个小上位机,可以通过串口来控制板子上的RGB灯,通过控制,可以混合出任意的颜色,今天整理了一下,开源这个Qt上位机和STM32代码. 项目介绍 基于u ...
最新文章
- 过去50年最重要的统计学思想!
- AI基础:Pandas简易入门
- 浅谈Reactor 线程模型
- matlab r2010a教程,MATLAB教程R2010a(十二五)
- 什么是陀螺仪的dr算法_PID控制器调参工具——DR-PID Tuning(Matlab GUI)
- EasyUI datagrid增加统计当前页中某列的最大值,最小值,平均值,总和
- 仿真工具-NC-Verilog使用教程
- CAD中的曲线长度如何测量?
- 计算机组装与维修的前言,计算机组装与维修论文大纲模板 计算机组装与维修论文提纲如何写...
- linux pap认证,linux – pppd“同行拒绝认证”
- mysql数据库表关联和django_django 数据库表关联
- VK1628 LED数显芯片,LED驱动显示液晶驱动兼用TM1628
- 北斗系统基础知识2(北斗一代定位原理详述)
- thinkpad联想IBM笔记本为什么出现fan error
- 【Apache】配置.htaccess将主域名301重定向到www域名
- java接口自动化测试-导入xslx模板进行批量检索
- 胆囊炎的临床症状有哪些?
- js下载文件方法记录
- XML 架构示例(微软文档)
- Unity与安卓交互 | Unity2019.3版本之后,在Android Studio中写代码导出aar包与Unity中使用交互的方法