STM32F103C8T6 硬件SPI+DMA 控制WS2811

对于用硬件SPI控制的方法,网上已经有很多资料了,我也是查看网上的资料重新进行了封装,主要遇到一个第一个灯始终无法控制问题。

首先感谢作者提供的思路和方法。

1.控制思路请看这一篇

https://blog.csdn.net/tq384998430/article/details/88542469?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3

2.代码的实现请看这一篇

https://blog.csdn.net/weixin_43572492/article/details/89632893

其中使用代码的实现后发现第一个灯时钟没法控制。后来发现了把复位指令直接放到每一次数据发送完成后,再发送一次就可以了。

我的代码实现如下,使用的STM32 HAL库

主要是封装了控制代码,如下实现了红、绿每500ms变化一次

//一般SPI速率控制在6.5MHz就能达到每个字节1.25us左右
#define CODE0 0xC0
#define CODE1 0xF8

#define LED_COUNT_NUM   10	//灯的总长度

//100次,
const uint8_t LedsArrayRest[100] = {0};
uint8_t LedsArray[LED_COUNT_NUM * 24];
int16_t LedsCount = 0;

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

void WS2811_Set_RGB(uint8_t r,uint8_t g, uint8_t b, uint16_t len)
{
	//清除掉所有数据
	memset(LedsArray,0,len * 24);

	//添加数据进入到发送数组
	for(uint16_t i = 0; i < len; i ++)
	{
		//红
		for(int8_t j = 7; j >= 0; j--)
		{
			if((r & (1<<j)) == 0)
			{
				LedsArray[LedsCount++] = CODE0;
			}
			else
			{
				LedsArray[LedsCount++] = CODE1;
			}
		}

		//绿
		for(int8_t j = 7; j >= 0; j--)
		{
			if((g & (1<<j)) == 0)
			{
				LedsArray[LedsCount++] = CODE0;
			}
			else
			{
				LedsArray[LedsCount++] = CODE1;
			}
		}

		//蓝
		for(int8_t j = 7; j >= 0; j--)
		{
			if((b & (1<<j)) == 0)
			{
				LedsArray[LedsCount++] = CODE0;
			}
			else
			{
				LedsArray[LedsCount++] = CODE1;
			}
		}
	}

	HAL_SPI_Transmit_DMA(&hspi1, LedsArray, LedsCount);
	LedsCount = 0;
	while(!(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_READY));

	//发送完成后一定要发送一次复位,不然会第一个灯无法控制
	HAL_SPI_Transmit_DMA(&hspi1, LedsArrayRest, 100);
	while(!(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_READY));
}

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
	  WS2811_Set_RGB(100,0,0,8);
	  HAL_Delay(500);
	  WS2811_Set_RGB(0,100,0,8);
	  HAL_Delay(500);
  }

//一般SPI速率控制在6.5MHz就能达到每个字节1.25us左右

SPI配置如下

时钟频率:这里没用最大的72M,使用48M,然后SPI分频可以得到接近6.4MHZ的频率,这样比较接近1.25us的时序。

以上参考链接如有侵权,麻烦作者告知,本人立即处理,谢谢理解。

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在使用STM32F103C8T6控制控制OLED屏时,一种可行的方法是采用SPIDMA的组合。SPI是一种串行通信协议,它能够将数据以位序列的形式传输,并且在传输之前需要通过初始化来配置参数,比如时钟频率等。而DMA则是一种直接内存访问技术,它可以让内存和外设之间的数据传输变得更加高效,消除了CPU的参与,从而提高了系统的响应速度。因此,使用SPIDMA的组合可以大大提高系统的效率和性能。 要使用SPIDMA控制OLED屏幕,需要先初始化SPIDMA。在初始化SPI之前,需要设置SPI的端口和引脚,并配置SPI的工作方式,例如主、从模式等。然后可以使用SPI的读写寄存器来传输数据。在初始化DMA之前,需要设置DMA的通道和方向,并设置传输数据的大小、内存地址和外设地址。然后可以使用DMA传输数据,这将会减少CPU的负荷,提高系统的性能。 在使用SPIDMA控制OLED屏幕时,可以将需要显示的图像数据存储在内存中,然后使用DMA从内存中读取数据,通过SPI传输到OLED屏幕上。这样可以实现数据的高速传输和显示。同时,可以使用DMA的循环模式,使得数据的传输可以一直持续,直到传输完成为止。 综上所述,通过使用SPIDMA的组合,可以实现高效、快速地控制OLED屏幕。这种方法可以大大提高系统的效率和性能,对于需要高速传输数据的应用来说,是一种非常优秀的解决方案。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值