IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32单片机驱动全彩LED模块遍历百万种颜色 -> 正文阅读

[嵌入式]STM32单片机驱动全彩LED模块遍历百万种颜色

分享一个趣味的实验,单片机PWM驱动全彩LED模块,快速遍历100万种颜色。

一、使用硬件

单片机为STM32F103C8T6,三色LED模块如下图(图片来源于网络)
在这里插入图片描述

二、STM32CubeMx配置

配置TIM3的PWM通道1、2、3,对应引脚分别为PA6、PA7、PB0,这里的计数周期根据自己的时钟频率配置,我这里配置的PWM频率为2KHz,计算方法为,时钟频率48MHz,48分频即图中PSC的值为48-1=47为1MHz,计数周期即图中Counter Period(自动重装寄存器ARR的值)为500-1=499,则T=500/1M=500us,即频率为2000Hz.
在这里插入图片描述

三、PWM驱动

定时器初始化的代码不再表述,我们需要一个设置PWM占空比的函数,HAL库中,该函数为__HAL_TIM_SetCompare,对应在 stm32f1xx_hal_tim.h文件中宏定义

#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\
   ((__HANDLE__)->Instance->CCR4 = (__COMPARE__)))

为此,可通过以下函数设置占空比,取占空比是百分数100,即占空比为50%,则寄存器CCRx的值为50499/100,当占空比为100%时,CCRx的值为499,即为自动重装寄存器ARR的值。关于占空比的计算,具体可查阅芯片手册。

/*******************************************************************************
  * 函数名:PWM_SetDutyCycle
  * 功  能:设置占空比
  * 参  数:Channel通道
			Duty占空比
  * 返回值:无
  * 说  明:无
*******************************************************************************/
void PWM_SetDutyCycle(uint32_t Channel, uint16_t Duty)
{
	uint16_t u16CCR = 0;
	u16CCR = Duty * 499 / 100;
	__HAL_TIM_SetCompare(&htim3, Channel, u16CCR);
}

调用该函数,对三个通道分别设置占空比为25%、50%、75:

	PWM_SetDutyCycle(TIM_CHANNEL_1, 25);
	PWM_SetDutyCycle(TIM_CHANNEL_2, 50);
	PWM_SetDutyCycle(TIM_CHANNEL_3, 75);

用逻辑分析仪采集三个引脚的输出如下图
在这里插入图片描述
上图可看出周期为500us,即频率为2kHz;
在这里插入图片描述
上图显示占空比为50%的高电平时间间隔为250us。其他两个占空比的时间不再测量、展示。

四、遍历颜色

三色LED模块由三种颜色红色R、绿色G、蓝色B的led组成,通过三种不同比例的颜色混合,可实现全彩显示。RGB三基色可把三种颜色从0~255划分为256种强度,从而混合组成共16777216种颜色,但如果遍历这么多种颜色显然太耗时,而且意义不大,我们只根据占空比0到100的组合,实现约103万种颜色的组合,如果每种组合延时1ms,103万种也需要17min左右时间,也是比较耗时的。
代码如下:

/*******************************************************************************
  * 函数名:RGB_ColorTraverse
  * 功  能:颜色遍历
  * 参  数:无
  * 返回值:无
  * 说  明:每一种组合,延时1ms
*******************************************************************************/
void RGB_ColorTraverse(void)
{
	uint8_t i, j, k;

	for (i =0; i < 101; i++)
	{
		PWM_SetDutyCycle(TIM_CHANNEL_1, i);//R
		for (j =0; j < 101; j++)
		{
			PWM_SetDutyCycle(TIM_CHANNEL_2, j);//G
			for (k =0; k < 101; k++)
			{
				PWM_SetDutyCycle(TIM_CHANNEL_3, k);//B
				HAL_Delay(1);//延时1ms
			   	HAL_IWDG_Refresh(&hiwdg);//看门狗复位
			}
		}
	}
}

这里采用三级for循环嵌套实现颜色遍历,HAL库延时函数延时,因为程序会一直在for循环里,所以要喂狗。
实验过程中发现,最内层for循环的颜色变化很快且闪烁太明显,应该是因为占空比从0变到100,又会突然变为0,再增大到100,如此循环;考虑改进,使占空比变到100后,再逐渐减小到0,再增大,如此循环。所以为每层for循环增加标志位,每次for循环结束则标志位取反一次,占空比根据标志位的值而确定是取循环变量的值还是(100-循环变量),代码如下:

void RGB_ColorTraverse(void)
{
	uint8_t i, j, k;	
	RGBFlag_tu uRGBFlag;
	uRGBFlag.byte = 0;
	for (i =0; i < 101; i++)
	{
		if (uRGBFlag.bt.bRedCycle)
		{
			PWM_SetDutyCycle(TIM_CHANNEL_1, 100 - i);//R
		}else
		{
			PWM_SetDutyCycle(TIM_CHANNEL_1, i);//R
		}		
		if (i == 100)
		{
			uRGBFlag.bt.bRedCycle = ~uRGBFlag.bt.bRedCycle;
		}		
		for (j =0; j < 101; j++)
		{
			if (uRGBFlag.bt.bGreenCycle)
			{
				PWM_SetDutyCycle(TIM_CHANNEL_2, 100 - j);//G
			}else
			{
				PWM_SetDutyCycle(TIM_CHANNEL_2, j);//G
			}		
			if (j == 100)
			{
				uRGBFlag.bt.bGreenCycle = ~uRGBFlag.bt.bGreenCycle;
			}
			for (k =0; k < 101; k++)
			{
				if (uRGBFlag.bt.bBlueCycle)
				{
					PWM_SetDutyCycle(TIM_CHANNEL_3, 100 - k);//B
				}else
				{
					PWM_SetDutyCycle(TIM_CHANNEL_3, k);//B
				}		
				if (k == 100)
				{
					uRGBFlag.bt.bBlueCycle = ~uRGBFlag.bt.bBlueCycle;
				}
				HAL_Delay(3);
				printf("%d,%d,%d\n",i,j,k);
			   	HAL_IWDG_Refresh(&hiwdg);
			}
		}
	}
}

实际效果,比较失望,可能是因为这种廉价的模块的问题,三个led之间的距离实际比较远,三种光不会很好的混合到一起,看起来没有混合色彩的效果(手机拍摄照片的效果更差):
在这里插入图片描述

五、总结

不要买这个LED模块。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-17 12:09:12  更:2021-10-17 12:09:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:30:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码