|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机驱动WS2811彩灯源程序和实物图1 E$ {2 E- T% c" X) S8 w
& S" @" k/ i4 b6 d, f
! m# r* b! }' g
WS2811是一款可以级联的RGB三色LED灯。只需要一根数据线就可以控制多颗LED。现在发上来整理的库函数,可以直接调用显示函数。9 F- @# x+ T/ O+ U* ?
& k6 }( M" ~" `$ H
: D, C/ i v) t# ?+ _
WS2811.h
7 w. l* I% v4 Z3 T7 ]' P, |& e8 J/ I# h
% Y* v5 B& J, B2 Y
#ifndef __WS2811_H# A% ? b1 ]: C1 g- m2 ?
#define __WS2811_H
v& G; S/ i- ^' b% l! K! e2 H: m: v#include "sys.h"
) K8 N$ }. e2 y5 a2 ?; x! o
& @2 t6 I; K$ N+ F2 L8 T+ p
2 e! X8 A& S! V: @) a' h9 S+ g: R1 _3 m
2 ]4 ~# ]: [3 C9 G3 s3 O
#define White 0xFFFFFF // 白色% N N d9 M. S1 E" l
#define Black 0x000000 // 黑色
# `- x) X$ C4 q' [#define Red 0x00ff00 // 红色$ |. p. q( n* |- ?/ Q" a8 T) Y+ u
#define Green 0xff0000 // 绿色
5 ?1 k0 Z$ |+ ~7 B3 h. t: v! E6 c#define Blue 0x0000ff // 蓝色
) Q2 z& s, t% A% O' S s3 F( [; o3 Z6 z" b) k9 s
) B: u: G/ M8 p z9 d, C! E) K
* f8 s+ }1 W, j& r) m4 R% S
! I" |& `* g4 l5 w9 k6 Z d
#define nWs 16 // 有多少颗WS2811级联
2 L9 \# c4 R8 a4 ~4 A1 t& W* \: ?4 b6 e2 i! I7 K* H; c
3 L* ^5 \$ [( C$ |% Mextern unsigned long WsDat[];9 ~0 u- y- A( C) T1 L
; _! L0 m/ Z% s
: M+ q: D3 w+ ` H* j- f, pextern void WS_Init(void);9 g% ]: q# \+ |$ G# e) a s% J, d
extern void WS_SetAll(void);* D/ t7 f. J4 Y3 e
extern u32 ColorToColor(unsigned long color0, unsigned long color1);1 i- y6 b6 ~. Y5 x% b3 Y1 Y$ \. {7 O2 ?
! A$ [# x4 m# h& k l2 s* \$ L0 K/ j" Q' ]
# z2 ]8 k5 a3 @+ x3 x
#endif
: U) U5 i: t' I9 x2 K+ h) Q+ p
$ q r2 y3 ]) {
% T0 U6 @' ?, c& A- u0 n2 u; h& B8 B* ^
/****************************************************************************************7 ^9 B) }% E/ G# f6 w- a
* WS2811 彩灯驱动函数) P9 Q% l3 x2 ~ m8 y
*% i! j& n# H; L. D0 B6 s9 w2 q
* 调用方法:
- G# e* l% E6 N* 修改宏定义: #define nWs 1 // 有多少颗WS2811级联2 p0 v, G9 r6 L. j& o6 W
* WS_Init(); // IO初始化, d t, T3 F) s; }5 L6 ^2 R7 ^
* WsDat[0] = 0x808080;//显存赋值4 j) [' C1 W- ?; Y4 q/ Q
* WS_SetAll(); // 发送数据
1 p1 l" P1 U2 A% M$ d' Q- c/ m* ColorToColor(unsigned long color0, unsigned long color1);// 颜色渐变算法
0 i2 m7 }5 z8 f5 E' Y/ v3 O*
, l7 o( o/ P9 ~" s7 z/ J% X1 b5 D* 作者:星希望(已校验)% B% k) M' c: g
* 日期:2015年6月24日8 f7 v" s9 k# L% I" F! x
****************************************************************************************/
/ |5 Y. A# _$ `) f' O" R; q J#include "sys.h"$ T. j6 v, K* @ K; j3 a4 V x
#include
0 y2 Q9 N, B3 ?#include "WS2811.h"& m: Z y# C9 t0 | k
#include "delay.h"
8 ]% f1 o" b7 P: Q( D4 H6 h2 H # P9 ]/ V- h: l/ |
/* 显存 */
6 h( H) C4 n- L0 m& [6 f1 N/ xunsigned long WsDat[nWs];
" ^! A/ J6 ~7 F
9 K0 n$ i0 H u1 [4 Q( N& }5 R& H {5 {" E
1 c- A3 T. L+ H# K4 N0 y, J) ^! p& J7 W# q! z1 G1 n
/**************************************************************************************. i8 g5 S- |* c7 a
* IO初始化(移植时请修改)
) u/ H0 [5 a' J3 d4 Q**************************************************************************************/
2 `4 _, R' c- u3 k' |void WS_Init()
! ?& H4 h0 A, N$ V8 O% W{% D. _7 g% z( y$ K8 n# z
GPIO_InitTypeDef GPIO_InitStructure; N* B Y; ~9 ]& c4 p
9 K4 D1 g/ a$ K O. L4 q @/ @
//端口时钟,使能
5 m5 ~0 h2 E' Q7 Y RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); * \: S+ @5 U3 d0 x3 {; Y% k9 e+ p
' a/ _) O& ]# ?- s
* y7 s s$ Y! ~& C9 W5 e$ I
// 端口配置
& |* v0 x) C b7 U GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PIN& g7 f: x U" k# ^
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
I% N( x. P4 m1 O* ^ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz, q8 s- `( ~( |
GPIO_Init(GPIOA, &GPIO_InitStructure); // 根据设定参数初始化
+ Q2 d0 o }( a4 v# k( h/ X}) ]: b% ?8 D0 l6 p$ S; o
& \4 i8 H, s) t- I* [% ^' a
7 C* w# p3 Q$ g7 b: N* n$ v
/**************************: C$ N( _- ^5 V. C2 I/ b/ D- { u
* 内部延时
5 }5 O* N2 I% A- i* [& t***************************/
9 Y3 h0 c# |' c4 j- P( J8 ~8 }0 d8 rvoid delay2us()" o( J" M& p3 q. Q Y
{
2 I" I5 U4 H% J) @5 D& r! W8 p6 Y unsigned char i;; U8 s" H/ r9 l8 s9 B& b2 `
for(i=0; i<12; i++);" r T( n4 Z, P4 c3 @/ v: N. T$ o. O
}# T# a; x- E2 b1 n$ w: m) g
void delay05us(): F9 y3 ~- l* q& l/ T
{9 C% p1 Z" C. K, u) W% a, d# U, o( K
unsigned char i;
! k5 Q! k/ G3 P4 [0 V- y for(i=0; i<1; i++);$ j% a# l& R& M, s) a
}# w, T, Y' x/ p$ b0 S P
5 h1 l3 ^' X& C' G6 L3 S
5 q! c$ t4 W+ b6 `' A
/***************************
9 ?1 y/ m( x. Z+ M f( C* 发送一比特
2 b) |2 V ~7 M5 X****************************/
* ]: x( c# X: n, Gvoid TX0() { PAout(0) = 1; delay05us(); PAout(0) = 0; delay2us(); } // 发送0/ m2 g; C+ }$ L( O
void TX1() { PAout(0) = 1; delay2us(); PAout(0) = 0; delay05us(); } // 发送1
% N4 G) n l/ i: P" Svoid WS_Reset() { PAout(0) = 0; delay_us(60); PAout(0) = 1; PAout(0) = 0; }6 T R! B* ], ]$ |7 i- z2 n/ r
" g/ [' z4 K0 a( g" D8 \) J+ w
' f E# o x) M+ _/**************************************************************************************
" ?1 O: a1 ]6 ^! P0 l% {% z5 y; Z* 发送一字节5 h% S* }2 ^9 \5 S# l0 U
**************************************************************************************/
8 M9 J9 Y; Z( x8 ]; I |void WS_Set1(unsigned long dat), _( Z8 S0 o7 ^
{8 s) m/ k$ ^9 I5 g! l- Y
unsigned char i;
. ^" d/ P: u6 c) |( e! p
5 X6 g! Z: m7 Y+ l for(i=0; i<24; i++)4 h( E/ ]6 l' H& H+ a# y
{7 Q& s/ t/ R3 i4 C1 j8 I
if(0x800000 == (dat & 0x800000) ) TX1();
, _5 k+ J7 V( Q9 v6 k; U% i else TX0();
9 Y) ?3 A! {4 x0 k$ l dat<<=1; //左移一位
( L z. Q. M' O6 e }
' @2 s( ]% A4 V. L* R}
, z1 u+ M* r% i! m" m/ N5 w$ D0 i" J- M7 j
; a# h/ H7 c( J: Q
/**************************************************************************************
' B" O* G* t% {' h& v7 X* 发送所有字节$ z+ U0 T' h" g, x
**************************************************************************************/
0 |; S; S" \" k# D5 uvoid WS_SetAll()
, n% T7 E" h1 K- m7 d. v& J/ b{
, n0 \+ g2 U2 e- w8 R7 a/ J, J5 e unsigned char j;% h5 ~; d0 Y) G
# }8 p" c, ^$ o( u& T for(j=0; j<nws; j++)
* y u( N0 S# O" b' Y J {
k) D4 e; k: @4 o, l1 c WS_Set1(WsDat[0]); // j / 08 b7 Q4 w$ j* V/ t" I; ~
}, E, N" r- v: o0 }, Z
WS_Reset();
! `+ |1 T" O, q, h}
. z4 ?7 Y) Z9 a# v
6 \* }6 A# u5 s, M8 z0 H, T+ ~" c$ E. B
% P: z5 ?, j1 c/ ^7 @
/ A/ o: @; X* M3 S( S5 I: a! M/ w
5 D o) s" h, P+ |9 h& [
5 y9 c# L6 c5 D: p
( {$ g0 L/ U- s# c# }
7 W/ h. P, Q: y& \6 ^8 x/ x9 c z$ C
4 h+ P6 u9 R# h% q
( V" X4 I" |3 i5 S3 E5 m f( c, B$ S$ Z3 y! N. n
f7 \- x7 K; `( N, d0 y
9 g& Z0 A+ L v) j% s' Y0 y5 p- R: o( K4 ^" {0 W- M, W
) O% h; K$ O/ e
8 X- x( L- a- p
/********************************************, ?7 [6 J3 j1 @! J! I$ w
* 求绝对值
* [6 _5 {" G) P0 `: ]********************************************/* Y' U$ \6 K) A; c5 ^
unsigned char abs0(int num)9 ?& V8 \# Z" e& _: d m/ n
{( l6 ]. M( B1 O. @! _
if(num>0) return num;5 T, W$ x- Z" D. W
0 @! j. T2 M j% f) } num = -num;5 f6 c& x# C4 q. @& @: h; K/ Z) }
return (unsigned char) num;
5 e) p; M6 o3 V0 w) S$ s4 J}
, N9 L: f/ @8 A
1 p, c& h! K4 Q. A
1 C/ F, l9 r9 U, x6 j$ T/***********************************************************************************. a2 z' {' `* s' c/ L" Z
* 颜色渐变算法/ F. _/ j; w0 w o5 s S9 @8 i! V
* 误差 <= 2; W k+ m3 C. [" `6 o9 Q q3 S6 r8 S
************************************************************************************/) W- C4 p' Y$ Q6 y/ H4 |
u32 ColorToColor(unsigned long color0, unsigned long color1)- f D! T; f+ `8 f) F9 ?
{; {1 T5 ^4 f) d) \
unsigned char Red0, Green0, Blue0; // 起始三原色5 f/ R# R2 q6 {
unsigned char Red1, Green1, Blue1; // 结果三原色; C1 ^* S3 y% s5 _' I- C
int RedMinus, GreenMinus, BlueMinus; // 颜色差(color1 - color0)
0 f( V7 a* _6 m* |, | unsigned char NStep; // 需要几步
) _$ l6 ^+ ^ d( A2 b( J$ Q0 J float RedStep, GreenStep, BlueStep; // 各色步进值 h# ]+ Q7 l8 {( V: o% p
unsigned long color; // 结果色
. J( e: C x& A( y unsigned char i;
5 f' Y2 A) D v! [! C2 S
6 U) a% k; m5 _/ h0 j1 x. } // 绿 红 蓝 三原色分解
$ j0 i6 r& _# z Red0 = color0>>8;5 Y) i: |6 c2 a* x
Green0 = color0>>16;9 N* g( S& B$ t5 b+ d5 `
Blue0 = color0;$ g0 U/ {0 Y1 m. s, f# R
& h, o7 G, W% s# w
Red1 = color1>>8;
+ p! B, ]3 f" i3 R7 [ Green1 = color1>>16;
3 a$ x8 C" _5 B4 D Blue1 = color1;
8 T q; u9 ]$ A6 h8 x ! y; s9 G8 Y4 G4 e/ T$ O- z
// 计算需要多少步(取差值的最大值)
; [1 u2 ~$ D Z( w RedMinus = Red1 - Red0; 9 n8 z8 T9 K9 M8 T, Y" u
GreenMinus = Green1 - Green0; " h* P8 f' G# E8 R- S2 P
BlueMinus = Blue1 - Blue0;; D- y$ l$ P7 w& |4 }/ Y, G
4 m1 L3 E1 y% ]. x' |" c9 e NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus);( P% ?' E$ A4 G) k) t- D5 a2 T
NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
; n" |, t; n6 ?6 u( R! } 4 b- o& D( _& M- u# `+ [ n
// 计算出各色步进值1 h. v7 ~% V5 d. L3 T# c; @2 b1 F
9 G) c% c0 S" o' X; X
8 S' N" p ~# v. r. d2 [ n
v$ m4 ]. c6 p3 I
% y: P4 {- s7 C* _; }, ^…………余下代码请下载附件…………$ w- c* y6 v, P; W
# [4 L; z6 d, i1 w# f8 y1 w6 T
: Y1 @/ F; [1 p$ ~
( f' I& L- }* h4 D5 C2 S& r4 g% `+ R0 g
/ U) V: b: ^1 _; w" i& f
0 g* X$ k0 r$ c5 A5 x1 F& i下载:
% Z' A/ q8 k; `) K, Q+ W% h% S. g: M) _, d+ c7 @3 D/ g
) B, ]0 t$ \2 w* h7 W, c4 z( K- U$ e& Z) C
|
|