|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机驱动WS2811彩灯源程序和实物图% z8 |0 o* O- B. r! {! e! }1 Z3 }
8 X) `. U) V! x7 p, e4 l
# C6 r7 @ t0 S! @WS2811是一款可以级联的RGB三色LED灯。只需要一根数据线就可以控制多颗LED。现在发上来整理的库函数,可以直接调用显示函数。
3 r, B: V. B2 P! G4 N
, j3 Y9 m4 y( C0 g
* K5 n" E( T( U. FWS2811.h
# B" D2 S T3 G2 P# g% p" Q
0 E Q' U- c2 q6 x* X
: ~4 C8 a0 ]7 ?/ d( \( U7 Z6 t#ifndef __WS2811_H2 i: j0 Y1 ^4 A5 \3 b& T
#define __WS2811_H 4 l/ l8 E9 Y3 y
#include "sys.h"$ I h" d3 P" c4 S9 q) J( {* v, [
0 {% ]# y, M) \# z; a# I! e; k( Q8 M! C, q8 r
a+ M m; m$ e% o
' x/ M5 H2 M: e6 U7 `1 L0 u#define White 0xFFFFFF // 白色3 N" q2 ?( D% v% b0 ^* w
#define Black 0x000000 // 黑色* X, R2 w4 R4 R8 m
#define Red 0x00ff00 // 红色* e' u! @) C" Y; t, n7 W+ `2 g' J
#define Green 0xff0000 // 绿色
' q) }2 x$ ?9 O- e6 _) f. k#define Blue 0x0000ff // 蓝色
: B0 T' u8 x% @+ l3 n" W& ^! m; v+ A$ J5 e% y
3 v, c% d ^- d6 d9 N9 C0 o/ @3 k+ X3 K0 x
* w& `" }+ B9 `( N' V' ^4 G#define nWs 16 // 有多少颗WS2811级联, y, m! `/ [: X- n p9 E
/ {6 r- ?4 _2 \0 _ v4 F- d9 K4 T9 y5 c, H2 ?- R# |
extern unsigned long WsDat[];
$ P" O! Y, d- m7 n" {8 d L! J5 v/ `# K6 g0 ` V7 \# D* \: w
% S" _0 ]; C& m# b
extern void WS_Init(void);( r/ e# J' @& J( Z0 O
extern void WS_SetAll(void);
9 L7 f* x- `9 w- ?extern u32 ColorToColor(unsigned long color0, unsigned long color1);
3 E- n [6 M1 j5 b' H( k, H: K. o( [$ Z% ^! z* O; I. A
r1 K' w2 d% D
1 |* Y0 z, u$ A& `#endif3 A8 k9 g8 D9 r1 N$ Z
1 ]. T% k9 h# J
) o6 T: b- n* A5 g/ N W% h1 F8 _
9 u& h/ y4 @& \ X( m, Y" ?+ \/****************************************************************************************
2 O/ f. o6 Q5 F" S+ X1 M' A/ B3 O& g* WS2811 彩灯驱动函数$ s0 Q+ P7 n8 D' C
*
8 s% q/ ~2 v9 }7 ^* 调用方法:
, t2 N3 D, w* t# v* R @+ s7 q* 修改宏定义: #define nWs 1 // 有多少颗WS2811级联# Q$ l, b0 O8 ^4 K3 |
* WS_Init(); // IO初始化
9 w+ f' e: ~# J4 z* WsDat[0] = 0x808080;//显存赋值
; H6 b9 C2 \& C0 u: ]) @$ P0 I) g* WS_SetAll(); // 发送数据1 G# d, K ]# l3 ?9 U) {6 H$ x- D
* ColorToColor(unsigned long color0, unsigned long color1);// 颜色渐变算法4 l0 u2 _# L/ o" r$ M: Y
*8 `, k4 F& |# Z- [+ G
* 作者:星希望(已校验)
! D- |' a* W5 y) B$ F* 日期:2015年6月24日7 ]1 |& F* Q# ~$ e' X
****************************************************************************************/5 l( I! B: F. ]. r
#include "sys.h"
1 U+ ~. X9 L3 P5 D K4 T% l, S+ F- q#include * ~5 h. ]/ I3 f M# p* {5 \
#include "WS2811.h"7 I1 P. f: j- K
#include "delay.h"- K {1 {# ^5 ?
0 Y" b1 H, {5 n
/* 显存 *// n% Y- O9 }2 M& K
unsigned long WsDat[nWs];$ j& Q8 g4 w! p3 y
, ?4 A6 D6 |* I- x. h, c6 a
5 R9 e. ?( B6 m& D* l5 B: N6 n0 E8 O
2 Z+ k, M" f) |. u. v' v0 o/**************************************************************************************. S& R- L8 J. Z: V$ y! K+ U8 ~
* IO初始化(移植时请修改)2 q7 k" d) Q0 }& o6 w* ~. Z
**************************************************************************************/
7 P! l/ ]) K# F8 d( u0 Vvoid WS_Init()) a! j7 ?8 T2 @6 ?4 v& O
{
" N) C; I. {! I' H) _. S. g GPIO_InitTypeDef GPIO_InitStructure; # V7 d6 B4 X. T z
\- R9 u" V8 e* I/ \2 W- Z& i0 k //端口时钟,使能" B; ` j$ N9 v( B; o8 `& ?8 d9 P
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); 4 J; _9 u1 Z: H
' Z" u. P8 s$ b- W5 S6 B
3 l [) M& C5 V: W // 端口配置8 ^7 b4 s3 ?0 y0 D( @& H
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PIN, _; [0 j" e% I# p E) `! U
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出$ T( D% H/ _% t( l' `( D
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
+ H6 s1 b3 h9 Y4 ]( g" I* ^) R GPIO_Init(GPIOA, &GPIO_InitStructure); // 根据设定参数初始化 8 P6 W2 _) Y1 H# s; S$ d5 T0 H
}
! q5 j4 ], O( [4 o+ q b3 J7 w
6 d+ s C* l( L# V& d; v' P2 k U
; a; |5 T; J3 j" O. N7 K/ z/**************************
9 Z8 K _1 M: v. J# u6 A. r8 l* 内部延时
! O* W- T) x: g# W0 e***************************/
% l) ~3 s, [" qvoid delay2us()
m8 V9 `7 G5 ~1 f; n% j{$ x+ I& h; s& ^4 f% C. X
unsigned char i;
. @0 {( q+ C! _2 ~' o for(i=0; i<12; i++);1 Z0 ^+ r* J9 L7 n- Q- _9 Y
}
: v8 F3 g6 L. n* b0 Mvoid delay05us()
# d6 L* O! b- x, i9 [9 O{
+ O4 v2 J- G1 |% s unsigned char i;+ u% D9 i$ b! C
for(i=0; i<1; i++);" \" Q$ F9 P( D8 d y" @/ @
}/ C+ C# B8 s; i" U
1 f. I# m+ H4 `1 Y$ L; k8 c. N. o" u# f, }
/***************************
. ?: ~3 d1 T* Y' b* 发送一比特
8 j0 ^6 r" t6 R8 ~****************************/
' h5 a5 N# M# T8 avoid TX0() { PAout(0) = 1; delay05us(); PAout(0) = 0; delay2us(); } // 发送0
# g8 [2 r' ?+ F0 B2 Pvoid TX1() { PAout(0) = 1; delay2us(); PAout(0) = 0; delay05us(); } // 发送1
7 Z5 g7 Z1 J* d& Y5 `% T5 avoid WS_Reset() { PAout(0) = 0; delay_us(60); PAout(0) = 1; PAout(0) = 0; }
* N7 v4 V) g. F6 r2 s/ E B7 H- E- O: U, q/ N
1 x- F) b( [6 r1 |& W/ w" Q6 r" }- c/**************************************************************************************: l2 ~6 a$ q* r
* 发送一字节0 E' S/ _( V2 q' |% o1 g
**************************************************************************************/7 W9 h3 \# X& W
void WS_Set1(unsigned long dat)6 E" j7 q3 y; I# a
{
- o! j) G' e& `5 ? unsigned char i;
/ I1 h. c- M: ]8 s$ K' N u4 B3 o5 h % D/ F! o. @3 f
for(i=0; i<24; i++)
1 b7 J* _! f9 C {5 z6 \! c( G6 q* G4 Y
if(0x800000 == (dat & 0x800000) ) TX1();
. I6 H" o4 X. c4 j- G else TX0();
2 p: q5 w8 e5 r, ^$ C dat<<=1; //左移一位
1 r1 A2 w5 X, h9 Y# ?1 A+ V$ } Q }
. M a# m2 P2 c' _8 R1 f}
4 b1 {: J$ L1 `, ]& X' A _
5 K" t- h! U; [# o4 N& X m. v6 ~& l: e6 ]! P3 ^
/**************************************************************************************
7 v( m$ e- k P* 发送所有字节8 c% G( E& A8 A4 O4 X0 o+ u1 l
**************************************************************************************/
0 f% X' ?4 {& t$ G+ P" _void WS_SetAll()
* J; X: L" T$ L{1 y/ B6 x/ K* i
unsigned char j;$ R9 E" H) Q) I# ?% P
3 v; c5 F. V0 G
for(j=0; j<nws; j++)
9 I3 `! F; I$ f5 I! P" G9 k0 X {5 n) E. X- |/ H6 f
WS_Set1(WsDat[0]); // j / 0
- O9 Y8 u8 j" R q3 i }4 ~* x* H7 O; l# C% k
WS_Reset();
2 I+ E) h+ s6 A- u}
; J0 a4 K, A+ D# k S) A! P( p; ^$ D5 k0 I" U% ^/ c1 g8 w
) D/ l# X Z, s! c: n
7 q" s$ X2 s: N5 u* i" r1 \( b4 D% ^; { Y2 X
0 m8 m5 D+ ]/ d- G7 n7 B* h* ~+ J
+ S) P0 W# i$ v$ F5 \0 M
" B5 V4 F! |/ B7 E; }, z9 p [: ]! E
3 e. J) V8 n& z1 K1 T
7 k( {9 f4 L& C$ j" h9 a4 Y x
2 ] m0 {0 x( X# ], O+ u! }" o+ E- a" E
6 W. C4 G" |; K% ^
{, M8 j1 I: e! ?( _% l' r
' `: c4 \3 A4 J% B% n0 Z5 A4 O( n4 Z) A1 C+ b+ Q9 X1 P
3 {; Q3 f# G, M2 x
8 ~; x$ F4 ]. [; l/********************************************9 W2 ~" i3 L( {/ L7 w! Q5 Z" l9 j3 i
* 求绝对值
) g9 k; B. m6 |% \********************************************/
9 _) h( S& i- v+ S8 funsigned char abs0(int num)" ?* A( z' W) o8 l6 v A
{" k- f! J1 j; ]; Z
if(num>0) return num;
4 O- o6 F9 W# u s! v& d ! w3 M" G1 X& p* i* N
num = -num;% D8 ` W! X0 U9 K, s. T
return (unsigned char) num;
9 w* ]/ E9 B" q8 S( J: |}
( f) g* Q' A' t( a8 N+ Q" Q$ B3 M/ P5 J: R
0 ]% ?, S) P* a2 J0 o0 B
/*********************************************************************************** t$ \1 G' F* M; Z: Y( W7 ]
* 颜色渐变算法
) j( O D# y+ u1 T0 t, v3 w, ^: `+ D* 误差 <= 24 L- K9 _5 V) O, q3 ]3 K3 j
************************************************************************************/
! h B$ c0 [) l ~! ^$ Gu32 ColorToColor(unsigned long color0, unsigned long color1)
9 _' z, _8 q" r; h. U. w/ h1 v{) C( M0 V7 P1 n3 d
unsigned char Red0, Green0, Blue0; // 起始三原色% R0 |' ]# n" q0 w' k2 _
unsigned char Red1, Green1, Blue1; // 结果三原色0 f6 ^6 @# B3 ?* T6 @/ y/ X0 g; _
int RedMinus, GreenMinus, BlueMinus; // 颜色差(color1 - color0)
% D, g& ]& |! b; x2 c2 V ~ G- r unsigned char NStep; // 需要几步/ Z' M x+ V, d6 \$ P/ w
float RedStep, GreenStep, BlueStep; // 各色步进值
4 i; Y1 u4 F5 a: N8 L1 L( k/ W0 H unsigned long color; // 结果色1 @* ]: G# w- H$ t, X7 {1 Q
unsigned char i;
4 i3 U# ~9 z/ v
+ e+ [" s% K, N# D% X8 V // 绿 红 蓝 三原色分解1 \9 c( G5 [$ d& Q% g4 b0 }
Red0 = color0>>8;
6 B( U0 [. c1 m0 A6 a Green0 = color0>>16;
) R7 [2 D I7 Y$ l Blue0 = color0;/ Y: E, I" k& \) q: u6 [6 c
. d; R8 {3 R3 S L3 B
Red1 = color1>>8;. w: r! W8 m1 A" f5 i
Green1 = color1>>16;
9 R9 N5 k3 t" G* ]0 U0 c/ _ Blue1 = color1;8 X% w" |2 f) }) t& A0 K
! K, \9 S j$ O. [2 C! c // 计算需要多少步(取差值的最大值)
0 U4 A$ H' m+ A$ ~. o RedMinus = Red1 - Red0;
! F7 u1 l# N$ A- z9 V0 }/ U GreenMinus = Green1 - Green0; 7 ?% l, D# m/ B j; E
BlueMinus = Blue1 - Blue0;
- h9 T4 `5 k4 a- C
! U5 ]' H/ P6 v1 b. }+ U: A NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus);
; x: ^5 w1 j6 h' e% B: X NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
8 Y6 \2 ^! S+ _
) |2 s$ D3 t' s7 L. u1 Z // 计算出各色步进值
0 `2 S6 m' J/ V* ^( A1 T! @
. d u4 V7 f, c. {
& V' U4 X# f6 P
3 m; e9 v4 c. ^. U5 L8 Z8 u# Q, c2 X% p; u b
…………余下代码请下载附件…………
& U; e* o- T& m! i- B1 l; q
' @3 x( v2 r1 }2 E
/ R% E( ]3 O* g a3 G) Q2 E' \! |+ R7 s2 s, V% o
: [2 o# Y7 e' J, d. L6 N( q4 x/ w' e$ J; ~( a. p9 E0 w# Y
* V4 t2 b* u9 n p4 ]- X( E* B
下载:
# | f, `' b+ r6 ]+ W4 @* S; g1 a: W
* x) S* r/ g$ F( i
8 _1 N4 I$ Z6 J# Q: G; J7 H* v; Y |
|