|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机驱动WS2811彩灯源程序和实物图
! H4 g& k9 @$ |3 P& I9 m6 J( O; P0 h* d9 y) ^
* g# p' W" W2 s" {& L! g Y, t
WS2811是一款可以级联的RGB三色LED灯。只需要一根数据线就可以控制多颗LED。现在发上来整理的库函数,可以直接调用显示函数。+ a8 i. F9 u4 t5 u' `
* a8 ^" m. b. t' h
6 G. P$ l2 E) ]. B `& O- OWS2811.h/ _2 n7 t+ A( c
( w( i5 m' E, M7 D8 g8 L& h# ]! G
6 c/ `) q+ {6 _1 b$ S6 T! t$ P#ifndef __WS2811_H
* y* G4 }% \, q h& q#define __WS2811_H
) j6 h4 ]8 B7 [#include "sys.h"! l" j; k ]# h9 I1 F4 u" t
+ m4 {% ?! q" `) I6 v3 @# s5 M
* L2 n9 z6 N7 f
* Y; k7 q* T$ O# x% J5 B; }
' t& k4 z; I3 ~$ p; h# T#define White 0xFFFFFF // 白色
7 l5 @" ~* w! `( V/ w( J- g, [#define Black 0x000000 // 黑色
2 `+ P% X a, p#define Red 0x00ff00 // 红色
) p$ G }) S+ m& f* |) C0 q#define Green 0xff0000 // 绿色
! }; I3 c1 s: Y1 K#define Blue 0x0000ff // 蓝色
" L5 e. U& L. @" H2 X
; d! I: b) y7 L" e) L f
4 o \) y/ c+ h1 @' [7 \4 B$ W
( l( @" u3 o8 m! B) ]4 v$ u! R6 k/ g/ j+ f+ \4 A
#define nWs 16 // 有多少颗WS2811级联
" G4 ]) z3 l! D0 P
5 z, ` ~. Q! x+ }! _
/ C2 G4 Z+ e0 p# [) gextern unsigned long WsDat[];+ U* E: S8 ?2 q, n# S
( c9 u; V% i+ @. U' O. W4 o. P% }" ?7 P0 E
extern void WS_Init(void);/ Z, F, j, E- a8 p
extern void WS_SetAll(void);* Z; ]- b& S5 p- y6 }) r6 q$ W3 O
extern u32 ColorToColor(unsigned long color0, unsigned long color1);/ Q9 \% U! [# a& B9 Y
/ f3 _% M, ~4 c3 L' Y
1 w4 c+ W+ z, `9 v& _9 v- q* Y
" N) U2 M% A9 ^#endif, {: k: H8 G2 Q9 x$ `
# p+ ~6 T: H9 A
1 a- _ O' C6 E' F' c8 Y3 L1 i$ h3 ^+ I6 b
/****************************************************************************************
- i, @0 B/ e" `1 x! }1 R* WS2811 彩灯驱动函数
$ x8 e0 |. N0 X0 P% _6 {! x4 i*
5 ]/ i; ?+ j' s4 G" l: ]! O* 调用方法:
, D! e& p4 M# ~; b% h. `3 ~8 a8 t* 修改宏定义: #define nWs 1 // 有多少颗WS2811级联
4 h) T% k1 w/ L6 f# D" O$ _* WS_Init(); // IO初始化" J# [, O) Y2 |/ x$ |! K: ]
* WsDat[0] = 0x808080;//显存赋值, O I% n8 a2 S
* WS_SetAll(); // 发送数据! g% x% E1 r. d1 J& L0 c
* ColorToColor(unsigned long color0, unsigned long color1);// 颜色渐变算法" ~* s5 x9 ^/ c, @. H2 T
*! Z" B# e' g# c" z
* 作者:星希望(已校验)/ o; h. Q" w& Y3 n W* z, ~1 M4 L: q
* 日期:2015年6月24日
+ l T- D0 r) X* N****************************************************************************************/% y1 L" J9 i7 E3 d" P
#include "sys.h"
6 M* r" B9 W7 L4 n#include & w7 O% c6 `0 _/ b2 j K% Q
#include "WS2811.h"
8 M7 }: Z9 p' d3 t2 Q; j# e$ D#include "delay.h"
8 U4 U" r5 F, ^( Y- x( { k 2 d" y9 l: r( C4 |0 V
/* 显存 */8 L8 z/ x# G! W W. d
unsigned long WsDat[nWs];
# G1 l0 c3 [" V' h5 z! w
6 Q* U5 S$ E$ ^7 C2 w5 r+ R. x# l9 ]
" |1 H/ p3 T+ [% y4 _- m% }
8 i1 y! _1 ?( a/ p; [. Q: A' q$ o" R) |) D# L
/**************************************************************************************
/ B$ }4 R6 y# r; X* IO初始化(移植时请修改)
1 W7 V6 `% _! [, |8 T* ^**************************************************************************************/
4 I8 v: h1 Q: R. P3 Dvoid WS_Init()) y- |& Z0 `3 I( _( d$ ~# u
{
# U; i3 m9 E0 q5 @0 E x% @; B GPIO_InitTypeDef GPIO_InitStructure;
) |3 V- K. {/ j* l0 P
6 H: U* r/ M5 F6 T1 e3 W //端口时钟,使能
" h) g0 H5 x/ r, X# c$ S RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); / E# z3 q8 } y6 R( K0 X
* G' c& M& B# Z0 X8 b2 E, g( g
* G% R$ r4 }8 X8 x6 M+ c // 端口配置
4 }& s$ p* O$ |" G GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PIN
! l! }" `* g+ ?# P GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出0 N# N, d1 a/ X* r9 x
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz Z, x- D3 l, N1 o, }
GPIO_Init(GPIOA, &GPIO_InitStructure); // 根据设定参数初始化
/ Z7 l- Y4 ~# ~) n}
+ h- s3 d5 M2 R) F ^
9 Y( A/ D4 X. ^2 j/ l: D; u9 Y
1 M1 ^0 f1 s; W" ^- x. }+ ?/**************************
/ W/ }2 N* n# w' {* 内部延时2 @2 ~! `7 l6 m/ c& r3 r' c v# K/ v
***************************/4 m) |3 L% K9 R) j: r; W
void delay2us()
" ~: ~( o5 I' V$ U+ m) j{
, ~: h( @" w) P. W/ T9 ^! j/ r( J5 d unsigned char i;
0 b1 l* Y2 y: ]& q0 c6 \ for(i=0; i<12; i++);5 F3 W, i6 H, t
}
4 N% C! w0 e+ [/ J J) fvoid delay05us()- b5 {7 v/ r% V, x$ t& o. p& w2 N
{
4 s: S q1 ?( M3 s: f unsigned char i;
9 B5 p7 Y/ A6 N3 P for(i=0; i<1; i++);
1 p! a+ y8 l* _9 u5 [}( _) f% A D! B/ V$ d
) v C5 `. O. n: k R0 [7 J7 M
G" e" N) B' B: z& _+ _/***************************
& |- q7 H' u1 D& E! v- l, y' r* 发送一比特/ G8 Q7 h+ f5 z0 c4 Y
****************************/& J1 P0 H; {$ q# `7 x" Q% g% f
void TX0() { PAout(0) = 1; delay05us(); PAout(0) = 0; delay2us(); } // 发送0
! ]; ^% o$ F" f% n' V3 hvoid TX1() { PAout(0) = 1; delay2us(); PAout(0) = 0; delay05us(); } // 发送1
" _4 w& C3 V; L. d) e7 hvoid WS_Reset() { PAout(0) = 0; delay_us(60); PAout(0) = 1; PAout(0) = 0; }
8 p7 a/ L+ X% R. Z k X8 G) G0 Z, p0 U+ t
( c- h( y2 ~" {- i/**************************************************************************************
l3 q, a* l& ?% M* 发送一字节4 H7 p% G7 \, V7 p
**************************************************************************************/( ~( m" K0 V& w$ Z' t. {5 _
void WS_Set1(unsigned long dat)
0 }7 b! p: U! Y3 [8 T4 j3 P. i{
7 d% a W F9 @& _3 F7 B( e unsigned char i;
" j+ r/ _# P5 x7 G8 w8 Y! E6 W
' U t7 {0 X4 P+ M1 k7 P for(i=0; i<24; i++)
! }2 |! _# Z. L# k% S! [; v' z" Y0 [' c" I {
" @# o4 h; F" E, ?# ? if(0x800000 == (dat & 0x800000) ) TX1();
+ ~/ P6 s. C1 p) T. O else TX0();
. b+ g$ U4 n5 x dat<<=1; //左移一位: f" |8 h( ]' v0 i0 f
}
: z3 v. z% f- F4 X0 G6 s, ?}
' k$ g3 w4 {' R% ]8 ]# t- d( R" Y0 m& {6 v
7 Y% ]3 m& q" y5 N9 r8 u/ b/**************************************************************************************
& C( F' F# _% M) s' w* 发送所有字节
, z9 [+ T. Q$ a' h**************************************************************************************/
0 C8 m. D8 h% J& B! M' Rvoid WS_SetAll()
[2 l. L. J- n& o* V9 s9 e{
* O: P; m8 l. u) X& M4 I5 e unsigned char j;
0 R2 P! O; `" U" f5 i - ^) U W3 i0 q" B0 ~1 b
for(j=0; j<nws; j++)
; d4 S c9 K3 T$ u# ]3 ` q5 m {
' v; d/ d$ z) r WS_Set1(WsDat[0]); // j / 0
0 n0 D7 g% F$ p }
, c4 V; D% G. E) }5 j WS_Reset();
9 O- x7 k U4 W W5 M}
$ Z$ t0 ]% U$ C' P
, Z' T. H( V% }, i/ T6 m: z9 h! N* y4 u1 ]8 u/ a
2 }& `% X0 d2 n! l* C
' T# h, l* c$ U: ~+ [
0 Y5 ^8 V' K$ ?/ m
+ T% {, G+ }6 G C8 V1 K. _0 O( B# G1 \$ J
3 r0 R( @6 k( R4 e/ }
1 X5 a }" }1 {# Q. T8 m' E9 u% a5 }7 g1 d" `7 O5 b0 H9 y* T& o
8 }% M( e# c1 K. K* Y3 N
- l9 e, B6 S4 p) x
+ u- l& M, e7 j: @# @' F
% C: U" l2 O& j
3 f9 [6 S6 x' n- t0 I9 V. W5 E
+ I; g" P2 M% O* K% G
/ Z& y# A' z5 ]. s1 k" Y {; n3 B3 a! l" e: L+ S* A: t
/********************************************
: t% u O" e7 C# o" G r2 _* ]* 求绝对值
2 @! o3 `8 P( O********************************************/2 d( K; D0 C* f: z
unsigned char abs0(int num)
& e, F: q1 T5 K* N- E K' k l3 o{
; u( S; G( y" L$ T. @* ? if(num>0) return num;- Z5 I+ L! I/ W. {( J% J- a9 j
, u5 N0 H1 }) Z
num = -num;
) E9 m4 I' h$ u, H5 O return (unsigned char) num;
9 S( Y+ b6 b: g. `}0 B: `( |% U& a# s W( ^0 H
8 I- f8 U: W- {
4 W' S' ^. L( _" S/ Y+ g- d/***********************************************************************************" Z# V- Z: U7 t4 L- |# w3 d+ J1 S
* 颜色渐变算法 {: k$ I2 W: j5 j3 M
* 误差 <= 2- N0 D1 P6 K: X6 o' u
************************************************************************************/
& A* \& b. J) u y2 S, X$ Nu32 ColorToColor(unsigned long color0, unsigned long color1)1 P! j; P9 x3 ?' l6 k1 Q! e& }
{7 Y; c. K7 n* P/ R/ k% j& M. T
unsigned char Red0, Green0, Blue0; // 起始三原色
" J# b3 l; T! f- d- o8 n+ \ | unsigned char Red1, Green1, Blue1; // 结果三原色
6 G" q9 a) |' M$ K int RedMinus, GreenMinus, BlueMinus; // 颜色差(color1 - color0); B! m8 o! o. `: _& G
unsigned char NStep; // 需要几步
+ P# }1 N0 F7 U" _: Z float RedStep, GreenStep, BlueStep; // 各色步进值3 k( n1 Z+ M! s. r1 ?
unsigned long color; // 结果色
" j, j3 @, R9 _- l: x0 E( X unsigned char i;' u7 r$ t. o" f. c
6 Y5 d6 I6 O$ L4 {; e // 绿 红 蓝 三原色分解/ ?) G/ v/ Z- | P3 h. r" l
Red0 = color0>>8;( q4 A" j0 K* R( x# Q2 g
Green0 = color0>>16;
% w( r& z# h3 a+ }" M1 d/ ~ Blue0 = color0;
; S- {" b% S+ |4 w3 G* J
$ G( ~" R$ _4 g6 `9 H' R, ? Red1 = color1>>8;, y: x' N% @; _2 d! ~
Green1 = color1>>16;
0 O/ M7 `& V' E; m, k) q Blue1 = color1;
! v1 x4 o% W! X& u2 ] % U G' Q# j4 q4 k
// 计算需要多少步(取差值的最大值)( y( v& X4 P1 B' b: o& h+ T& P# {
RedMinus = Red1 - Red0; 0 ?8 ~( O- u) ^* k8 e
GreenMinus = Green1 - Green0; 4 k% `) k* r1 N: M9 r) E: y5 l
BlueMinus = Blue1 - Blue0;9 }- z" \) D4 S& P( \* V4 h4 ^7 e
8 r+ ]; p/ _( m D' N% |/ D9 i% G$ C
NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus); s) T2 s; ]$ v8 e- ]: X
NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
8 g$ e! i" z+ e! M& o
( k" x; s/ L7 W4 {% ^& S // 计算出各色步进值
$ c% d: ?9 v( f! p
/ {6 m; U# `3 s$ d, n. a8 \" r3 \7 ^7 P6 C% r& S9 r3 {
0 O1 y# O2 F8 A5 O- ~! s' [
. r2 G7 e7 b5 ]* n$ \. l0 Q…………余下代码请下载附件…………. |5 G) S+ @: ]# n
7 M( |, R# r. C6 O/ i2 _2 k a# @! B5 A. ?* l7 R: t, ?% J
8 }- i% C- Z% l5 M! |1 B8 P4 p+ t: P6 s3 F. S% O) R$ B7 L
1 Q. }2 M6 t4 R; G0 x' ?6 p
0 E! C' f7 r( S6 q, a4 u. T4 i2 C下载:. d6 ]& b' F2 w; J* x; M
% G2 L& j/ V0 V3 g; a) l4 S8 ^2 f# X) @, X' _) y
+ G: m; Y* T( R8 k( }9 J |
|