[STM32]PWM+DMA控制WS2812

本文介绍了使用STM32F103C8T6微控制器驱动WS2812 RGB灯珠制作生日蛋糕图案的过程。通过参考两篇教程,作者修改了代码以适应需求。主要函数包括`WS2812_one()`用于显示RGB灯及`hz_left()`用于汉字左移。代码中涉及汉字取模数据的处理和颜色显示,并提供了进一步优化的空间。
摘要由CSDN通过智能技术生成

STM32型号:STM32F103C8T6

实现效果:(由于是给别人做生日礼物,所以图案是个蛋糕)
在这里插入图片描述

参考网站:
WS2812灯珠的STM32驱动方式(一)——了解对手
WS2812灯珠的STM32驱动方式(二)——DMA+PWM

(有关WS2812的原理介绍可参考链接1,驱动方式和驱动原理可参考链接2)
我是在大佬原有的基础上进行修改

接下来是部分代码介绍:

首先是

WS2812B.c

 uint16_t LED_BYTE_Buffer[6200];

根据RGB灯的数量,需要对LED_BYTE_Buffer数组的大小进行修改

void WS2812_one(uint8_t (*color)[3], uint16_t len)

该函数是一个显示函数,依次对需要显示的RGB灯进行显示,color是颜色数组,len是需要显示RGB灯的数量。


main.c

void hz_write(uint8_t (*date)[32],uint8_t (*color)[3]) //显示单个汉字

这个函数是写移位函数时的临时函数,可以不看,完整的移位函数如下:

void hz_left(uint8_t (*date)[32],uint8_t (*color)[3],uint8_t num) //汉字左移 date汉字取模数组,color颜色,num汉字数量,
{
	uint8_t i,j,k,flag,dat,rgb_m = 0,rgb_n = 31;		//i,j循环标志,flag汉字十六进制标志,dat移位临时数组,rgb_m灯定位,rgb_n灯定位
	uint8_t rgb_hz[256][3],cache[2][32];		//rgb_hzRGB显示数组,cache[32]缓存数组
	uint8_t len = 0;				//len汉字长度

	for(i=0;i<32;i++)	
	{
		cache[0][i] = 0x00;
		cache[1][i] = date[0][i];
	}
	while(num - len + 1)
	{
		for(k = 0;k < 17;k++)	//单个汉字移位完成
		{
			for(i = 0;i < 32;i++)	//显示单个汉字
			{
				if(i%2 == 0)
				{
					rgb_m = i/2;
					rgb_n = 31-i/2;
				}
				dat = cache[0][i];
				for(j = 0;j < 4;j++)	//将十六进制转换,通过RGB显示出来
				{
					flag = dat&0x80;
					if(flag == 0x80)
					{
						rgb_hz[rgb_m][0] = color[0][0];
						rgb_hz[rgb_m][1] = color[0][1];
						rgb_hz[rgb_m][2] = color[0][2];
					}
					else
					{
						rgb_hz[rgb_m][0] = 0;
						rgb_hz[rgb_m][1] = 0;
						rgb_hz[rgb_m][2] = 0;
					}
					rgb_m += 32;
					dat <<= 1;
					
					flag = dat&0x80;
					if(flag == 0x80)
					{
						rgb_hz[rgb_n][0] = color[0][0];
						rgb_hz[rgb_n][1] = color[0][1];
						rgb_hz[rgb_n][2] = color[0][2];
					}
					else
					{
						rgb_hz[rgb_n][0] = 0;
						rgb_hz[rgb_n][1] = 0;
						rgb_hz[rgb_n][2] = 0;
					}
					rgb_n += 32;
					dat <<= 1;
				}
			}
			WS2812_one(&rgb_hz[0],256);
			delay_ms(200);
			
			for(i=0;i<16;i++)	//移位
			{
				cache[0][2*i] = (cache[0][2*i] <<= 1) | ((cache[0][2*i+1]&0x80) >> 7) ;
				cache[0][2*i+1] = (cache[0][2*i+1] <<= 1) | ((cache[1][2*i]&0x80) >> 7) ;
				cache[1][2*i] = (cache[1][2*i] <<= 1) | ((cache[1][2*i+1]&0x80) >> 7) ;
				cache[1][2*i+1] <<= 1 ;
			}
			
		}
		len++;
		if(num > 2 && len < num)
		{
			for(i=0;i<32;i++)
			{
				cache[1][i] = date[len][i];
			}
		}
	}
}

该函数的功能是进行汉字左移,形参date为存放汉字取模的数据,color为颜色,num为汉字数量。
由于取模与16*16的RGB灯行内排序不同,所以需要注意数据存放的数组所在位置,通过这个位置对程序进行修改。

当然,这个代码还有许多值得优化的地方,比如,由于颜色只取单色,可以将color形参设置为一个一维数组等。

汉字取模的格式为
在这里插入图片描述
最后,程序文件如下:

ws2812_RGB.zip

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
STM32F4可以通过TIM PWM DMA控制WS2812灯带。 在使用STM32F4来控制WS2812灯带之前,我们需要了解一些基本的原理。WS2812灯带是一种基于Neopixel技术的RGB LED灯带,它具有灯珠之间串行通信的特点。通过发送一系列的0和1的数据信号,可以控制每个灯珠的颜色与亮度。 首先,我们需要配置STM32F4的GPIO引脚作为TIM输出模式,选择PWM模式,并配置DMA进行数据传输。接着,我们需要设置TIM的周期和预分频系数,以控制PWM信号的频率和占空比。根据WS2812的通信协议,每个数据位以50%占空比的PWM信号来表示,其中逻辑0和逻辑1的时间分别为400ns和800ns。 然后,我们通过DMA传输具有正确占空比的PWM数据到GPIO引脚,以控制WS2812灯带。我们可以使用定时器计数器的更新事件作为触发源,通过TIM的DMA请求信号来触发DMA传输。 我们可以通过编写相应的代码来配置STM32F4的定时器和DMA。首先,我们需要定义一个数据缓冲区,将要传输的PWM数据写入缓冲区中。然后,我们配置DMA的传输长度、传输方向和传输模式。接着,我们配置定时器的PWM模式、周期和预分频系数。最后,我们启动定时器和DMA,并等待传输完成。 以上就是利用STM32F4的TIM PWM DMA控制WS2812灯带的简要介绍。通过正确配置定时器和DMA,我们可以实现高效、准确地控制WS2812灯带的颜色和亮度,从而实现丰富多彩的灯光效果。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值