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

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑 , i7 |" Z6 L2 {/ k
0 Q/ k6 r$ r# v3 i! ?2 ]; W5 b
其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。
' }7 l5 F1 _+ Y, T  _今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。2 p# w: R& `0 H! x
还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。" W( q& ?8 }8 B/ y" ~
驱动芯片:STM32F103RBT6 频率:72M
9 Q) r3 H5 U* u说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V) v, C$ P  u, H7 q
好吧,上程序:
# W8 y% x; p  Q; D2 Mvoid WS2811_SendByte(u8 dat)//发送1BIT的数据' |6 C$ v  T$ j5 C
{
; s4 o, d% k+ k( S        u8 i;! S) V3 n7 q$ h) H4 T/ L8 w
        for(i=0;i<8;i++)
: _2 ^# ~) u. w+ H0 S' S        {3 M( `1 Y- }/ l7 o2 y
                if(dat & 0x80) //发送数据1; r5 t! u& H; u- ]. \0 S
                {, U1 @' r5 S' h( m/ p
             Light_SDA=1;' v% b3 O! r% [& V! n/ ~; x
             delay_us(1);8 F  p6 y3 K1 K
            Light_SDA=0;
$ F8 w( F5 b, d5 J6 L3 H            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
" e0 P1 l! Y) H                }
- n+ a3 Q/ s3 F* }& w                else                        //发送数据0; v8 k+ h6 [" r( F2 _! Z: ~* G
                {
2 ?* n7 K( T/ g4 u$ N4 y            Light_SDA=1;//0
8 S7 d: `2 B/ ^            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
: b9 Q7 h- A! P4 N0 }  t# I( O/ V             Light_SDA=0;9 y3 _' P) x# f) X+ z
            delay_us(1);0 p: y6 C6 j# g! K2 ?, J
                }+ b& `4 m, ]. m9 ^; s  l! A& }
                dat <<= 1;
( L6 m+ }# c9 A8 O! X. S        }
: ?6 P2 b' ?0 Q}
8 V' J/ |9 x+ v7 s. h7 \
2 r3 M8 T! O3 c( h
/ \, L& D3 X3 q, m6 @void Reset(void)                 & V: X. n' L3 F6 Q) Q& V
{        
; z- A. o: A8 Y; @& ^2 r: W    Light_SDA=0;6 O4 Q5 v) V- K4 f1 N
    delay_ms(30);. L9 O/ `& x, z; g% u0 Q6 w
}
+ E9 z3 Q8 ^& V9 ~2 K: b
5 l: x5 u1 K; L7 t( Q1 [+ O基本的发数据程序就这样了
& l& P" e& {, `# ?/ N- P' L3 @" w9 J" r( q3 Evoid send_data(u8 R,u8 G,u8 B): N' s2 _& h' s% d4 ?
{7 D# k! O0 k  q2 x  E4 |
                u8 i;( @% \4 [4 Y, i  d  {: o2 ~
                for(i=0;i<led_size;i++)
/ w9 W1 q4 e1 i* L                {* f- v+ h5 d% Q$ U/ N
                        WS2811_SendByte(G);
' W0 [+ p2 m* u6 z0 }1 w) Y- P0 j                        WS2811_SendByte(R);
. K( |# s' u7 x9 E5 P                        WS2811_SendByte(B);
9 W0 `+ l+ _6 C+ L' V; A3 r                }
+ V. Y! r: D" }' Z! e; A' E                   Reset();
5 ]% S6 I9 r( {! b}& O9 C1 g2 ]; L: W  v

4 Z6 ^3 {2 T" F1 o1 W3 K1 svoid ls_mode(void)( h, d6 B& Q9 r
{
7 P7 X4 {% S1 n' l/ ~- V6 X& `; f        u8 i=0,ys=0,yz=0;
2 I0 a* J6 u2 p; N1 X, T; q8 s        for(i=led_size;i>0;i--)
( S* C6 j+ z0 f; I  w5 g, D. u        {
! z: [' `+ S) Y, p& w0 a0 A                if(i<=ls_t)( |7 F! r) d  x5 ^& Z
                {7 r: s1 w% ]2 f. I" ^4 Z  M5 t4 u
                        if(ys<ls_t)
  I: Z6 D" A1 |- W( G                        {
9 L3 P" h7 i- l7 p" c                          ys++;
3 v( m+ c$ k$ ]2 m: n! h                        }) m. F' O5 F$ M
                        else
7 a- p$ ]2 K' Q1 Q* P4 @$ x                                ys=0;
: m0 f4 j) n  P1 _                        WS2811_SendByte(LED_data[45-(ys%45)][1]);2 C- S; ?) p7 ?. \. \7 K) M
                        WS2811_SendByte(LED_data[45-(ys%45)][0]);
) g8 I2 F/ Q' C0 x0 r; Z: t  L; Z7 a# p                        WS2811_SendByte(LED_data[45-(ys%45)][2]);
- l+ Z; E6 p, Y5 P  \                }0 t' W0 c0 G% I
                else  Y2 ~0 I5 G3 W7 a
                {
) J4 y& A0 \* d, R+ ]: t                        if(yz>0)
5 C. E1 F( ]3 ^: L; k7 O4 {                        {
' c& x6 g* ~5 j; P! @$ a                          yz--;  T- b) u# G/ w. K- I
                        }
- h+ V6 Y7 l# Y' C& Z$ u2 C                        else
" g1 O- ]3 ^% z+ f+ H" U, }                                yz=led_size-ls_t;7 ~4 I: _. w" I7 F& }) h5 K7 b% L
                        WS2811_SendByte(LED_data[yz%45][1]);
5 G9 W2 e+ z1 ]                        WS2811_SendByte(LED_data[yz%45][0]);
' {; f' l! }0 X' I# f( O                        WS2811_SendByte(LED_data[yz%45][2]);5 M1 _. o' W# g& @
                }
$ Z2 k: S( n0 X$ y4 w1 M        }
$ O5 b9 \, s. _- a1 U2 i          Reset();
3 l: j% s+ B: Y7 f: ^- ~}, [2 N9 b+ F1 L2 D6 F6 _2 H
% E% C. }6 k. S) W8 C) F" _6 s

' V1 k3 Y0 r5 n" f% O) u! t+ ^这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!
; o6 c4 b5 S8 L1 vconst u8 LED_data[45][3]={  e- y$ h$ \* }8 D# [( F0 C+ a
        {55,0,255},//G,R,B% b, p4 `& s1 ?" E: g  G
        {100,0,200},
9 R' Z9 R6 p/ _5 B        {155,0,155},; p# S5 R% n3 B# K5 f
        {200,0,100},
- X1 l/ n7 G% c( f' Z: G. V' Y' o1 @        {255,0,55},//5
$ D: J3 p" Y1 V        {255,0,0}," E# Z' q2 t% Z  f; P/ F
        {255,0,0},6 H. [$ y0 k) m: b" x
        {255,0,0},& j( ?* g7 x- k% m8 Y, ?
        {255,0,0},
0 X  ^' O- C- A, X        {255,0,0},7 B6 ]% O% h" A! z; Z, P0 N$ A9 l
        {255,0,0},- Z5 J" r# ^/ ~6 i
        {255,0,0},
4 z% |' s4 [$ i7 l+ r4 c( L7 i        {255,0,0},
3 q7 k0 ~3 \: F) J' M1 C' L        {255,0,0},0 H5 `) z  S5 n: `2 }- k
        {255,0,0},//15- D! B" u! z7 _9 M$ ^% ~
        {255,55,0},
' h3 G' J3 k3 k- Z        {200,100,0},; y, |& M5 t9 Y& z! q: A
        {155,155,0},( y2 P& a5 m9 z3 a. u$ g2 O
        {100,200,0},3 Z8 Q% P% ^2 ~7 v4 G7 a
        {55,255,0},//20  T& A( @+ x/ p, I
        {0,255,0},//G,R,B
% @+ E/ Z  C& p. X& U' m        {0,255,0},6 Z5 b0 R. J$ |/ E: p0 A
        {0,255,0},
$ @9 I: |- v# ?/ p; {% L0 N% I3 `        {0,255,0},
3 M5 ^; j8 `) t8 j* t9 g6 H. m        {0,255,0},
7 K$ j5 q5 i* K! G+ w8 L        {0,255,0}," a+ {+ s: I1 X% h4 ?2 ~, f
        {0,255,0},
' E1 E9 V% D% N1 }        {0,255,0},
  Z+ U. u# M4 G+ U8 i: U        {0,255,0},4 N2 a3 N2 a& r( C) @1 b
        {0,255,0},//30$ ~% \4 T( B5 P5 f( S- s
        {0,255,55},//G,R,B
+ T) a0 y: d5 z9 W! ~$ \        {0,200,100},1 B8 ~6 h8 v* V- l  @$ V
        {0,155,155},, w8 M9 D/ g% x- m1 W  t( z! K
        {0,100,200},5 h6 `/ _! ^, r1 d" w
        {0,55,255},$ M6 G) a3 V: y, t
        {0,0,255},//35( l$ [9 l. e! D# q5 _2 T, E
        {0,0,255},
: v" j; J# o6 G8 k        {0,0,255},
1 T1 L  N0 f+ m- M. Q        {0,0,255},. W, U/ m5 j( O
        {0,0,255},2 P) K5 E2 l) ~. |
        {0,0,255},3 \  I+ A/ w8 ~  ?
        {0,0,255},
& ~9 M9 I2 L9 h+ p8 Q4 C        {0,0,255},
3 @6 U& l+ d& @6 W* P$ [4 x        {0,0,255},+ H1 Z; w$ G! `  I
        {0,0,255}//45
) s+ b3 P5 F/ ^                           };
6 Q6 g0 U4 L( N# {: Y3 ?9 m. F; \( p2 V- i, L: l

3 U: a' @- t$ c$ \5 G; W6 U, H这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式
* d! o7 ]4 H( V单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:
4 o1 u- b* K8 S/ ivoid TIM2_IRQHandler(void)  // 1s enter
8 B! {4 l9 V0 F! y- U; `{
8 a4 I9 ^+ L& M5 i3 d: H     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
/ s6 `' V- T' r     {
: q/ R4 O) X7 s. p9 \//                        ls_mode12();
6 E2 O; R! a3 E) }                if(++t2>=ls_speed)
' w4 x5 S& V+ N- C                {
. g6 y1 f  x" T% Z8 n6 M' G                        t2=0;2 i3 h" o% B" p# P6 |4 I  u
                        if(++ls_t>=led_size) //注意!!
9 B6 P$ I1 q& t/ `0 U8 C; x1 T4 a                                {6 g5 \- C0 e3 E8 d. X% n& X: H
                                        ls_t=0;
/ L& j4 e8 a3 B  K+ u2 r5 D" i  u4 Y                                }
; `+ R1 b  n9 D( l  ?                        }
3 x. ^0 d& Y; u* `; }. G6 F        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        / G# Q! N) K2 H5 V3 q! ]
     }  
7 v7 u  E; s7 x6 L4 S& A, w}
1 {# @, N( F, q  K- l
' K7 r7 l. C- `, L1 D
% z. P9 ^: e7 s- }0 S这样在main函数调用ls_mode()灯就流起来了!!' n% l  F  _6 J$ R+ u
漂亮的东西怎么没有视频:
, R3 t6 S# a3 C9 _/ M" @" \4 b9 w9 Q  F
P70614-085819.gif * `1 M: @" e# @- o' M

评分

参与人数 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:178 x: ~% m6 I: Z. m, Z' t: \+ i
兄弟,分享一下SPI是怎么驱动的?

% R* \: N5 S0 \% _思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:093 J' A% }5 s8 R) C: G! w4 v, f
我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...

' |6 }  `! K5 x, a+ `, D请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器
  R" W5 Q2 i7 l; y6 O2 E
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
$ w: f) b+ a7 @0 CMCU是跑72Mhz 吗?

' D% V/ Y9 B' V2 R1 M5 W3 a是72M的
时光虫子 回答时间:2017-6-14 16:19:52
做的不错,看上去很炫啊
epochal 回答时间:2017-6-14 20:03:00
不错。赞一个!
pythonworld 回答时间:2017-6-14 21:00:09
功耗如何,费电吗?
123下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版