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

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑 ( {* C" Z- S$ e, P% ~
* G: M. _" ~2 y2 @8 z, l
其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。3 ]! P4 X, @5 w) D+ _- _
今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。. s7 u; W: [1 A- T, Z1 z5 H9 Z: j  _" l
还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。
' A( _) B# G$ V3 U% {0 x! O驱动芯片:STM32F103RBT6 频率:72M
8 O/ T% ~" x; M( {9 ?, a0 ]1 q$ T说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V
6 e# D1 ~; @0 V: Q4 d好吧,上程序:' D; K4 h, m8 @
void WS2811_SendByte(u8 dat)//发送1BIT的数据
, L# K9 }  H+ I5 z% f{1 R" t) b) p. r% B& Q( {
        u8 i;
- R. F- R+ Q$ q; e# g5 B6 \! S, l        for(i=0;i<8;i++)
* k( M" D7 y% I- x+ [3 V        {1 r4 T+ m6 G$ S# T8 z
                if(dat & 0x80) //发送数据1: ]4 e' `/ [! `9 F
                {0 w9 n; e+ g8 X5 N/ Z
             Light_SDA=1;: W2 S: e- Z0 c% v9 U) R
             delay_us(1);; g/ Q- T9 t6 e3 W: [2 _
            Light_SDA=0;, Q' _. ^) C) v7 m/ M
            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
& T9 w6 y4 E% M& B! [9 G. x                }; q5 Q3 C, ?, Y5 N5 ^) l
                else                        //发送数据08 v( m1 u, B: v/ h4 l
                {* `. O! m3 V! u
            Light_SDA=1;//07 U) }2 M% j7 {6 N) `' B
            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();6 O4 d! y, x, Z
             Light_SDA=0;
9 |6 S. r7 Y3 E8 D! r! U3 R6 n9 [! m            delay_us(1);
0 z2 L. T- l% i                }
. H- k7 X: w& r! \                dat <<= 1;
& Y6 F% `9 {8 _7 q+ X        }: f; h' `1 w* Q* ^6 B
}- ?& v" X6 c+ Z9 J1 p$ c
2 Q* i5 x0 C0 y. x
* p- w8 l! X" `
void Reset(void)                 " x4 s% i7 v5 y$ z# `  f" R
{        / N7 X/ B3 B8 W
    Light_SDA=0;
) b3 ^- g- `0 {# a  y! Q    delay_ms(30);+ L  k" P* t7 B  e/ ~( X  ?
}: R% Q- u. B0 M- `7 b1 j: N
; S! N' j0 E. F( p5 i0 k
基本的发数据程序就这样了
, o& T5 R# o, U7 X& [" Z! Vvoid send_data(u8 R,u8 G,u8 B)7 u4 I3 H5 K4 `9 _! c
{
& b4 N' N% A" F  Z; |                u8 i;
! s2 N) g$ ]0 S: Q                for(i=0;i<led_size;i++)
3 s8 S7 ~' @- [0 A" s                {# w# O, w$ e2 }" H7 ^8 V. @
                        WS2811_SendByte(G);
7 _% o+ B0 N* V; |                        WS2811_SendByte(R);
& _1 d4 A  v+ Q4 Q: u5 }' T, m) D- U                        WS2811_SendByte(B);
( }6 U3 R3 S- X% E5 U! u+ R+ t                }
9 A# ~  v* a6 ^! N+ Q                   Reset();9 w3 o' y! X' I- |  o# k
}( H/ D/ v8 Z1 \5 o) Z, D* `6 R/ J
" Q. B( x$ R5 {: Y. N5 O
void ls_mode(void)5 Y+ k: C2 X% d& @
{
) z0 S0 i" ]/ ?, `        u8 i=0,ys=0,yz=0;
. ?" D/ j/ ^, A! G# V/ [  E. `8 `        for(i=led_size;i>0;i--)8 T( x% t* @/ n- j6 P0 ~2 `
        {* g6 N% v2 ?( R& n
                if(i<=ls_t)
* W  p+ `* O; N; ^+ p8 l                {; B8 A8 n( s0 A) ~0 n" }8 R$ \
                        if(ys<ls_t)
: H7 I% J8 D: A8 C6 W                        {
2 H9 j: E+ p. A( c5 D. A0 U                          ys++;7 o8 k5 v2 \5 Y8 U$ \
                        }
# c" Y) Q9 J, w) x                        else# ^! V) ]" c/ c) }- U( h
                                ys=0;
( H; _5 G9 h7 e                        WS2811_SendByte(LED_data[45-(ys%45)][1]);/ [$ D0 C: ~4 k- O# r( [
                        WS2811_SendByte(LED_data[45-(ys%45)][0]);
1 L' \4 e0 r: U6 z- a1 S+ g                        WS2811_SendByte(LED_data[45-(ys%45)][2]);9 s' o2 ~. j: o: n% f
                }+ e" v* T* ], W- ]
                else1 j( \. [/ u- K- d8 A: d1 A
                {
4 n1 G2 {9 o: l                        if(yz>0); n! v$ r% t3 j, X1 T
                        {
$ M1 p% u( r8 j. P* V6 I  q                          yz--;7 ]: w" h% k3 ^# w5 M% P
                        }  i) Y  X2 a* Q  ~
                        else
. Z; ]3 z1 W8 N  ?                                yz=led_size-ls_t;
6 o8 b, U% l( L! X* o$ N' Q- J                        WS2811_SendByte(LED_data[yz%45][1]);
/ V+ u8 W3 b6 e) l! ]6 m: @6 D                        WS2811_SendByte(LED_data[yz%45][0]);1 I( d- E+ M( D  ]$ R6 W
                        WS2811_SendByte(LED_data[yz%45][2]);: _0 b, }, o: J2 ]7 Z" q  D
                }
) m" V: {7 @( A, {        }
: E1 ]9 r3 c! y! g          Reset();( k# d# X9 j) {8 ~9 J5 i
}
4 X* F( C+ M: }  _) X! ~8 p1 H( M0 w+ b- O- N3 Z
) K2 ?4 [  c0 S
这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!/ q. h# G' k6 b% F' Z4 u
const u8 LED_data[45][3]={
; ^: e" c7 {) T0 ^        {55,0,255},//G,R,B; K6 Z4 H1 P  |- z
        {100,0,200},
: V' M# ^. G) X/ u9 K6 n' G        {155,0,155},. o. ?3 [. I0 ~! r" p& k! \1 U/ W& O
        {200,0,100},
7 c  Z2 C1 k; S( s, E        {255,0,55},//5% h3 W% P* G  _. j6 `
        {255,0,0},
; M: X. F' W! l/ T; \. [+ x3 |, c        {255,0,0},7 H; _! a, ~1 ^0 l, o& w
        {255,0,0},& j& L$ L; \% g# `* }8 Y% u
        {255,0,0},2 A  S0 N) U! _8 T4 T' w
        {255,0,0},! [( b% h/ e: b& S/ w4 [6 {
        {255,0,0},+ Y& W3 q) V9 x; Q% ]$ T$ @
        {255,0,0},
, m+ O) l; I2 X        {255,0,0},% O# C4 ~8 b# u* k) h  Y
        {255,0,0},
4 }: P/ V* h5 A4 A. C        {255,0,0},//15" r: b+ o2 A; f% G9 t, U( Z
        {255,55,0},9 \  D0 j2 @8 g  y4 C, O1 I
        {200,100,0},5 B0 x6 |8 M1 g7 X1 n
        {155,155,0},
7 x" y# X4 H0 W, {. `# V        {100,200,0},3 a' w# l4 f9 M; {) r. F
        {55,255,0},//20
% M" D3 U& z+ q# \1 w5 h* \        {0,255,0},//G,R,B
! ]$ {0 c2 P" S/ {  B        {0,255,0},
1 m& e3 L# C$ s$ S7 s        {0,255,0},
0 a& k2 m9 d" Y8 N! i        {0,255,0},
+ ^6 ]5 l0 S- ?, ?. J- o        {0,255,0},. p. A) K( U4 M$ M" t) X
        {0,255,0},( ~2 x8 D# x+ c! [' v% P, P- R
        {0,255,0},
& E% J, {6 B% E' ]* T; U  t- x3 p3 q        {0,255,0},
6 c* ~) ^8 n! H7 r7 z        {0,255,0},
* O9 |) x3 H7 X2 Q3 R" C        {0,255,0},//30
9 f# [3 u3 |$ A        {0,255,55},//G,R,B( }  H# i! u  i+ L5 i5 H
        {0,200,100},& o; G  K, N7 \
        {0,155,155},2 H$ s  V+ Q) p; r0 `- ?7 h7 q$ l
        {0,100,200},
! M, S3 I4 M+ {0 A& s  K        {0,55,255}," X: e3 B2 i7 x& ~9 I
        {0,0,255},//356 t+ ?/ e3 q- C* h
        {0,0,255},
6 J" o; o7 P" v# T        {0,0,255},
1 v$ b. h' S) C7 e! s9 y; B        {0,0,255},
3 R6 ^, k0 f0 p1 m2 D        {0,0,255},& s5 T( E' B4 Z( q% U
        {0,0,255},( K2 p0 s; B) e- {& t
        {0,0,255},( ?  h+ A( [4 B
        {0,0,255},) t* [6 N( L$ n' _/ E" X, d
        {0,0,255},$ A' r6 }. K( [$ r8 {) t- I6 T
        {0,0,255}//45$ D+ p6 t7 U4 X+ ^
                           };$ d: D/ W( q2 j3 K1 G/ L

& Y# Q5 h. e5 E1 n/ k1 @- e
$ N) Y7 y% t( b! ^: I. E这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式
' c. C" w) t: K8 O单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:; M: o2 x; {0 i' [+ W
void TIM2_IRQHandler(void)  // 1s enter8 ?# b* Y& j2 v* T
{) k. ~1 ^/ l' i* \% f3 \' T
     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
3 n% H9 c( v- V+ N: q/ F     {( v! i1 }. |+ d$ s  I4 ?
//                        ls_mode12();. i. H2 b# {" F/ M
                if(++t2>=ls_speed)
1 U, n" p+ f- R5 K3 C                {
2 a+ Q" B3 \8 v$ P                        t2=0;6 ], V/ P$ L' ~" K- Z1 R
                        if(++ls_t>=led_size) //注意!!' Z, ?% t7 w$ R, X
                                {
: E2 ~7 R+ K1 C) W* O+ E" }                                        ls_t=0;
/ @" S1 O. s0 X% j& W7 @& o  E                                }
9 {( t- Z, H1 }  G, s                        }* v) T8 g$ ]2 r* t
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        
% |% ?0 f; T0 E8 ^4 G+ t- _( Q     }  , w2 |& z! Y# P, M5 q# G
}
7 H$ Y; ?# W) c- z! T# I9 F; a2 J* a, E7 i7 p. j# E9 l' k

+ s8 Z: K- z: E- r& l5 J这样在main函数调用ls_mode()灯就流起来了!!
% r: o" z& q* q% n& J1 U  m漂亮的东西怎么没有视频:3 ?9 }& [. a7 _  K0 n% P& m8 L
( g. l5 l( R2 Y% r$ l  _3 L
P70614-085819.gif
( F5 [/ s: o* L& _% f& c! k

评分

参与人数 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
$ Y3 V0 U9 u& s+ n兄弟,分享一下SPI是怎么驱动的?
! |& u1 r! i1 m; T( k( J
思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:09
; w4 C* g. ]/ m我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...

9 M# S. f% V) @( z! y! W" ~请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器" T9 W9 P9 x8 i* l
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:065 l: T! r" t2 s' C6 A
MCU是跑72Mhz 吗?

8 r( r. _( S( a, p$ E6 s" U7 N是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 手机版