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渐变相关推荐

  1. STM32实战(1):搭建模板工程

    " 从今天起我会更新一个STM32实战系列教程,以STM32F103RCT6核心板为例由浅至深的向大家介绍嵌入式软件开发的学习过程,计划是先从最基础的搭建工程开始,到裸机开发,再到各种中间件 ...

  2. STM32实战六 PWM加移相正交

    这一章编写PWM程序,使用TIM3以两个通道,完全映射到PC6和PC7,除普通PWM输出外,增加移相正交PWM功能,为后面的编码器计数模式提供信号源. PWM.h #ifndef __PWM__ #d ...

  3. STM32实战总结:HAL之GUI

    在TFT上简单的显示字符.数字.汉字.图形.图片等,都是一些简单的显示.如果想要进行较为复杂的显示,就推荐使用GUI. 市面上常见的嵌入式GUI有LVGL,emWin(ucGUI),TouchGFX, ...

  4. RGB渐变LED,实现停止在任意颜色

    在发布的第一篇文章使用RGB共阳极LED,基于Arduino实现七彩渐变_默以思的博客-CSDN博客_arduino rgb灯渐变 中,讲解了可以连续变换的RGB灯光效果,实际上,从试着使LED间断变 ...

  5. 【STM32实战】机械臂快递分拣系统(二)——机械臂控制程序(上位机)编写

    [STM32实战]机械臂快递分拣系统(二)--机械臂控制程序(上位机)编写 前言 题目分析 蓝牙模块的使用 上位机程序的编写 连接阿里云 测试 前言 近期回校上最后一门课,刚好是做机械臂有关的题目,所 ...

  6. 【STM32实战】机械臂快递分拣系统(一)——机械臂控制程序(下位机)编写

    [STM32实战]机械臂快递分拣系统(一)--机械臂控制程序(下位机)编写 前言 题目分析 工程模板生成 蓝牙模块的使用 蓝牙接收数据解析与机械臂控制 测试 前言 近期回校上最后一门课,刚好是做机械臂 ...

  7. STM32实战总结:HAL之电机

    电机基础知识参考: 51单片机外设篇:电机_路溪非溪的博客-CSDN博客 无刷电机和有刷电机 先详细了解有刷电机: 带你了解(有刷)电机工作原理_哔哩哔哩_bilibili 再详细了解无刷电机: 无刷 ...

  8. STM32实战 1 | STM32Cube生态系统认识与介绍

    STM32实战 1 | STM32Cube生态系统认识与介绍 一.STM32Cube Ecosystem STM生态系统 二.PC软件工具套 三.STM32Cube MCU Packages(STM3 ...

  9. qt串口采用队列_基于STM32的RGB调色器——STM32程序和Qt上位机全开源

    前言 uFUN开发板1.0版本评测时,基于Qt写了个小上位机,可以通过串口来控制板子上的RGB灯,通过控制,可以混合出任意的颜色,今天整理了一下,开源这个Qt上位机和STM32代码. 项目介绍 基于u ...

最新文章

  1. 过去50年最重要的统计学思想!
  2. AI基础:Pandas简易入门
  3. 浅谈Reactor 线程模型
  4. matlab r2010a教程,MATLAB教程R2010a(十二五)
  5. 什么是陀螺仪的dr算法_PID控制器调参工具——DR-PID Tuning(Matlab GUI)
  6. EasyUI datagrid增加统计当前页中某列的最大值,最小值,平均值,总和
  7. 仿真工具-NC-Verilog使用教程
  8. CAD中的曲线长度如何测量?
  9. 计算机组装与维修的前言,计算机组装与维修论文大纲模板 计算机组装与维修论文提纲如何写...
  10. linux pap认证,linux – pppd“同行拒绝认证”
  11. mysql数据库表关联和django_django 数据库表关联
  12. VK1628 LED数显芯片,LED驱动显示液晶驱动兼用TM1628
  13. 北斗系统基础知识2(北斗一代定位原理详述)
  14. thinkpad联想IBM笔记本为什么出现fan error
  15. 【Apache】配置.htaccess将主域名301重定向到www域名
  16. java接口自动化测试-导入xslx模板进行批量检索
  17. 胆囊炎的临床症状有哪些?
  18. js下载文件方法记录
  19. XML 架构示例(微软文档)
  20. Unity与安卓交互 | Unity2019.3版本之后,在Android Studio中写代码导出aar包与Unity中使用交互的方法

热门文章

  1. java数字转罗马数字
  2. JDBC与数据库连接
  3. android系统应用开发常用的adb命令个人收藏集锦(不断更新)
  4. win10系统怎么创建虚拟网卡?
  5. 为什么建议大家使用 Linux 开发?真的很很很优雅!
  6. sqlzoo刷题笔记-02 | SUM and COUNT
  7. Acess错误:文件共享锁定数溢出
  8. 聊聊iClient for Leaflet坐标转换问题
  9. Html HBuilder封装APP
  10. Delicate girl蘑菇街女装 精品时尚等你来