STC15單片機驅動WS2812

今夜無眠,寫此博客吐舌頭

我們先來看時序圖!



#include <STC15F2K60S2.H>
#include "intrins.h"

sbit WS2812 = P1^7;

#define numLEDs 8   //燈的個數
unsigned char buf_R[numLEDs] = {0};//顏色緩存
unsigned char buf_G[numLEDs] = {0};
unsigned char buf_B[numLEDs] = {0};

void RGB_Set_Up();  //送0碼
void RGB_Set_Down(); //送1碼



void HAL_Delay(unsigned int t)
{
		unsigned int x,y;
	  for(x=114;x>0;x--)
	  for(y=t;y>0;y--);
}


	 
//復位延時
void Delay50us()		//@22.1184MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 2;
	j = 15;
	do
	{
		while (--j);
	} while (--i);
}


//1碼,高電平850ns 低電平400ns 誤差正負150ns
void RGB_Set_Up()
{
		WS2812 = 1;
	  //經過邏輯分析儀調試的的延時
		_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); 
	  _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); 
		WS2812 = 0;
}

//1碼,高電平400ns 低電平850ns 誤差正負150ns
void RGB_Set_Down()
{
		WS2812 = 1;
	  //經過邏輯分析儀調試的的延時
		_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  
		WS2812 = 0;
}

//發送24位數據
void Send_2811_24bits(unsigned char G8,unsigned char R8,unsigned char B8)
{
	  
	  unsigned int n = 0;
	  //發送G8位
		for(n=0;n<8;n++)
		{
			G8<<=n;
			if(G8&0x80 == 0x80)
			{
				RGB_Set_Up();
			}
			else  
			{
			  RGB_Set_Down();
			}
		}
		//發送R8位
		for(n=0;n<8;n++)
		{
			R8<<=n;
			if(R8&0x80 == 0x80)
			{
				RGB_Set_Up();
			}
			else  
			{
				RGB_Set_Down();
			}
			
		}
		//發送B8位
	  for(n=0;n<8;n++)
		{
			B8<<=n;
			if(B8&0x80 == 0x80)
			{
				RGB_Set_Up();
			}
			else  
			{
			  RGB_Set_Down();
			}
		}
}
//復位碼
void RGB_Rst()
{
		WS2812 = 0;
		Delay50us();
}
//把24位數據GRB碼轉RGB
void Set_Colour(unsigned char r,unsigned char g,unsigned char b)
{
	  unsigned char i;
		for(i=0;i<numLEDs;i++)
	  {
				buf_R[i] = r; //緩衝
			  buf_G[i] = g;
			  buf_B[i] = b;
		}
		for(i=0;i<numLEDs;i++)
		{
			Send_2811_24bits(buf_G[i],buf_R[i],buf_B[i]);//發送顯示
		}
}
//某一個點顯示的顏色
void SetPointColour(unsigned int num,unsigned char r,unsigned char g,unsigned char b)
{
	  unsigned char i;
		for(i=0;i<numLEDs;i++)
	  {
				buf_R[num] = r;//緩衝
			  buf_G[num] = g;
			  buf_B[num] = b;
		}
		for(i=0;i<numLEDs;i++)
		{
			Send_2811_24bits(buf_G[i],buf_R[i],buf_B[i]);//發送顯示
		}
}

//顏色交換24位不拆分發
void SetPixelColor(unsigned char num,unsigned long c)
{
	  unsigned char i;
		for(i=0;i<numLEDs;i++)
	  {
				buf_R[num] = (unsigned char)(c>>16);
			  buf_G[num] = (unsigned char)(c>>8);
			  buf_B[num] = (unsigned char)(c);
		}
		for(i=0;i<numLEDs;i++)
		{
			Send_2811_24bits(buf_G[i],buf_R[i],buf_B[i]);
		}
}

//復位
void PixelUpdate()
{
	RGB_Rst();
}
//顏色
unsigned long Color(unsigned char r, unsigned char g, unsigned char b)
{
  return ((unsigned long)r << 16) | ((unsigned long)g <<  8) | b;
}

//顏色算法
unsigned long Wheel(unsigned char WheelPos)
{
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) 
	{
    return Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

//彩虹
void rainbow(unsigned int wait)
{
  unsigned int i, j;

  for(j=0; j<256; j++) 
	{
    for(i=0; i<numLEDs; i++)
		{
      SetPixelColor(i, Wheel((i+j) & 255));
    }
		PixelUpdate();
    HAL_Delay(wait);
  }
}

//稍微不同的是,這使得彩虹均勻分佈
void rainbowCycle(unsigned int wait) 
{
  unsigned int i, j;

  for(j=0;j<256*5;j++) 
	{ // 5 cycles of all colors on wheel  車輪上所有顏色的5個循環
    for(i=0;i<numLEDs;i++) 
	 {
     SetPixelColor(i, Wheel(((i * 256 / numLEDs) + j) & 255));
    }
	  PixelUpdate();
    HAL_Delay (wait);
  }
}

//Theatre-style crawling lights.呼吸燈
void theaterChase(unsigned long c, unsigned int wait) 
{
	int j,q;
	unsigned int i;
  for (j=0; j<10; j++) 
	{  //do 10 cycles of chasing  做10個循環
    for (q=0; q < 3; q++) 
		{
      for (i=0; i<numLEDs; i=i+3)
			{
        SetPixelColor(i+q, c);    //turn every third pixel on  把每一個第三個像素
      }
			PixelUpdate();
      HAL_Delay(wait);

      for (i=0; i<numLEDs; i=i+3) 
			{
       SetPixelColor(i+q, 0);        //turn every third pixel off   把每一個第三個像素關掉
      }
			PixelUpdate();
    }
  }
}

//Theatre-style crawling lights with rainbow effect
//帶有彩虹效果的戲劇式爬行燈
void theaterChaseRainbow(unsigned int wait) 
{
	int j,q;
	unsigned int i;
  for (j=0; j < 256; j++) 
	{     // cycle all 256 colors in the wheel 在輪子上循環所有256色
    for (q=0; q < 3; q++)
		{
      for (i=0; i < numLEDs; i=i+3) 
			{
        SetPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel off 把每一個第三個像素
      }
      PixelUpdate();

      HAL_Delay(wait);

      for (i=0; i < numLEDs; i=i+3)
			{
        SetPixelColor(i+q, 0);        //turn every third pixel off  把每一個第三個像素關掉
      }
    }
  }
}

// Fill the dots one after the other with a color
//用一種顏色填充這些圓點
void colorWipe(unsigned long c, unsigned int wait) 
{
	unsigned int i=0;
  for( i=0; i<numLEDs; i++) 
	{
    SetPixelColor(i, c);
    PixelUpdate();
    HAL_Delay(wait);
  }
}

void main()
{
	  
		while(1)
		{
			  rainbow(45);
        rainbowCycle(40);
        theaterChase(Color(0,0,255),80); // Blue
			  theaterChase(Color(0,255,0),80); // Blue
			  theaterChase(Color(255,0,0),80); // Blue
    		theaterChaseRainbow(40);
				colorWipe(255,255);
		}
}


以上是全部代碼





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章