ARM技术论坛
直播中

流水源君

3年用户 1028经验值
擅长:测量仪表,嵌入式技术,处理器/DSP,控制/MCU
私信 关注
[经验]

【悟空派H3开发板免费体验】基于spi驱动WS2812灯

使用spi引脚驱动WS2812,接线端口如下

image.png

程序如下spi_ws2812.c:

#include "sys/types.h"
#include "sys/stat.h"
#include "sys/ioctl.h"
#include "fcntl.h"
#include "stdio.h" 
#include "string.h"
#include "unistd.h"
#include "linux/spi/spidev.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define	WS2812_PIXELS	3
#define WS_TRANSFER_SIZE   (WS2812_PIXELS*24)   // Transfer dataSize

#define WS_BIT              24
#define WS_BIT1             0x7C
#define WS_BIT0             0x60

/*******************************************************************************
 * Variables
 ******************************************************************************/
u_int8_t g_WS2812TxBuf[WS_TRANSFER_SIZE];   // WS2812 Strip transmit data buffer

void WS2812_PixelSetIndexRGB(u_int16_t n, u_int8_t r, u_int8_t g, u_int8_t b)
{    
    if(n < WS2812_PIXELS)
    {
        memset((void *)&g_WS2812TxBuf[n*WS_BIT], WS_BIT0, 24);

        if( ((g>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+0] = WS_BIT1;
        if( ((g>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+1] = WS_BIT1;
        if( ((g>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+2] = WS_BIT1;
        if( ((g>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+3] = WS_BIT1;
        if( ((g>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+4] = WS_BIT1;
        if( ((g>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+5] = WS_BIT1;
        if( ((g>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+6] = WS_BIT1;
        if( ((g>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+7] = WS_BIT1;
        
        if( ((r>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+0] = WS_BIT1;
        if( ((r>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+1] = WS_BIT1;
        if( ((r>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+2] = WS_BIT1;
        if( ((r>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+3] = WS_BIT1;
        if( ((r>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+4] = WS_BIT1;
        if( ((r>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+5] = WS_BIT1;
        if( ((r>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+6] = WS_BIT1;
        if( ((r>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+7] = WS_BIT1;
        
        if( ((b>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+0] = WS_BIT1;
        if( ((b>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+1] = WS_BIT1;
        if( ((b>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+2] = WS_BIT1;
        if( ((b>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+3] = WS_BIT1;
        if( ((b>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+4] = WS_BIT1;
        if( ((b>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+5] = WS_BIT1;
        if( ((b>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+6] = WS_BIT1;
        if( ((b>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+7] = WS_BIT1;
    }
}

int fd = -1;

void WS2812_ShowRGB(u_int8_t r,u_int8_t g,u_int8_t b)
{
    int i;

    for(i=0; i<WS2812_PIXELS; i++)
    {
        WS2812_PixelSetIndexRGB(i, r,g,b);
    }
    write(fd,g_WS2812TxBuf,WS_TRANSFER_SIZE);
}

int main(int argc,char **argv)
{
	u_int32_t speed_hz=6400000;
	u_int32_t bitper=8;
	u_int32_t i;
	if((fd = open("/dev/spidev1.0",O_RDWR)) < 0)
	{
		printf("fail!!");
		return -1;
	}
	ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&speed_hz);
	ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&bitper);
	
	WS2812_ShowRGB(0,0xff,0);
	sleep(1);
	WS2812_ShowRGB(0,0,0xff);
	sleep(1);
	WS2812_ShowRGB(0xff,0,0xff);
	close(fd);
	return 0;
}

将c文件传入悟空派内。
然后通过GCC编译。
gcc spi_ws2812.c -o spiws2812
编译成功后执行:
./spiws2812

WS2812点灯

更多回帖

发帖
×
20
完善资料,
赚取积分