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

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑 4 i3 z/ z' Y* M1 d1 r3 [. V! y* B
7 c9 S" L+ s( D4 z; G4 g
其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。$ w) c1 |8 f* V
今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。
# j. W! z  s' J& ~4 `4 ]还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。- j$ s' i4 \2 y) m& d) E
驱动芯片:STM32F103RBT6 频率:72M4 M( c2 {0 V  A9 W5 ~" g$ b8 E
说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V& r: ~, |6 W4 h# X2 v
好吧,上程序:
3 b  Y3 g: J+ Y) }0 B3 D& qvoid WS2811_SendByte(u8 dat)//发送1BIT的数据
4 b0 }. q7 b" F( F& Q{' E0 {/ z9 _+ [, n" O
        u8 i;
! P: C, L# M7 o# x; S. `+ R        for(i=0;i<8;i++)5 I! p) @& S1 F0 ?( [: Z
        {
& a8 y  C) K8 A. W8 g                if(dat & 0x80) //发送数据1* G, }8 L. J8 {1 w  t. n! o2 X
                {9 j- {* N+ v  a7 J
             Light_SDA=1;
8 [' A1 [+ F. B4 U, H. `             delay_us(1);
) n, w* \, I8 G6 @- F( t8 J( b            Light_SDA=0;! f  l; @* T! j: |: I/ G% {
            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
0 S- ~1 ~" j1 a" u8 f. i                }3 m; m. h. h- I; v- H
                else                        //发送数据0& F2 \) \2 [7 C# O9 b. D5 J. T+ A
                {
/ H) B; h& W8 N' v. y0 E6 X- B            Light_SDA=1;//0
$ G* Q0 {4 R# [6 W/ a            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();7 B! q4 [; }/ n+ n
             Light_SDA=0;
; w" A# F% Q0 r2 e! v* f  K            delay_us(1);
; @2 a  _3 J2 J0 W$ _' z7 P% N                }  {9 W! |. T0 ?+ g0 V1 |
                dat <<= 1;
0 u8 F! j' x1 f! `        }
* w1 S" `# m, `! ?6 ^}
2 q# {/ Q# D% P8 y' y9 e8 x% E
7 ~  a, g% J8 V& P
void Reset(void)                 
0 G# o+ n! ~) X4 `- c8 Y{        ' z  l: |1 B' a
    Light_SDA=0;. h. |7 k) ~* l( u5 G/ I9 d, s
    delay_ms(30);9 b7 d- Z( F( Q' T2 m# C7 a
}
) N( P+ M& C7 N# c/ T2 S
1 Y# C# ]+ @8 p3 O5 H* m1 I基本的发数据程序就这样了
7 \! x; i4 e' y3 M. b8 f) Jvoid send_data(u8 R,u8 G,u8 B)
, `7 N" V& T1 h# d2 a{
; B& e8 K7 S. X$ f7 O( {- t( q+ K                u8 i;
: I5 n& B# V" p( ?3 a4 q! Y                for(i=0;i<led_size;i++)
: O' e+ @6 g4 C' _* _  H* y                {
' e" r/ V- R! E0 [9 o  e5 |                        WS2811_SendByte(G);
: D) z* ?% M6 F" J# \                        WS2811_SendByte(R);
7 H# M9 P7 J& D: ^' M+ P                        WS2811_SendByte(B);$ B. t% {# F9 V( h- T5 E' S( p
                }$ p6 J" S2 f7 F) Z
                   Reset();
( h8 G% h8 S% a) Y1 ?$ P- h}
1 s* ^$ |7 `3 M! A2 W5 m) @
. x* G4 f6 n/ L) ivoid ls_mode(void)
% J7 W8 H6 _- T  |* Z{! @- |, }9 v1 L2 m$ K# F
        u8 i=0,ys=0,yz=0;
% b% h5 a! `) O" @! G        for(i=led_size;i>0;i--)
) z* W7 G) t6 L* d% [        {
: ^* h' P8 l# Y* g, a                if(i<=ls_t)8 x* c5 \, y7 s: b/ j- o
                {! p0 f0 w( m9 d4 R' m
                        if(ys<ls_t)
. _" w& T& k; I9 a& E) L                        {; Q! y5 l' R7 ^9 r5 [1 V- K
                          ys++;  _' z2 e0 V7 a1 {, I2 |- [! ~- m5 L; W
                        }
# {2 X! `, c/ O; A& b& h& c                        else
% i- j8 m- W4 J( S9 W+ u) R8 \                                ys=0;- @1 A4 ]+ B2 \
                        WS2811_SendByte(LED_data[45-(ys%45)][1]);
/ s$ ]1 ]5 ]+ n0 o5 a3 z# G0 p                        WS2811_SendByte(LED_data[45-(ys%45)][0]);
5 W5 H1 U1 [- T" a; r0 @  h                        WS2811_SendByte(LED_data[45-(ys%45)][2]);5 m7 H9 P! ?3 e) u) K
                }$ A6 {& |; `# c6 R* S
                else
- z1 [' c, ~3 l* }                {
* Q0 }. r) t. [1 t. A4 H! y" z                        if(yz>0)
& F  [& y, i% p* _$ X                        {
7 T. ^# M3 Z' m/ o7 e7 V* X                          yz--;5 I# c1 W; z5 u& |- p5 F0 {7 I
                        }
$ d7 B) [# z5 A                        else" q% D+ k/ e# c" b
                                yz=led_size-ls_t;
, t/ \  D2 G, ?8 j/ L                        WS2811_SendByte(LED_data[yz%45][1]);* _9 L, v- M7 }8 z' g1 S8 M6 w6 h
                        WS2811_SendByte(LED_data[yz%45][0]);
3 `1 ^0 b" _( V& B                        WS2811_SendByte(LED_data[yz%45][2]);8 v5 ]  K+ A4 D# }
                }5 m0 g: e. N. ~3 l
        }6 ?# K5 U6 V" L' D6 s
          Reset();
! f' ~/ d; |+ [9 C& I}" p" R; H. j* N# {! v

/ \" R3 X1 m+ [8 D4 r+ v" ~- V8 V+ F, o
这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!
) X# z9 Z3 d' j2 Oconst u8 LED_data[45][3]={* O5 {$ _0 p" o
        {55,0,255},//G,R,B+ k& ~- N% ^6 g( Y1 k6 X& t* h( Q
        {100,0,200},0 t1 B5 i, c) u- T' ~# P( i' |
        {155,0,155},
. n% {- A& E! d1 L8 G3 p. [        {200,0,100},( [. Y1 A/ n& T- E" j
        {255,0,55},//5- z3 ~  T& p/ O9 y# C
        {255,0,0},9 f) B/ z' A6 e0 r; L  O, a
        {255,0,0},! {8 U, s- z3 j/ Z
        {255,0,0},
0 I- X* U/ x* r, S6 ~        {255,0,0},2 o7 k: |( v( |2 K' z% `( x
        {255,0,0},, A  p0 X2 _& ]$ W$ z& K& K' x0 U
        {255,0,0},: [( [4 K+ H5 N3 b8 E$ R
        {255,0,0},
) {: M3 r# I( n        {255,0,0},
0 t2 Y# k9 N* b$ r        {255,0,0},
; c$ {5 Z2 m, x# K0 g        {255,0,0},//15
2 Z! u. t% |% Z' V6 v8 r        {255,55,0},
# b. o& h$ t' |7 g1 j0 r3 S        {200,100,0},1 S$ U/ E8 g$ i1 S
        {155,155,0},2 u' D, x1 S' G. I! q; ^6 G- ]
        {100,200,0},* M% A5 v3 Z) b. g' S
        {55,255,0},//20$ X) y' z! c( d1 W
        {0,255,0},//G,R,B5 h* i& w/ e! q: M* ~# y( |1 a! l( z
        {0,255,0},
) v, X* b6 j0 n/ u        {0,255,0},7 ^% p$ B/ V/ @: _5 g! z
        {0,255,0},: D6 z+ B3 h( j& H, ^
        {0,255,0},
- L* i5 \( [  a; g8 z+ p( b+ b        {0,255,0},0 b3 ]  z. L, F( D$ h- H
        {0,255,0},
5 A! U+ d. b2 h; f8 a8 [        {0,255,0},
% |" O* R/ t' [& A        {0,255,0},+ P4 A. J2 `7 v- `1 ^) c- r
        {0,255,0},//30" L; @6 i5 h- N( _3 m, d6 u5 |
        {0,255,55},//G,R,B
6 s. S& B; w; v# j6 h2 O) Q        {0,200,100},' ]) Q8 `8 ^. ~8 {# `' ]  h
        {0,155,155},; H+ }& z, G  Q( q, k# {# C: w
        {0,100,200},
8 b& X; U# D1 {  x7 J0 L! f! J9 G        {0,55,255},  O& h4 E% o  k- Y' J, V" J
        {0,0,255},//35
# G5 {  _1 P. r9 j        {0,0,255},/ t  L# _4 i6 ]; l
        {0,0,255},0 }! H9 j+ H. O7 m( x0 ^0 z- [
        {0,0,255},
+ V3 y( a- a7 w. _- f9 L' P        {0,0,255},
1 W1 i% v9 w. u        {0,0,255},, C+ f( {9 G2 g$ F1 W& |% |6 g
        {0,0,255},/ v$ l6 k) n/ J3 |$ ?& ~, q
        {0,0,255},$ u! o  {) M8 u. N/ d, R
        {0,0,255},
  w$ P4 J+ P6 B3 f: l  p. F        {0,0,255}//45+ O3 ~! M* W4 O( \' d" g* ^
                           };
7 ]5 k" H! @; A6 ]; U
- F! }) U% x: P& K+ p* Y, b- G3 T0 a, i+ Q  H
这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式4 ~6 y! U/ K3 ~# r3 S
单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:) s/ `9 `) }* d: L  t. |, \, J
void TIM2_IRQHandler(void)  // 1s enter
: i0 a7 ]# F7 A7 v5 r( P' W9 F{
. d! X5 e+ Z. x" N     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
# ?/ I3 @0 G) S' [0 E$ s+ }     {
6 u: |0 f! F: a% I6 i' W4 ]//                        ls_mode12();
/ G8 j" s* H6 w8 C' Z6 p3 |  u  f8 @                if(++t2>=ls_speed)
: q3 ^3 m8 F' s- N; i4 Y6 f                {* ]  h, j' \: y- x& C
                        t2=0;
* C; a* K+ i4 g+ n                        if(++ls_t>=led_size) //注意!!, s$ ?3 q3 F( u6 o0 F
                                {
8 X2 ?8 p' [1 j! ]0 O                                        ls_t=0;
* }, C: ^( S$ b! C6 F3 k                                }
+ j# I) Y* x* w! l) s5 x                        }
& @2 @( o1 F  b6 f: \) ?        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        7 _  C& I* V) \; I) Z+ N  N
     }  
. Z/ U  E+ }0 K9 y& C6 H. d}
+ Y* u. i& K. t  Z  a
- r! L- k9 A/ I; J8 N  N
. q5 O6 a, d- p) F+ l. B% C& K这样在main函数调用ls_mode()灯就流起来了!!- E' T$ s$ m! V2 \+ X# T
漂亮的东西怎么没有视频:
8 e- w" Y; C+ ]8 v" _3 c/ W+ y+ J9 }, m
P70614-085819.gif
1 m8 E! Z8 {* F: Q5 x

评分

参与人数 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( p4 g- S; r; U9 x
兄弟,分享一下SPI是怎么驱动的?

! }; p7 y6 I# N; _5 d, W思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:095 q* S6 {! c7 S' E
我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...
) [7 m: {" G( q4 o' m
请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器; T( z; [, N( V
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
* i$ F# {/ ?; n; _MCU是跑72Mhz 吗?
- t, _; w9 @, e& B: T2 W3 T
是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 手机版