STM32玩转物联网09-RGB三色灯实验
本篇文章中,我们将介绍如何使用STM32的HAL库驱动RGB三色灯,实现彩色灯光的控制。通过本篇文章的学习,您将掌握RGB三色灯的基础知识和编程方法,以及PWM(脉冲宽度调制)技术的应用。
前言
本篇文章中,我们将介绍如何使用STM32的HAL库驱动RGB三色灯,实现彩色灯光的控制。通过本篇文章的学习,您将掌握RGB三色灯的基础知识和编程方法,以及PWM(脉冲宽度调制)技术的应用。
一、准备
1.RGB三色灯原理
RGB三色灯通常由红色、绿色和蓝色三种LED灯组成。通过控制每种颜色的亮度,可以混合出各种不同的颜色。RGB三色灯的工作原理基于颜色的加法混色原理,即通过对不同颜色的光线进行叠加,形成新的颜色。在STM32中,我们可以通过PWM技术控制每种颜色的LED灯的亮度,从而实现彩色灯光的控制。
2.RGB三色灯控制方法
- 基础功能:RGB三色独立可控,显示为纯色,可通过普通GPIO进行控制。
- 混合效果:实现多种颜色混合显示,可通过PWM进行控制,本文使用控制占空比来调节灯亮度。
二、实例
1. 建立工程
将上节《远程控制LED实验》代码复制并修改名字为:09.RGB_Led,打开Project.ioc文件,配置TIM3三个通道PWM输出,分别对应PA6、PA7、PB0。
生成代码后,通过Keil打开工程,在Application/User/Driver处右击选择Add New Item…,添加C文件,名称命名为drv_rgb。
同样方法创建drv_rgb.h文件, 上图第2步选择Header File(.h)文件即可,drv_rgb.h内容如下:
#ifndef __DRV_RGB_H__
#define __DRV_RGB_H__
#include "main.h"
void RGB_SetColor(uint8_t r, uint8_t g, uint8_t b);
void Breathing_Effect(uint16_t period_ms);
void Rainbow_Effect(uint16_t speed);
#endif
drv_rgb.c内容如下:
#include "drv_rgb.h"
#include "tim.h"
// 设置RGB颜色值(0-255)
void RGB_SetColor(uint8_t r, uint8_t g, uint8_t b)
{
#ifdef COMMON_ANODE
r = 255 - r;
g = 255 - g;
b = 255 - b;
#endif
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, r * 250); // 红
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, g * 250); // 绿
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, b * 250); // 蓝
}
// 简化版HSV转RGB
void HSV_to_RGB(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b)
{
uint8_t region = h / 60;
uint8_t remainder = (h % 60) * 4;
uint8_t p = (v * (255 - s)) >> 8;
uint8_t q = (v * (255 - ((s * remainder) >> 8))) >> 8;
uint8_t t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch(region) {
case 0: *r = v; *g = t; *b = p; break;
case 1: *r = q; *g = v; *b = p; break;
case 2: *r = p; *g = v; *b = t; break;
case 3: *r = p; *g = q; *b = v; break;
case 4: *r = t; *g = p; *b = v; break;
default: *r = v; *g = p; *b = q; break;
}
}
// 呼吸灯效果
void Breathing_Effect(uint16_t period_ms)
{
static uint32_t last_tick = 0;
static uint8_t dir = 0;
static uint8_t brightness = 0;
if(HAL_GetTick() - last_tick > period_ms/255) {
last_tick = HAL_GetTick();
if(dir) {
if(++brightness == 255) dir = 0;
} else {
if(--brightness == 0) dir = 1;
}
RGB_SetColor(brightness, 0, 0); // 红色呼吸
}
}
// 彩虹渐变效果
void Rainbow_Effect(uint16_t speed)
{
static uint16_t hue = 0;
uint8_t r, g, b;
HSV_to_RGB(hue, 255, 255, &r, &g, &b);
RGB_SetColor(r, g, b);
hue = (hue + 1) % 360;
HAL_Delay(speed);
}
main函数内容如下, 关闭ESP8266相关代码,本节只进行本地RGB三色灯功能开发。
int main(void)
{
/* USER CODE BEGIN 1 */
int ret = 0;
int cnt = 300;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
printf("start application\r\n");
// 使能空闲中断
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart3, (uint8_t *)Uart_Frame_Record.Data_RX_BUF, RX_BUF_MAX_LEN); // 启动DMA接收
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
#ifdef SUPPORT_ESP8266
// 连接路由器
ESP8266_STAInit();
delay_ms(1000);
if (wifi_connect_status != WIFI_GOT_IP)
{
while(ESP8266_STAConnect((char *)Wssid, (char *)Wpassword));
}
// 连接MQTT 服务器
printf("ready to connect to mqtt server\r\n");
mqtt_task_init();
mqtt_task_subcribe();
// mqtt_task_report();
#endif
// 固定颜色显示
RGB_SetColor(255, 128, 0); // 橙色
HAL_Delay(2000);
while (cnt-- > 0)
{
Rainbow_Effect(100);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
#ifdef SUPPORT_ESP8266
mqtt_task_report();
HAL_Delay(60000);
#endif
Breathing_Effect(3000);
}
return ret;
/* USER CODE END 3 */
}
2. 核心函数
drv_rgb.c中核心函数为void RGB_SetColor(uint8_t r, uint8_t g, uint8_t b), 通过设置占空比来控制RGB三个引脚的输出电压,从而进行灯控制,注意:需要手动调用HAL_TIM_PWM_Start()函数才能正式启动输出PWM。
// 设置RGB颜色值(0-255)
void RGB_SetColor(uint8_t r, uint8_t g, uint8_t b)
{
#ifdef COMMON_ANODE
r = 255 - r;
g = 255 - g;
b = 255 - b;
#endif
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, r * 250); // 红
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, g * 250); // 绿
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, b * 250); // 蓝
}
3. 程序执行
本实验实现了上电首先亮蓝色灯2秒,然后进行30秒彩虹渐变效果,最后实现循环红色呼吸灯效果。
三、小结
如您在使用过程中有任何问题,请加QQ群进一步交流。
QQ交流群:573122190 (备注:物联网项目交流)
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)