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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于SK6812编码LED实现炫光功能(PWM+DMA功能MCU兼容) -> 正文阅读

[嵌入式]基于SK6812编码LED实现炫光功能(PWM+DMA功能MCU兼容)

老套路;引言,追源,再讲实际

????????谈到LED大家一定都不陌生,在玩开发板的时候就点亮过各种颜色的贴片LED了吧,可是当我们同时要用到多个LED的时候,芯片IO不够用了呢?对了,点下我的头像看一下查理复用算法,那如果依然不够用了咋办呢?

????????新道具出现了-略微昂贵的编码RGB-SK6812

当然可编码的LED不止这颗型号,类似有WS2812B这些型号,但控制原理如出一辙,要问我为啥原理相似,还不是生产厂家为了取代别家涨价的物料而做的咯,回归正题,具体控制原理我们先熟悉一下,如下图;

?由图可以得到的信息:

(1)编码是以24bit来完成一个LED的RGB效果,也就是如果需要点亮N个LED,则需要发送N个24bit数据,然后复位一下,就可以实现不同LED亮出不一样颜色的效果了

(2)每个bit的高低电平:cycle(周期)=1.2us,占空比=50%为1,占空比=30%为0

(3)编码LED是单线通信,到这里可以构思的方法出现了三种:1-SPI;2-IO;3-PWM

这里我不详细解说我实际操作时候遇到的问题,以及我是如何排除这些方法的,最后结果我选择了PWM+DMA的方式,原因是该方案既不浪费资源,且移植性强,可操作性强

正文

??????? 在MCU的选型中,确认是否具备PWM+DMA功能,如果不具备就可以不继续浪费时间了;

首先配置PWM,这里有一个功能,在我使用的MCU中是具备同时寄存两种PWM波形的,用户需要确认自己使用的MCU是否具备此功能,或者可以同时寄存更多种PWM波形。在初始化时将这两种波形先预存好;

pwm_set_cycle_and_duty(PWM_ID,(uint8_t)(RGB_cycle_set),(uint8_t)(RGB_duty_high_value));
pwm_set_pwm0_shadow_cycle_and_duty(RGB_cycle_rest_set,RGB_duty_rest_low_value);
/*每个MCU配置不同,不需要细纠*/

然后预设好中断

	pwm_set_interrupt_enable(PWM_IRQ_PWM0_IR_DMA_FIFO_DONE);
	irq_set_mask(FLD_IRQ_SW_PWM_EN);

此时不需要打开PWM输出,等到主函数中配置完需要输出的pwm组后再输出;

准备工作还没有结束,我们需要再单独配置一下底层代码处的输出高和输出低电平的驱动函数

/*
 * @description		: 设置电平1的pwm
 * @param - none 	: 无
 * @return - none 	: 无
 */
uint16_t hal_set_pwm0_high(void)
{
	return pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 1);//高脉冲生效,1个PWM0_PULSE_NORMAL帧
}

/*
 * @description		: 设置电平0的pwm
 * @param - none 	: 无
 * @return - none 	: 无
 */
uint16_t hal_set_pwm0_low(void)
{
	return pwm_config_dma_fifo_waveform(1, PWM0_PULSE_SHADOW, 1);//高脉冲生效,1个PWM0_PULSE_SHADOW帧
}

(内容根据自己的MCU提供的SDK包进行修改)

然后开始正式的驱动程序:

/*
 * @description		: 对DMA进行填充,单一色域的多个rgb亮
 * @param - len 	: 要显示的灯数量
 * @param - *rgb 	: 要显示的灯的三色参数数组
 * @return - none 	: 无
 */
void api_SK6812_send_dat_one_in(uint8_t *rgb, uint16_t len)
{
	uint8_t i;
	uint8_t memaddr = 2;
	while (len)
	{
		for(i=0; i<8; i++) // GREEN data
	    {
			IR_DMA_Buff[memaddr] = ((rgb[GREEN]<<i) & 0x0080) ? hal_set_pwm0_high():hal_set_pwm0_low();
	        memaddr++;
	    }
	    for(i=0; i<8; i++) // RED
	    {
	    	IR_DMA_Buff[memaddr] = ((rgb[RED]<<i) & 0x0080) ? hal_set_pwm0_high():hal_set_pwm0_low();
	        memaddr++;
	    }
	    for(i=0; i<8; i++) // BLUE
	    {
	    	IR_DMA_Buff[memaddr] = ((rgb[BLUE]<<i) & 0x0080) ? hal_set_pwm0_high():hal_set_pwm0_low();
	        memaddr++;
	    }
	}

	uint32_t length = memaddr*2 - 4;
	uint16_t *buff ;
	buff=IR_DMA_Buff;
	buff[0]= length&0xff;
	buff[1]= (length>>16)&0xff;
	SK6812_Show();
}

?这是一个单一颜色的多个LED驱动的代码,简而言之就是使用逻辑将我们的数组数据填充到DMA数组中,然后驱动DMA,后面的功能也是如此,然后在外围通过改变数组的内容,实现各种想要的任务,例如呼吸,渐变色,炫光

思想就是这样的一个思想,实现任务还是建议各位自己动手尝试,如果实在不想,可以去我的文章的代码库里拿取

?

?

?

?

?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 13:19:13  更:2021-09-12 13:19:18 
 
开发: 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年12日历 -2024/12/30 1:31:36-

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