STM32C6T6,SPI+DMA驱动WSP2812B炫彩灯带

本文详细介绍了如何使用STM32C6T6通过SPI+DMA方式驱动WS2812B炫彩灯带,包括硬件选型、GPIO、SPI和DMA的初始化,以及颜色转换和灯带控制函数的实现。提供了完整的代码示例,展示了如何进行点灯和关灯操作,以及按数量和颜色进行呼吸效果的实现。
摘要由CSDN通过智能技术生成

目录

硬件选型

芯片类型:STM32C6T6开发板、WS2812B类型灯带、5V电源

驱动方式

SPI+DMA传输

GPIO初始化

这里使用SPI1的单工通信,MOSI引脚为GPIOA_7

void ws2812_GPIO_Init(void){
	GPIO_InitTypeDef 		GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

SPI初始化

void ws2812_SPI_Init(void){
	SPI_InitTypeDef  		SPI_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
	SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;//设置SPI单向或者双向的数据模式
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置SPI工作模式:设置为主SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构,
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//选择了串行时钟的稳态:时钟悬空低
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//数据捕获于第二个时钟沿
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; /* 48MHz / 8 = 6MHz 定义波特率预分频的值*/
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值计算的多项式
	SPI_Init(SPI1, &SPI_InitStructure);//根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI1, ENABLE);//根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
	SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);//使能SPI,DMA功能
}

DMA初始化

void ws2812_DMA_Init(void){
	DMA_InitTypeDef 		DMA_InitStructure;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	DMA_DeInit(DMA1_Channel3);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI1 -> DR);//外设地址寄存器
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ws2812_data_buffer;//内存地址寄存器
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//数据传输方向,从内存读取发送到外设
	DMA_InitStructure.DMA_BufferSize = WS2812_LED_NUM * 24;//传输数据长度
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//数据宽度为8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//数据宽度为8位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常缓存模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel3, &DMA_InitStructure);
}

将颜色转换为0码和1码,储存到闪存中

#define WS2812_LED_NUM 	144
uint8_t ws2812_data_buffer[WS2812_LED_NUM][24] ;
// 11111000  SIG_1   5/8 = 62.5%
// 11100000  SIG_0   3/8 = 37.5%

#define 		SIG_1 		0XF8
#define 		SIG_0  		0XC0
void ws2812_Set_one_LED_Color(uint16_t LED_index ,uint32_t GRB_color){
  uint8_t i = 0;
	uint32_t cnt = 0x800000;
  if(LED_index < WS2812_LED_NUM){
    for(i = 0; i < 24; ++i){
			if(GRB_color & cnt){
				ws2812_data_buffer[LED_index][i] = SIG_1;
			}
			else{
				ws2812_data_buffer[LED_index][i] = SIG_0;
			}
			cnt >>= 1;
    }
  }
}

启动传输

void ws2812_Send_Data(void){
	DMA_Cmd(DMA1_Channel3, DISABLE );
	DMA_ClearFlag(DMA1_FLAG_TC3);    
 	DMA_SetCurrDataCounter(DMA1_Channel3,24 * WS2812_LED_NUM );
 	DMA_Cmd(DMA1_Channel3, ENABLE);
}

关灯操作

void ws2812_AllShutOff(void){
  uint16_t i;
  uint8_t j;
  
  for(i = 0; i < WS2812_LED_NUM; i++)
  {
    for(j = 0; j < 24; j++)
    {
      ws2812_data_buffer[i][j] = SIG_0;
    }
  }
  ws2812_Send_Data();

}

按数量和颜色点灯函数

void ws2812_number_LED_one_Color_breath(uint16_t interval_number, uint32_t GRB_color)
{
	uint8_t i = 0;
	uint16_t j = 0;
	rgb_color.G = GRB_color>>16;
	rgb_color.R = GRB_color>>8;
	rgb_color.B = GRB_color;
	for(i=1;i<=100;i++)
	{
		for(j=0;j<interval_number;j++){
			ws2812_Set_one_LED_Color(j, ((rgb_color.G<<16) | (rgb_color.R<<8) | (rgb_color.B)));
		}
		ws2812_Send_Data();
		
	}

}

主函数

int main(void){
	ws2812_GPIO_Init();
	ws2812_SPI_Init();
	ws2812_DMA_Init();
 	ws2812_AllShutOff();
  while(1){
		ws2812_number_LED_one_Color_breath(20,0xFF0000);
 		 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值