请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑 5 D5 p8 i4 q$ k3 S! o" r- g5 `+ q
" l0 H, O! ?" t1 W: ?& N
其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。5 o" o$ }9 }) B2 K  o0 h
今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。
. X# W, x6 t- M  z还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。
1 D& x" c# c- E0 q" }- N驱动芯片:STM32F103RBT6 频率:72M$ a3 o1 o7 n! d, |8 C- u0 I
说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V8 m- r' i4 i9 s6 B& \+ x, U
好吧,上程序:
9 \( o& K, m  P8 ]6 M0 ~void WS2811_SendByte(u8 dat)//发送1BIT的数据
: y, d' \, p9 d2 G- Z9 f9 x/ Q{1 L0 l$ }& N( W
        u8 i;2 V' T; o) p: }# k1 I
        for(i=0;i<8;i++)% Z3 E. Y: s0 @8 T( m  \
        {, ~' ]3 Z5 Y7 G. b9 k( r) A: m+ z
                if(dat & 0x80) //发送数据1
, g5 N; q* y$ M4 l0 l                {
  o7 K( M: a- ^. U; d0 R             Light_SDA=1;
7 w/ o, [* d3 B) i: ?/ o2 j1 O             delay_us(1);
3 a/ x; K+ p1 d4 ^            Light_SDA=0;
; v) e/ E" n9 D1 Z! t+ T            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();& ?: [1 I" O. g% F9 ~6 K" T6 m+ u
                }
" T; a8 ]( J& @3 d- H( |                else                        //发送数据0# @' w% B! g. m; b1 [
                {% G  L, \7 C$ f$ I8 a
            Light_SDA=1;//0
( A# U7 w! L0 T( Z. d, S            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();) R* F& q8 _% G, a# c
             Light_SDA=0;
% M4 J4 |) F7 [$ T* q& e            delay_us(1);( d/ ]& k0 }( u9 T5 d: D
                }: F/ z5 ^9 J' }! Z
                dat <<= 1;
8 d# a. f  J6 [6 `% K7 j* z8 G3 p        }
  U( d( j. ~, o2 `7 M3 s) P}& c- O, P9 b# R8 l! q% \4 X# L/ b
1 |* X- ?' }. B1 y4 d: ]9 @6 u
$ z; U" K2 K/ P  e
void Reset(void)                 7 s7 G2 n4 I0 \$ r" t
{        : \$ [9 ^" h7 {2 @  a: ]0 c" u1 t7 r, V
    Light_SDA=0;  b- x+ B8 L# P9 U/ t" }- `- h
    delay_ms(30);7 z( r' o3 k8 S, X2 |
}
' Q+ ~, e3 K) T# z3 @  x) @! w) T3 t- v, l4 e) N( M& p% _* G
基本的发数据程序就这样了& s- h# a; B% n
void send_data(u8 R,u8 G,u8 B)+ W; l/ t" V3 q! v# t: M' E% |
{
# N( t/ X- x: P+ t+ v                u8 i;
% z- f+ i1 d+ _) I                for(i=0;i<led_size;i++)
5 v  l, c7 U: M- ~, K+ D/ H                {  p7 O7 M/ ]) w' Q
                        WS2811_SendByte(G);
+ F4 s4 Z& Q9 H; q* b) z                        WS2811_SendByte(R);
% L9 X( v3 N: ?! m- ^                        WS2811_SendByte(B);6 c* q" R$ m6 o* p5 T
                }
+ p& m2 s, F% f$ L: r7 e                   Reset();9 S  j5 K6 i! x8 d$ @9 Y) b& ?
}7 V, b7 V3 i2 S" B* M; a
* w3 {. x& n  L$ S" T
void ls_mode(void)! h' t8 `3 e1 s- N3 J/ }1 v, Q
{
8 F/ y9 v7 D1 a: j+ h        u8 i=0,ys=0,yz=0;/ f# D# B9 c# _; U
        for(i=led_size;i>0;i--)5 d; \& G2 T" ~& @6 v
        {
2 u* q" Z$ s7 m8 c# H                if(i<=ls_t)4 s- c4 R8 E0 \9 W# g- k, a
                {
, z* j$ c$ x, f                        if(ys<ls_t)
2 A+ G! S  E3 d; x3 I4 [2 u                        {
7 X* y7 s% B& X6 x1 t) N                          ys++;
' C; X9 `/ G. B" _# {2 J6 k: {' o                        }
6 [  m8 M  e3 E) q" f0 @# X' ^                        else
/ x" u* g4 E4 ~& P8 k  z                                ys=0;! B, y5 a, Q8 Q6 b4 R2 |
                        WS2811_SendByte(LED_data[45-(ys%45)][1]);( H, X# w* C" r; ?) R1 P
                        WS2811_SendByte(LED_data[45-(ys%45)][0]);3 U" t, G3 o+ p3 J1 [( |/ [
                        WS2811_SendByte(LED_data[45-(ys%45)][2]);% Y' H8 d7 ?% |7 u/ Q- s' ]5 j
                }7 t! s. m3 h5 A$ D/ ]
                else
) D& h+ ?3 K4 F5 a- \3 j                {
8 R0 p5 x. |# d5 k3 ]# B- x                        if(yz>0)
% t8 B$ ^- t3 D                        {
' Q. [; n/ c1 N                          yz--;: q2 K" \, B. Q/ ~# p
                        }
4 O, j( F$ Q  r) d$ |, V                        else. w5 a' I5 l8 w/ t( [) j2 f+ i, Q
                                yz=led_size-ls_t;4 z6 d1 G. t/ A
                        WS2811_SendByte(LED_data[yz%45][1]);1 ]3 }9 i8 i7 _7 i0 G  E# z1 l# L
                        WS2811_SendByte(LED_data[yz%45][0]);
- T6 w1 y# i% t+ N' M" r$ }! ^                        WS2811_SendByte(LED_data[yz%45][2]);
2 ~# `4 a5 @# E# U# u! T3 {                }
0 t: I6 x3 Q) t! c# {# N' y        }
- x1 x- O; Q2 U* u. n# L          Reset();
" W3 C( R: `& D2 _}. ]( G: @3 ?' Z4 F9 @
$ k9 S- T3 m+ }3 m( Z8 D
* {2 D' ^9 W+ ]: ~
这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!
' @0 M9 h3 I9 M1 ]const u8 LED_data[45][3]={
; A8 ~1 n% \" W$ q        {55,0,255},//G,R,B
7 e" ^" A9 p$ p" H5 `# A1 m" H        {100,0,200},5 W( E3 k+ ]- w# \7 b4 `8 K
        {155,0,155},
! i* T, }1 _$ f        {200,0,100},
5 y, {* k3 r7 T        {255,0,55},//52 z- C, m/ r- I, M
        {255,0,0},) f  ^6 V" D6 j1 M8 p  \
        {255,0,0},
) y' y0 p7 d' d' L- _        {255,0,0},5 t) m8 m, f; N: e: t9 ]0 u8 W4 S
        {255,0,0},
6 a; k$ g/ u, z& N        {255,0,0},
; w  R$ x; |6 t- ]5 u8 z        {255,0,0},: m; t' n! R: t( Y& F* a
        {255,0,0},1 ]( v; j5 i: b  t. R3 {$ y
        {255,0,0},
8 q% o; `- W  G        {255,0,0},; Y. p; v% D) R
        {255,0,0},//153 |) ]. e8 o$ |; U+ F- Y# \
        {255,55,0},
# V3 A2 V2 f7 g0 Q* V8 t, b        {200,100,0},
% e, Q) \/ M" B" B8 H# A        {155,155,0},
2 |2 r. q9 ]5 ~& ^' I5 i        {100,200,0},
! J- i7 E, x- C( c% m6 U: w9 E1 {2 g* l        {55,255,0},//20! J& a5 \8 D5 y& s8 C
        {0,255,0},//G,R,B
/ |6 I# F# W+ v: n7 x        {0,255,0},: h% K/ Y- ]% I1 I' C5 i7 W) s
        {0,255,0},
" Y, H8 `% H: H( n        {0,255,0},, v5 {5 z) G% V, U" ~" K& ]3 ^
        {0,255,0},) c5 k2 c7 Y2 f3 I. g) t# Z3 p
        {0,255,0},  e& L4 G2 {9 S. z  `! ?
        {0,255,0},! C) P2 c, L0 U/ J
        {0,255,0},, b$ o% l& N2 b7 T; Z
        {0,255,0},, ^) U; ]6 h- \+ |& K' z/ X
        {0,255,0},//303 d0 o8 ~: F9 O1 K" }$ w
        {0,255,55},//G,R,B
) k  g6 _  O1 d  e3 f7 j* s. j        {0,200,100},
: `; ]- t7 z& M* h7 T3 b6 p* q! T' v; d6 e        {0,155,155},
2 R- \& S# a: B9 u( h/ D/ Y        {0,100,200},
) W/ s1 b+ `3 c6 {) k4 ~        {0,55,255},
+ o( y; g4 ?, v7 ^. A8 {        {0,0,255},//35) U7 }0 A) E; @9 W
        {0,0,255},
# S: D/ d: H8 [4 K        {0,0,255},6 @  k/ M/ @$ z5 A! Z2 D
        {0,0,255},
/ X, S8 y8 `& @- u        {0,0,255},
" Z6 d* \4 W. g& m- G        {0,0,255},
6 L! ~4 F8 A4 X5 ~  y; n& z: W        {0,0,255},
- q1 \8 V; K( G7 t( a        {0,0,255},
1 S) r  p* [+ C+ {" M% K        {0,0,255},
& Y3 o! K! |6 @0 |        {0,0,255}//45
1 n3 R: B* p7 T& n9 c* c. ]6 R                           };4 s/ t$ A; f  S$ e+ _0 r

* P8 W8 t6 J- [" E7 U# w4 A. u7 U6 L9 u3 b' T1 X/ n
这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式1 |( Y/ `# H5 I7 I
单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:
& c% G) `9 i( G% q: Hvoid TIM2_IRQHandler(void)  // 1s enter
) _1 q9 U' A% Z{
$ ~# [6 [; J4 E) d: ^2 C     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)9 R7 g4 c- I1 q
     {! U- ?* S4 `7 x# {$ S0 \/ U
//                        ls_mode12();
9 n, f! c0 h) g7 t( N3 w                if(++t2>=ls_speed)$ E0 ^. u7 D4 f* V
                {
, Q  u: h9 j# P: P( v  \2 W                        t2=0;# R6 l9 D6 j( B3 a6 c  z/ O
                        if(++ls_t>=led_size) //注意!!1 f6 j, q/ H# r4 [7 e  S4 J4 v
                                {
4 I+ P7 d' Z9 N6 w2 O3 }0 P                                        ls_t=0;
# Z0 l6 P# L3 }& }' f; u' g                                }
7 F2 S# r* w8 P5 h" s# m# K+ B                        }6 T- x& p: c4 P' `) M' M
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        
8 B) @+ N5 J# E  ~- i( t     }  % {/ Z2 p( Z5 K' r6 N4 A" k
}1 L+ {# u* |) P+ l8 a$ ]" @1 {, O
" _# T# t/ g% K" D1 Z0 j
4 f$ c; w+ o# i/ ^; S
这样在main函数调用ls_mode()灯就流起来了!!; b5 F5 ~, g/ G0 Z6 i
漂亮的东西怎么没有视频:
" K2 u  ^0 a( r' p% l! S% L1 ?1 ~
- q6 G1 a9 G& C  C P70614-085819.gif
  p6 J1 S( l7 }; u

评分

参与人数 4 ST金币 +11 收起 理由
勿忘初心ºº¹ + 1 赞一个!
pythonworld + 2 很给力!
shaoziyang + 5 很给力!
MrJiu + 3 赞一个!

查看全部评分

1 收藏 7 评论33 发布时间:2017-6-14 09:02

举报

33个回答
dream2010 回答时间:2017-11-3 23:09:05
我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 SPI口,256级灰度可调,能控制1000个以上的芯片,这种芯片对时间要求比较严,一屏数据要按时序一次发完,否则可能显示就有问题,一直想换成PWM,但是不知道怎么去实现不停控制精准的时间,用示波器调感觉太麻烦了
myccl 回答时间:2018-5-6 20:28:02
anny 发表于 2018-5-3 08:17- W- S; N9 f  N& ^4 D+ H5 c
兄弟,分享一下SPI是怎么驱动的?

! @0 c4 b3 X- _2 }. A4 w思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:09
! b% E: Y1 T/ H我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...
( h7 ]8 H. `9 [( z) |
请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器
( K) D) m: G4 k# E" X
MrJiu 回答时间:2017-6-14 09:11:49
看起来不错的样子!!!!!!!!!!
anobodykey 回答时间:2017-6-14 09:13:36
很炫酷那
shaoziyang 回答时间:2017-6-14 09:17:00
挺不错的
Stm32McuLover 回答时间:2017-6-14 09:24:50
帮顶。。。。
左岸右岸 回答时间:2017-6-14 09:42:22
waiman 回答时间:2017-6-14 10:06:50
MCU是跑72Mhz 吗?
jackten 回答时间:2017-6-14 10:37:56
厉害厉害               
lisingch 回答时间:2017-6-14 10:53:15
漂亮,赞!
黑皮男 回答时间:2017-6-14 12:41:24
挺炫的
zero99 回答时间:2017-6-14 12:57:21
酷炫
anny 回答时间:2017-6-14 13:06:49
waiman-156411 发表于 2017-6-14 10:06
3 W1 t9 M/ s. i4 S5 Z6 DMCU是跑72Mhz 吗?

) l  |' H$ z! `3 ^, u' x) l' `是72M的
时光虫子 回答时间:2017-6-14 16:19:52
做的不错,看上去很炫啊
epochal 回答时间:2017-6-14 20:03:00
不错。赞一个!
pythonworld 回答时间:2017-6-14 21:00:09
功耗如何,费电吗?
123下一页

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版