RGB灯优化----SPI实现

本文详细介绍了使用STM32F4通过SPI接口驱动RGB灯的实现过程,包括计算SPI通信时间、接线、程序设计和具体代码示例,展示了如何配置GPIO和SPI以及如何封装数据发送函数。
摘要由CSDN通过智能技术生成

一、实现思路

😊前面已经进行过一个RGB灯的实现,今天通过SPI的优化,也可以实现,具体的思路就是通过SPI发送一个字节的时间来计算,下面先来看下原理图:

 ✌注意看,RGB的需要发送0码和1码的时间符合上面手册给的时间范围才可以亮起来,所以我们只需要计算发送需要的时间就行,

😈GRB灯--SPI实现的计算方式
F40的芯片-----APB1的时钟为42MHZ
42MHZ--发送一个字节--我们要发一个字所以--42/8=5.25MHZ    

则数一次需要的时间为1/5.25=1.9*10负7次方,换算为ns    *1000000=190ns发一个位


发送0码---高电平时间为220ns~380ns.低电平时间为580ns~1μs
发送1码---低电平时间为220ns~380ns.高电平时间为580ns~1μs

所以发0码--1100 0000--0xc0---只要在那个范围就行
      发送1码--1111 1100--0xFC

🙅注意:我这里用的是F4的APB1的时钟,,F103的或者其他芯片的型号都不一样,需要自己去查看手册,计算具体的时间

二、接线

😫这里我用的开发板接的是PB15,映射的是SPI2,想用SPI实现就得接到有SPI的IO口上,不然会没效果,上面也写了计算的方法,然后我们来看代码:

注意:使能GPIO的时钟和SPI2的时钟----重点

三、程序实现 

😌上面介绍了初始化的实现,,下面解释关于SPI的发送函数和封装RGB了数据传送的函数

//SPI2发送接收函数
uint8_t SPI2_sendByte(uint8_t data)
{
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==0){}//等待发送完成
		SPI_I2S_SendData(SPI2,data);
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==0){}//等待可以接收
		return SPI_I2S_ReceiveData(SPI2);
}

这个就没什么好说的了,SPI的发送和接收是一起的,并且是一个字节的发送和接收,下面是RGB的数据传输函数---------------------------------------有两种方案,一种是24位一起发,因为一个颜色占据8位,G-绿R-红B-蓝===三个颜色一起发,就是24位 ,也可以8位8位一起发,我们就用24位一起发的模式来讲解,末尾有全部的代码:

🙋第二种方案就是8位8位发 

同样的计算方式,只是发送的位数不同而已,想发送三个颜色,必须再写一个函数配套用

编辑实例:

 四、代码

WS2812.C

#include "WS2812.h"
#include "delay.h"

void Grb_Init(void)
{
		//PB 15  推挽输出
		GPIO_InitTypeDef GPIO_InitStruct={0};
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);//使能PC时钟
		//GPIO配置
		GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AF; //复用模式
		GPIO_InitStruct.GPIO_OType =GPIO_OType_PP;//设置输出模式推挽
		GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
		GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//设置无上下拉。GPIO初始化默认是低电平
		GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed;//速度设置
		GPIO_Init(GPIOB,&GPIO_InitStruct);//GPIO初始化
		GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
		
		//SPI2参数配置
		SPI_InitTypeDef SPI_InitStructure;
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
		SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_8;//波特率预分频值
		SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;//串行时钟进行偶次采样
		SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;//时钟空闲为高电平---模式3-上升沿采集数据
		SPI_InitStructure.SPI_CRCPolynomial=7;//CRC值计算多项式--7--复位值
		SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//SPI双向全双工
		SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//8位数据帧
		SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;//数据高位在前
		SPI_InitStructure.SPI_Mode=SPI_Mode_Master;//SPI主模式
		SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//NSS信号由软件管理
		SPI_Init(SPI2,&SPI_InitStructure);
		SPI_Cmd(SPI2,ENABLE);
		
		RGB_to_GRB(RGB_BLACK);
		RGB_to_GRB(RGB_BLACK);
		RGB_to_GRB(RGB_BLACK);
		RGB_to_GRB(RGB_BLACK);
		GRB_RESET();//复位
}

//SPI2发送接收函数
uint8_t SPI2_sendByte(uint8_t data)
{
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==0){}//等待发送完成
		SPI_I2S_SendData(SPI2,data);
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==0){}//等待可以接收
		return SPI_I2S_ReceiveData(SPI2);
}
	
void GRB_RESET(void)//复位
{
	GRB_Data = 0;
    delay_ms(5);
}

void RGB_Write(u8 data)//发送一个颜色
{
   int i;
	for(i=0;i<8;i++)//一个颜色八个位
	{
	   if(data & 1<<(7-i))//高位先发
	   {
	       //发送数据1
		   SPI2_sendByte(0xFc);
	   }
	   else
	   {
	       //发送数据0
		  SPI2_sendByte(0xc0);
	   }
	}
}

//怎么把颜色发送给芯片  通过PB15  24位色 转2进制  从高位发
void RGB_Write2(u32 data)//发送24位颜色
{
   int i;
	for(i=0;i<24;i++)//一个颜色八个位
	{
	   if(data & 1<<(23-i))//高位先发
	   {
	       //发送数据1
		   SPI2_sendByte(0xFc);
	   }
	   else
	   {
	       //发送数据0
		    SPI2_sendByte(0xc0);
	   }
	}
}


//RGB   G 8--15   0xff00  00
void RGB_to_GRB(u32 color)
{
	RGB_Write((color>>8)&0XFF);//发送绿色
    RGB_Write((color>>16)&0XFF);//发送红色
	RGB_Write((color)&0XFF);//发送蓝色
}

WS2812.h

 #ifndef __WS2812_H_
#define __WS2812_H_
#include "io_bit.h"

#define GRB_Data PBout(15)
void Grb_Init(void);
void GRB_RESET(void);
void RGB_Write(u8 data);
void RGB_to_GRB(u32 color);
void RGB_Write2(u32 data);

#define RGB_RED  0XFF0000
#define RGB_GREEN  0X00FF00
#define RGB_BLUE    0X0000FF
#define RGB_BLACK  0X000000
#define RGB_YELLOW  0XFFFF00
#define RGB_WHITE  0XFFFFFF
#endif

 main.c

#include "stm32f4xx.h"
#include "delay.h"
#include "LED.h"
#include "exti.h"
#include "key.h"
#include "WS2812.h"


int main()
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组2
	delay_Init();//延时初始化
	Exti_Init();//外部中断初始化
	LED_Init();//LED初始化
	Grb_Init();
	while(1)
	{
		if(button1)
		{
			RGB_Write2(RGB_RED);
			RGB_Write2(RGB_GREEN);
			RGB_Write2(RGB_BLUE);
			RGB_Write2(RGB_WHITE);
			button1=0;
		}
		
		if(button2)
		{
			RGB_to_GRB(RGB_BLACK);
			RGB_to_GRB(RGB_BLACK);
			RGB_to_GRB(RGB_BLACK);
			RGB_to_GRB(RGB_BLACK);
			button2=0;
		}
	}
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值