|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机驱动WS2811彩灯源程序和实物图: d0 @* e' ?. ?' e
# j. V, u) ^' \9 v
, m5 k, V7 l5 k: x H/ a. M3 r3 r* ^) mWS2811是一款可以级联的RGB三色LED灯。只需要一根数据线就可以控制多颗LED。现在发上来整理的库函数,可以直接调用显示函数。3 _7 q" X. i4 c4 f& o
6 Z+ T. {/ u* w6 S5 `5 i. W
- F) E6 C8 ]% `& W/ P9 E* E4 N
WS2811.h
7 k7 ^) v( q5 L2 v2 g" o" E' Z2 f0 ]# ?3 N5 y0 p
; k! M: M0 p; v
#ifndef __WS2811_H
0 B5 t; {9 c# E#define __WS2811_H
$ L. u& w, K4 J8 k6 {6 Q2 M# d% X#include "sys.h"4 r, M( d- P( _: l' X
+ n8 H4 U2 F5 r% q% Q4 N, X2 `# o Z; r# ?# |
( k1 n* t# r4 c% j$ `6 x0 R9 `$ v& N d* e2 G8 X
#define White 0xFFFFFF // 白色) X6 u9 Q; g- B; l1 D& U7 M" N
#define Black 0x000000 // 黑色
$ I$ X( V: [4 H' e#define Red 0x00ff00 // 红色
" T/ ~+ B' J7 W#define Green 0xff0000 // 绿色
; \* a4 [% I; A' E#define Blue 0x0000ff // 蓝色9 [: k6 l2 q. _) u! E2 _
7 ?# |# z& ~# ^$ c, @8 e5 s
) g1 Z# C1 _( w7 n+ p& p! l. ~; p5 s! y7 e' ~ w. s; \
7 ~& T/ ^; y4 d
#define nWs 16 // 有多少颗WS2811级联; Z3 \5 h! H0 X' a& t+ z# E+ f0 l
/ k5 z/ ^" A4 u, z. T# `/ k n
) A$ y$ Y5 i: R' y8 l4 M8 Qextern unsigned long WsDat[];3 i; P) o/ z$ p k% m; G" t
; }# ]5 G# Y) a9 Q4 u
6 R" ^. T( @5 D+ f, A/ M9 m
extern void WS_Init(void);. w( `. W; T8 E" U9 f7 t
extern void WS_SetAll(void);
& I) G' `& K2 B% I0 Y, R; y; P1 vextern u32 ColorToColor(unsigned long color0, unsigned long color1);) V5 o8 p: E N9 B l1 I
4 ]% [- a' {/ d) p6 ?9 \2 t1 B& A& f
( P4 {* m, H4 I: {
#endif" L9 e4 c2 N" S5 \# ~
" e h( A, K/ d3 S8 l
2 y+ i& J; ^3 T
, l2 o) \% ^, D/ o) [* h
/****************************************************************************************
]% D) Z# a3 S4 b3 n6 ~4 [% _" x3 f* WS2811 彩灯驱动函数( W; f) A' a/ x! g5 n9 ^' ]8 J$ `
*
9 l4 u! ^) c1 w' g3 z, K* 调用方法:) o" |1 x& ^$ W0 _$ W
* 修改宏定义: #define nWs 1 // 有多少颗WS2811级联
/ U4 g$ H# E& P* ?6 C% h* WS_Init(); // IO初始化; \ u) G( M) L7 B7 X. d
* WsDat[0] = 0x808080;//显存赋值
: Q/ Z, D/ e z) ~* WS_SetAll(); // 发送数据, v# T( f; `- z. G( [/ l, E( ^
* ColorToColor(unsigned long color0, unsigned long color1);// 颜色渐变算法+ l+ c0 d, \9 W1 |
*. b! ?2 n3 R) P9 r* |- `
* 作者:星希望(已校验)
; U- w2 _0 T9 ?0 P/ v. Y* 日期:2015年6月24日* ?2 e y5 x+ I9 M' p
****************************************************************************************/
3 \! }% N7 Q; F5 {. }#include "sys.h"4 r4 S& I! [: S6 b0 @
#include
; `( l+ A; O4 t3 N3 N& v$ Z#include "WS2811.h"1 X1 _. ?" C- l# f/ g
#include "delay.h"
) Y2 @6 \* G! w: d. Z2 ?
0 h! U- A. X9 j" y/* 显存 */' P2 L: Y; E( _
unsigned long WsDat[nWs];
. D i9 A. ]' R! g6 Z9 ^
* s' v! y3 c5 V B: U3 v
! ^7 i4 C# C! U
, c9 A% C6 m4 x ^ }6 `' Z; h* O, \, T
/**************************************************************************************
U2 g# s+ O8 @8 c5 O& U* IO初始化(移植时请修改)' v6 K) S2 p# ^# C! w, k @" }( F
**************************************************************************************/
a$ t. I9 }' T( j2 f# N$ Jvoid WS_Init()
0 i7 A0 u5 P# ~! D2 U{9 T) m8 v2 c) X! i
GPIO_InitTypeDef GPIO_InitStructure;
2 D# ~4 F0 \( c5 J$ t
; h$ \! ?/ {: ` //端口时钟,使能
; |1 B" e$ A1 n5 T: o( \ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); 2 c8 j3 v. K* ] D2 p5 z0 q
1 H. Y. b$ n, T$ {+ V' c* J: C5 [0 R6 W( {% o i
// 端口配置" a, E; B4 z+ ]% N
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PIN
- B- ]. B1 z& t! T& ^ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
4 ]. E1 v7 W+ R GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz3 y& q8 C. f+ k- A5 R5 x
GPIO_Init(GPIOA, &GPIO_InitStructure); // 根据设定参数初始化 ! k0 u0 m0 Q0 [9 X! y6 W' z9 x
}+ ~. X8 Y9 D; i9 u
1 X% t& R0 ?4 A! A9 }* c/ O1 S9 z9 w
# r! e( K& y: W8 X
/**************************
8 V L( h. k) j7 y. D. b1 k* 内部延时: x8 O, q" r$ T
***************************/
% ]& n# k. ^$ k; m+ l, Xvoid delay2us()% m0 G3 {, G7 C( u+ D% p
{
$ s8 N" }) ]" s3 x unsigned char i;, l q- b7 ]( d
for(i=0; i<12; i++);
& f9 d: }& Y) G}1 k" [+ t# _5 E" x5 A
void delay05us()
4 s0 r6 U" w5 E5 E{9 { G4 l, v; a5 t' ~: L7 S
unsigned char i;9 }! t# d$ c: A% Y( N w+ |3 _
for(i=0; i<1; i++);
0 ~* n% u. k2 u}
/ P6 \7 d* l0 Y6 ?. `6 Z% S/ [( h3 L) D
( v" [7 X, z. @+ }& M' }6 V. e( t: g9 i, @! e! s
/***************************: F- c# Y0 K' P9 d+ Q2 N0 b H
* 发送一比特( P! w! D# u2 C# o
****************************/
. F- l& ^ R" @$ C9 Wvoid TX0() { PAout(0) = 1; delay05us(); PAout(0) = 0; delay2us(); } // 发送0
! X" w1 @2 C" e# R$ Lvoid TX1() { PAout(0) = 1; delay2us(); PAout(0) = 0; delay05us(); } // 发送10 w- y& s+ c; t8 q2 R0 b
void WS_Reset() { PAout(0) = 0; delay_us(60); PAout(0) = 1; PAout(0) = 0; }
4 J6 I+ D) U4 r3 \% K- X. T7 h' M3 q' P; q8 L
' Z+ {, ^9 j9 O# d% Y
/**************************************************************************************. H* ?3 z' w, U9 |3 D( t
* 发送一字节5 P6 i9 z+ z+ @7 t, J' l
**************************************************************************************/
$ z& J" \1 @2 z! }! S; w! Vvoid WS_Set1(unsigned long dat)5 r4 [5 [+ k$ n. _
{8 \2 k& y9 N3 x6 u
unsigned char i;
! r% S3 I8 C- x# J7 c " v" E" @# {+ P, X
for(i=0; i<24; i++)$ d9 y2 d ]2 X- G: G
{
8 w: {7 b- \( x: N" c+ d. x if(0x800000 == (dat & 0x800000) ) TX1();. {+ q4 j- ?/ k; w8 Z
else TX0();
5 B2 z, t; s1 I7 o7 b4 k8 l dat<<=1; //左移一位' G; ~0 T) I) {2 l
}
: H C" e2 b- B. z9 l* V* ~}
7 ?5 P+ f4 V* \/ _* K( I
: K6 }% ^& f! }- w! g0 d* e; j4 i$ v0 H: U/ i. d) A, x8 d
/************************************************************************************** b* B- x) n d3 \. o
* 发送所有字节, H5 o I" e' G0 A* ?
**************************************************************************************/
1 Y7 t, z. W7 r- pvoid WS_SetAll()
- w% X$ `: ?1 ^- z{9 f. s6 F3 C* v' \
unsigned char j;
" y# R7 G! i9 s, K: s
. N. { q8 C3 Q( c" w4 g9 h for(j=0; j<nws; j++)" q4 c9 c7 v' Q8 i V9 R, {+ H( o7 S
{
O- g$ K j2 D1 \4 M WS_Set1(WsDat[0]); // j / 0
9 a( P: H. R6 b4 [ }# g- I- j/ P- J$ g% c
WS_Reset();; H' i2 ?7 c6 L# t2 r2 f b
}7 R7 O$ Z) l! V$ c9 b& o
; G3 o3 O+ Z( t* [4 g
+ J' x3 k ^$ L$ H# j4 H
8 ^! D: L% h3 q' W2 E8 q
1 t# P5 [4 d9 I+ W& r9 P
0 p7 o) }& H5 o4 _: F! A
* A/ ~2 ~4 y m2 F
; z+ M9 e+ |0 [) j8 C1 v: \' a) {3 j$ a
: e$ f( S$ Y" S
?/ |; R5 D' D6 i3 B
6 K+ A, U5 \4 q( S; D' Z
4 T' V+ x. Z" A6 U+ l2 j$ X+ S
9 y9 G4 U8 p b2 o& ]) F6 }3 [0 F2 r) V" g+ Y
. L j$ Z4 [4 K+ e
# f3 [! J9 A: y7 U/ w9 z( |3 j
4 K1 A% e9 C: C4 N$ f: s$ ^' @! L
4 n" ^2 Z: A T" b: o
/********************************************4 N0 N* E. Q, J2 I/ {3 c
* 求绝对值
( o9 V0 Q+ ^( \. t********************************************/
6 D/ W3 }: b3 C2 }unsigned char abs0(int num)
6 D# I% k6 b) ^; y7 d/ V0 o, x# ?{0 y7 J8 R, W) r. m" f! \, I% U0 N8 n) b
if(num>0) return num;7 ~" e( O) Q: k
$ ]. ?0 F0 u4 g5 i, y7 m/ f3 L; f
num = -num;% H; d2 k4 ~' a, t# e
return (unsigned char) num;0 y! H! S: [) F7 G! i" }
}
- K8 z) w% H( s
1 D, T+ w7 ]4 y( n: p4 k; P) T g5 M+ a1 |2 |5 d& M( d) @
/***********************************************************************************
; K5 z& K) h) ~$ Q, d5 k* 颜色渐变算法& b3 g6 U! t/ i D; h9 S3 f+ C
* 误差 <= 27 s$ ~9 X! m. W5 ~3 G
************************************************************************************/
; d; Y) y4 }* w9 Tu32 ColorToColor(unsigned long color0, unsigned long color1)- _9 p# Z) r2 i5 x& K; h
{- j- b) c- G1 W8 i1 K9 D$ p; g
unsigned char Red0, Green0, Blue0; // 起始三原色
$ \/ J+ G$ s! l) Y. Z unsigned char Red1, Green1, Blue1; // 结果三原色" b8 W6 y6 X5 ^( {4 ]
int RedMinus, GreenMinus, BlueMinus; // 颜色差(color1 - color0)+ F5 P9 d1 J" m" r+ d
unsigned char NStep; // 需要几步) q- g; c0 x1 Q) Y- U0 W
float RedStep, GreenStep, BlueStep; // 各色步进值
! \! R& T# h* t% z; |) i% b* a unsigned long color; // 结果色1 i2 e& @9 D9 j( s0 c
unsigned char i;
* h( i/ ?+ A. x0 q/ M! W N- m* B 5 v0 p% J z( [7 u7 B' y
// 绿 红 蓝 三原色分解; c9 W" E- j M
Red0 = color0>>8;: U0 r2 b4 c1 M: p7 s0 c2 h: g5 W
Green0 = color0>>16;! v( K' z8 O% k5 [2 m- d! X
Blue0 = color0;
$ w) a( S* N7 d7 H: e t
" p2 l8 d5 g) s7 \5 p9 j! J7 i Red1 = color1>>8;
0 L# g3 a4 K# S/ i! ? Green1 = color1>>16;
- X' a4 j$ ~# ?5 ~+ N Blue1 = color1;( l9 }1 z6 s/ k) ^7 a3 m
2 J) _) h$ C0 k. w7 k+ P8 R
// 计算需要多少步(取差值的最大值)
8 H+ G3 A" S) G. Q9 I' O RedMinus = Red1 - Red0; ( z" E' y2 l8 F0 v! f. ?
GreenMinus = Green1 - Green0; % X- J: b+ j T4 J3 C I9 d( C
BlueMinus = Blue1 - Blue0;$ u+ e4 l' V% P
, v& P# o6 S$ y9 M2 f i
NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus);
1 X0 a0 i( x8 z# v9 A2 r NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
, w, l4 E+ y" D8 c L8 s
+ Q. `+ R5 ^" j& h8 f# K // 计算出各色步进值! I! d" ]7 g% _! P8 q
" [# C$ i/ y, @3 W! d3 h
L+ B3 a) |, g* ?) N, P# O. i1 w. \& g; K; T. v/ k' ?
: t' Y1 B2 h* A" n( ]6 H…………余下代码请下载附件…………' O+ q# j. P& S* W/ |0 t
$ m) g# [, R# T
9 b3 ]) V% D! e
$ g1 _6 G/ }% q% U" Z$ d: I
& _* ^4 D, z/ j& c% U# a9 M, V& l
) f; ?' f6 E. u, T. u$ r; _; R2 ~) R% X z
下载:/ a. r, k) _; L/ f: z6 R
' p, T# l! ?( p7 c! ^
% g- x6 [9 S2 n% W* t$ W; i0 ]6 w1 _; ~2 M+ g, C
|
|