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

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑 ) j  ~+ h; V7 H: J
2 y/ E* O: [$ H/ m! ?8 U6 }
其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。2 Y& `1 N. _! i6 v8 y- q
今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。
) c% H$ m9 j* ~还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。5 |9 s) ~' e3 j4 Y
驱动芯片:STM32F103RBT6 频率:72M
( i( _4 ?" x: }- k1 v9 G( M说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V( h3 j( h. {+ w$ L) K' h6 w; _
好吧,上程序:9 F5 _, c6 t; A1 i* w" e4 U& |. b
void WS2811_SendByte(u8 dat)//发送1BIT的数据
& u/ Y! q0 ~- @. t7 V: E' F1 B" }{6 a* L! w1 d1 H0 M2 v7 [
        u8 i;) y1 B* |4 E: C3 A1 `' M" b3 a
        for(i=0;i<8;i++)
, M( [4 ^) u: [8 Y        {
5 d; ^! T9 \! f; ?7 z3 u* ~7 K                if(dat & 0x80) //发送数据1
: C1 n6 V; j: `; I2 V* k- f                {1 i$ w" Z9 K4 g+ d2 t
             Light_SDA=1;
* X( Z& }4 y9 [6 Z5 C! v, ~0 r6 y             delay_us(1);
* ?9 k$ K  m: {5 s( e8 p            Light_SDA=0;
( W" I- z0 j1 k% a, x            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
4 K- l7 z- z6 x1 M3 s                }
0 _3 J- S$ w: H                else                        //发送数据0
, ]  x% B+ Y3 I4 k" U                {8 D3 \- t5 l' A# S+ ]1 f
            Light_SDA=1;//02 h% G* K& Z# L( X5 `2 q/ J* a2 E6 Q
            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
' S1 P$ m9 [' Z  u/ P* p             Light_SDA=0;' B+ `+ i$ A2 @) X8 g# M/ M1 P
            delay_us(1);
" K3 I1 r2 R4 y- ~8 G& U6 d                }! \1 b8 v. \! l' o! G5 z6 @
                dat <<= 1;: ^9 y7 H# K- z9 o& a$ }& N$ e
        }( \' B/ f) c5 O8 {% {) a
}' O& k5 u. G6 v5 s' B# a  j! d! Y( K
" q8 x# r1 k; x. t/ V

, |& O, j" u/ ~; Y$ v: I- P. Fvoid Reset(void)                 
- H, `5 t, D! h9 T5 e# Y4 W1 d{        
% B4 k. l( k) a    Light_SDA=0;& n( g: a+ W+ d5 u. _
    delay_ms(30);
5 K$ g- }1 p, ^1 A2 {( f}
0 h- Z8 e* ^6 ?) w( {
! n$ `+ v0 ^  `  y* \1 `5 D基本的发数据程序就这样了
6 [; t: ?5 f3 Svoid send_data(u8 R,u8 G,u8 B)) t7 g, H( B5 H$ ?7 u! l4 ?3 z& `
{
# D/ H1 }* ~) g" ~9 \                u8 i;
  D' q5 U% }6 l& W                for(i=0;i<led_size;i++)
" A$ @+ ?, u! @* c* p                {- [- A/ o5 ]6 B  u9 `8 r% O: d1 k7 P3 K* L0 z
                        WS2811_SendByte(G);$ h5 B  r3 v1 o+ `: V
                        WS2811_SendByte(R);
8 d: g; i8 A# S9 z$ J; ^                        WS2811_SendByte(B);$ p/ `$ {* h* U
                }# E% U/ A9 Z* A6 h
                   Reset();) Q' B. E+ p# z
}
6 z9 q, G3 {" {* h9 y: [4 S( }( D. n% k" W# O. T
void ls_mode(void)
6 L3 z% H* P' _$ t/ u1 {{
. t/ r; D7 P' U2 T: p0 V        u8 i=0,ys=0,yz=0;0 V. T" p( S. q4 n) Y( d+ Z
        for(i=led_size;i>0;i--)* J# t+ }5 }- u# X
        {
$ g! t5 C5 j3 K0 X0 ]2 D                if(i<=ls_t)& m1 }1 {) }6 m4 \$ l
                {8 |, B, B3 k4 e& a1 i4 c
                        if(ys<ls_t)
$ Z0 O; }" `' A! M& R                        {
: ~% i' C1 @* W                          ys++;) L: v( }5 c" b& A
                        }
" i* l& z* x1 u2 r% @# }                        else
' V/ C. z% G  |9 U+ A. J. {                                ys=0;
$ a% o1 M* G5 Q                        WS2811_SendByte(LED_data[45-(ys%45)][1]);$ ~; e* T: W- C  w! C
                        WS2811_SendByte(LED_data[45-(ys%45)][0]);) V, @  y3 w; x5 P, t7 g" N
                        WS2811_SendByte(LED_data[45-(ys%45)][2]);
5 E* A" n# p8 l                }
7 o* ~! O, I+ Q9 u) t5 O                else4 P+ e$ ?; J1 n
                {* o& ^- ?' U  V8 C0 A
                        if(yz>0)5 |- O. t. N/ D( g- `% l
                        {
9 g0 u" u" z/ {. t1 ?: R                          yz--;
; W+ u  G( P( y+ {  @7 w                        }8 p/ o' f* H. e! z
                        else
0 {  L! Z5 h! J# w8 i1 o8 x/ v                                yz=led_size-ls_t;, I' a: G- P6 C* a
                        WS2811_SendByte(LED_data[yz%45][1]);
$ G3 P9 N* c* M% d% q  h                        WS2811_SendByte(LED_data[yz%45][0]);
9 G' V& o( E- T; U' E; j: u2 X4 Y% D                        WS2811_SendByte(LED_data[yz%45][2]);9 b+ Y: j( F* U  Q4 r+ I
                }
, z2 G4 ]. i- @; w        }& K( a: u: _1 P# I0 K9 v
          Reset();! c( K# i" C5 U
}
. C  V; i9 I& ?5 ?. B1 L8 \2 a1 R0 d, w# u! D

" K7 ^0 p0 ^; ]2 K; b1 `这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!1 a8 g2 |; r8 K( i9 S/ ?  g
const u8 LED_data[45][3]={6 G) j& H5 i7 F, U. R
        {55,0,255},//G,R,B1 U8 c/ e3 ?4 @* P
        {100,0,200},
0 o& E& O  X' g, W( O+ e4 ]        {155,0,155},4 k4 X, Z# z5 {5 k5 P4 Y) K: m
        {200,0,100},6 G, Y) s2 @0 d3 Y
        {255,0,55},//5. u# A9 j! ~% O# G2 D# T
        {255,0,0},9 P' S% i7 J! J" y+ j4 c
        {255,0,0},2 Y" q. Z% K2 o4 f5 _3 O- H
        {255,0,0},, I; v, W$ A" D/ {* H- X" Y
        {255,0,0},
7 p  h5 G& a* q0 q% p+ H- c) b        {255,0,0},; w2 ?: E9 n& \, i: Q  m1 _
        {255,0,0},4 J7 _- y+ y! \7 w( i! H
        {255,0,0},0 `; w7 w8 f# ~5 I
        {255,0,0},$ a$ x! v- o6 {  o2 U9 {! D
        {255,0,0},
! Z3 o; i/ u  ^! ~: L/ S3 U        {255,0,0},//15
6 `0 @" i3 x( Y" {        {255,55,0},
' b% G% o0 @8 N8 r1 d9 O        {200,100,0},+ I0 H! Y8 ?6 Q4 Y1 h. i+ {
        {155,155,0},! v" Y# F1 p$ Q) B: d
        {100,200,0},1 Y* w0 T! o/ T4 T4 d
        {55,255,0},//20
0 X8 S# e& b* w# F7 t- y3 T        {0,255,0},//G,R,B
: D' s5 r; q$ N" e# [* V        {0,255,0},
6 x( K' V/ e; b        {0,255,0},. p+ E, ^& Z5 X$ x
        {0,255,0},
5 h/ u9 I$ O: t2 o: c; K        {0,255,0},
6 V9 ?1 r+ G, M- w6 t        {0,255,0},
" E$ K7 w+ N8 Q% I        {0,255,0},
6 R8 W  ?+ T8 Z  k$ ^# ]        {0,255,0},3 u9 o) @# M8 A
        {0,255,0},
0 O; A; T9 m# }# O; _! @% X        {0,255,0},//30
- l5 L5 G, G2 N2 |; l        {0,255,55},//G,R,B; X. ?: P% I. F, ^; x& y8 u7 g
        {0,200,100},# [. k( T7 a9 ?& w/ v. G1 C
        {0,155,155},) n4 {: c0 k% `1 K, T/ q
        {0,100,200},! _4 R9 j* n: R5 [6 Z7 ], l' z
        {0,55,255},* H- C& ~7 M. n$ M( v7 u' b
        {0,0,255},//35, X0 G9 }% b: G0 D
        {0,0,255},
; f5 p% y, v; E" ^8 {8 q        {0,0,255},5 b( E% ]9 I# \- W2 m6 `0 }7 q
        {0,0,255},
# Y# w7 [$ o5 ^, ?- G! k        {0,0,255},' Z; G! h+ G; x
        {0,0,255},# t8 c! a5 _4 L
        {0,0,255},
/ k6 G8 B1 {4 U7 N5 g        {0,0,255},( f6 [+ B/ H2 W$ K2 C& d
        {0,0,255},- Q4 t* b/ _; F- V
        {0,0,255}//45
1 H& _7 e& @6 d' i                           };& R# I( P5 D( C/ _; ?
, k& c6 J0 c2 T; H' a2 q
/ x: K. S( Z" v  W
这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式% Y2 r# [) ?" ^; P
单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:
, ?3 _9 x3 C* u5 w2 e1 V  vvoid TIM2_IRQHandler(void)  // 1s enter
$ h4 E- Z, _6 \- v+ B{
2 U/ A7 J1 k# h     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
/ U' ?( n" ]; g  b# J# |  w     {
2 Q! l: j+ P: t/ q& b) K- a/ z//                        ls_mode12();4 g$ W0 y1 B5 P! F5 ]; `
                if(++t2>=ls_speed)
' e+ E% }- q  M: Y                {
+ a! _( l- Y) E( e$ @4 n3 U! v                        t2=0;* N+ k7 k# V3 G: l
                        if(++ls_t>=led_size) //注意!!, v- b4 F% I' h0 Z
                                {; z1 u, q  L; Z; h" P* t) c
                                        ls_t=0;/ n8 u' F& z2 I5 `8 d" V( [" D
                                }
4 q+ Q. a7 c# R2 c                        }* {$ x* D- \! L' s$ X/ R
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        
) {* I- }$ A3 j' ?     }  $ O- W8 x( Z1 `! L% N
}+ V- h- y2 L# E  f) X& l% @5 S

2 z, K6 |( N! n7 V( ]4 a1 \$ _5 n9 a8 L3 V
这样在main函数调用ls_mode()灯就流起来了!!
# ^8 }$ x8 M, D( E- I* Z漂亮的东西怎么没有视频:
; S. I: b. q: V; d( a9 q
* M* F* ?2 ]$ X, ]- X( c P70614-085819.gif " }  F- t& Y/ a

评分

参与人数 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% _, o4 _" x& R! Q- F# S
兄弟,分享一下SPI是怎么驱动的?

  H, d& S7 p) F& z1 J2 _思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:095 U; ^, J- |; P3 q& J/ G
我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...
* E1 H# a9 ^$ B  R2 U' f% Z
请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器
8 K6 v; i( [0 Y8 Q
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 O! n: a$ D# r1 hMCU是跑72Mhz 吗?
2 H, P2 B1 z/ d$ q. M0 V
是72M的
时光虫子 回答时间:2017-6-14 16:19:52
做的不错,看上去很炫啊
epochal 回答时间:2017-6-14 20:03:00
不错。赞一个!
pythonworld 回答时间:2017-6-14 21:00:09
功耗如何,费电吗?
123下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版