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

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑
( h) y; {" o# N( b- s( i1 R1 f  L6 a* V% v- F1 V
其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。% Z3 ]1 W4 b$ [$ M2 F
今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。
6 t8 f6 G- w( d7 ?1 ~还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。1 m, t& V% \0 }/ g
驱动芯片:STM32F103RBT6 频率:72M
3 ^* e  I  z% [& P1 E( P说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V+ u0 `) W+ q+ H& q: V" D: c/ v
好吧,上程序:
2 ?9 j$ S1 u& j* e/ q( u+ H; uvoid WS2811_SendByte(u8 dat)//发送1BIT的数据
4 S% }* F% m4 k; L4 N+ K{% x; s% A  \; Y: u. N  i
        u8 i;
/ }) \5 t1 G3 R        for(i=0;i<8;i++)
* g- o# C2 ^" m* Q( }) X6 z        {% L/ x% X+ Y( {+ B5 J, `6 N8 D+ c2 W# ]
                if(dat & 0x80) //发送数据1
$ ~5 T* k% N( U                {; \# L  x5 j+ Z$ ?' z4 S
             Light_SDA=1;& L! q0 p3 v2 w
             delay_us(1);7 g# p  ?( l% d
            Light_SDA=0;" ?, K! z% E- v6 [5 ~0 C
            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
! M$ `( N! I/ ?7 t                }9 T9 k; D! t* l& x0 V" V
                else                        //发送数据0. U( ?" p& r- i+ b
                {
/ m3 }. C4 I; x            Light_SDA=1;//08 y8 k. E$ X! s2 \, H3 W' W! e
            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();; H3 @  v6 Z% N5 J$ I9 L; L
             Light_SDA=0;
' z% U# W0 F2 p( t9 Y9 {# c/ y" [            delay_us(1);: g/ C2 @; X6 L; Z5 h
                }
( H+ J# y% U" j  O& r                dat <<= 1;
7 z, E8 ]* O+ j3 f' u4 W+ N$ c# K        }
1 h5 W, E; t6 `% c" u1 k}! i* R. d2 ~3 e# |

3 j5 I4 \/ {# f
! y) F- [. w' F6 Q$ evoid Reset(void)                 3 \4 o6 _2 i( F
{        % G( V) i9 I5 j7 D
    Light_SDA=0;
; {& Q* @* e! g5 l, Q* ?    delay_ms(30);
1 Y& a1 v3 I1 \& V" s9 P8 r) K}
( x( c$ g2 o# @/ y; x5 W0 K! a: S' s/ h5 b
基本的发数据程序就这样了
: P+ i4 E! }* R7 r+ X" |. |' Evoid send_data(u8 R,u8 G,u8 B)+ e; M/ ?7 y/ o. n9 [6 p; d2 A
{! J$ j8 _: v% k' t
                u8 i;+ }( W1 K) R. V. N$ ~$ ^
                for(i=0;i<led_size;i++)" Q# L) b6 d" m% S0 K' Q
                {
$ L, M6 d8 d) F* g) x' Y6 S+ {                        WS2811_SendByte(G);
. ]3 _: W9 g: y, M                        WS2811_SendByte(R);9 ^# u4 u) @5 c; ]' g  ]: w; M% E9 @
                        WS2811_SendByte(B);2 ~+ {" j) P8 z
                }
6 ^- e# R  N, A3 P                   Reset();
- c9 ?: N# \& y+ K7 V}
/ s0 v5 s& \5 y+ \4 j
: Y5 A6 L; ?' k' s$ {void ls_mode(void)& n8 b: S0 b4 U8 E0 k& H. Z9 Q
{
1 x! d: }5 E0 b% t7 g8 @9 z        u8 i=0,ys=0,yz=0;: `) b6 A& A+ x- d  t8 P) d
        for(i=led_size;i>0;i--)) ^% ~, d0 e& g. w8 Q/ T/ v7 G
        {
- |5 W4 v# j* a" L( J1 s                if(i<=ls_t)* L7 x4 g) q  C" x1 A5 R$ ~  f# E8 `+ O+ x
                {
* l/ t) l/ W" f. y3 o# e                        if(ys<ls_t)
! k8 Z; M  l! o; B- a                        {. a. y; j. k5 V& s0 F
                          ys++;
; v8 `: c% r7 H' ~                        }# K! K# T4 e- T& e% g( X
                        else
& S0 n1 O' |. X0 l+ m. a& f3 O. {1 ?                                ys=0;: Z) U! j  G  I$ c3 t
                        WS2811_SendByte(LED_data[45-(ys%45)][1]);
' P. [# M5 s' v                        WS2811_SendByte(LED_data[45-(ys%45)][0]);
/ S9 r3 N, N& k                        WS2811_SendByte(LED_data[45-(ys%45)][2]);
" Q, F) i& J0 j% X+ ~                }
! F1 X3 ?2 b3 N; g& M; g/ W                else3 @7 z( P% h3 S0 ]
                {
5 S, C8 n+ a8 |* H" U3 G                        if(yz>0)
% E  I8 |- Q7 p1 x                        {
. ?1 G' y7 V# C- h* h# c' B                          yz--;
- ^. W9 v2 o  x! }9 M2 M- V. H                        }
& h: p1 R6 _7 U0 V                        else
7 n7 f4 }: V* b1 n4 R2 U( f8 B                                yz=led_size-ls_t;+ T( o; M' I+ p( j
                        WS2811_SendByte(LED_data[yz%45][1]);2 |7 t$ ~, A9 R: i
                        WS2811_SendByte(LED_data[yz%45][0]);
% D1 i( v& g" ]+ ^: a" t/ M                        WS2811_SendByte(LED_data[yz%45][2]);% ^* @- S$ h: i! J: O% b
                }
/ R; F# d% W6 }( T- S1 B        }
' {- h& I0 S6 Z+ j' {          Reset();. m* ]' }: B; S. c/ a0 U. v! Q
}- E8 \  [2 v+ ?
1 ^( l) M" S9 o% t+ s

: A( _. D' A% m( k这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!- Q* H9 ?0 A! p
const u8 LED_data[45][3]={5 X( M( N' c2 Q4 R* _
        {55,0,255},//G,R,B! L: w! J. D) m* E  p6 g) p
        {100,0,200},3 U* ~* O5 ^: a8 R0 V, C
        {155,0,155},, f5 U. r  O8 d) D2 u% {
        {200,0,100},( {' p+ S! F% `) w8 t* ?
        {255,0,55},//5
- A( \1 [/ X1 O5 d        {255,0,0},- |$ F; E8 M" V3 }7 @6 e
        {255,0,0},
) G% a. V& i0 z& e! t0 G9 G6 m        {255,0,0},
2 f( _3 y' ~! h  y        {255,0,0},2 g- P+ w& K+ N
        {255,0,0},
8 o; m3 B! Z3 d/ C        {255,0,0},
: i; R/ d' S4 v; B8 l        {255,0,0},1 e6 r3 l' E  b0 l% X2 m& M, f; E/ o
        {255,0,0},& e  g& x# ]& \4 Z1 x' o
        {255,0,0},% U. I1 Y+ x/ \/ M% _7 F, N% O- J
        {255,0,0},//154 Q4 Y& t, Q' c$ i. ?) [/ W4 @
        {255,55,0},
# o+ U6 F  N, y. @# q6 o; u2 C        {200,100,0},) g# h' q0 ?2 H5 i+ j
        {155,155,0},: w1 J7 s8 f7 U& S/ p8 `
        {100,200,0},
6 d. t, D; G0 k        {55,255,0},//20
! d7 a+ U2 x  C4 @# E# f) ?        {0,255,0},//G,R,B
" w' T6 V0 w, N3 c5 S. `        {0,255,0},
, X$ F6 }( O& {1 ]2 {        {0,255,0},  A4 _! ]2 P. S/ O! d7 F
        {0,255,0},, ?0 U, _! t9 y5 p8 a( h2 {. h- E
        {0,255,0},2 {1 S3 l+ i* _7 z
        {0,255,0},7 Q$ l. E% S, K6 |' ]
        {0,255,0},
7 b  M- g+ T8 ^( T) @! d5 L        {0,255,0},
' @$ _5 w( L: S/ n* M        {0,255,0},
: y3 z; v$ H! ~        {0,255,0},//30
9 y" F9 h0 E6 Z        {0,255,55},//G,R,B; ^1 Y# z: y& c: X+ @- e# m
        {0,200,100},
5 n9 e8 f2 W  D: K& J+ l5 }        {0,155,155},# H* E9 C, e: b8 v& ~7 c& k
        {0,100,200},- I6 L+ N/ L2 Z, M6 S6 F2 n2 |
        {0,55,255},
8 B+ P0 i8 }. p* y. [        {0,0,255},//35
0 P, d- n. }; a1 [) [0 T        {0,0,255},
% {/ v- h8 D6 D) L( P1 o" l$ Z        {0,0,255},
# D) J# [2 d0 A) T$ y5 T4 h/ A        {0,0,255},
/ N$ N: E6 l9 I4 e" ^5 N  ]        {0,0,255},* h. ~$ T8 q$ \# ^8 _  `
        {0,0,255},
8 z, P) l# {8 B6 A( _  ^8 i7 }        {0,0,255},: o1 |5 o, F# l8 x- H1 V4 z" v
        {0,0,255},4 M; e6 _9 l! [$ D7 D! j* l
        {0,0,255},
; f$ K0 P: Z3 c        {0,0,255}//45: Y& e( x* E; [: O9 q  |
                           };& E; V0 W7 u2 E! G) i2 V! k4 w

  O5 U- [+ t( M$ m0 t: b, R1 @: m6 R$ M9 C' I! f8 t* j
这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式
8 P! O1 ]5 K+ u4 Z) ~0 F单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:6 h  b+ {3 d: ~1 `& l; C
void TIM2_IRQHandler(void)  // 1s enter
1 \& m* {% q; s1 A! Q) P& d{
1 e4 ]4 O% h6 P8 l# [  s     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
9 A2 v* X3 a$ c& R     {
' k6 q# x4 q9 j  w//                        ls_mode12();
4 j3 y3 a* K4 f1 X# g                if(++t2>=ls_speed)
7 a" G9 l& x2 V& z$ t                {3 A( |' F- @6 G' {; S. M' T
                        t2=0;
- S# [8 v( e# s$ J& N" k                        if(++ls_t>=led_size) //注意!!) c6 }7 O. T  X! E$ G/ P
                                {
" x! f5 H, ?, \+ I0 F0 A7 s9 s                                        ls_t=0;
# h! T* d. t3 A  E                                }" b" r1 r( }$ `
                        }
3 g, a5 k$ H) v5 m( @9 M) w* M        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        
! [5 X+ g, t2 a1 Q! z     }  
- K# `0 v! O( U}
. B7 d) U% r$ z% c( d0 F
' m& v; U( ], n0 c/ @  N$ C& M, g  E
这样在main函数调用ls_mode()灯就流起来了!!
' {2 x6 }5 t, |' h漂亮的东西怎么没有视频:* ?: @. |5 y0 l* s
- p! U8 N# `- C' @# |1 E+ Y  G) l
P70614-085819.gif 0 h, L9 R3 x+ I6 b" l, V, d6 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:17' B2 F5 C. V$ ]& w: T
兄弟,分享一下SPI是怎么驱动的?
& f2 K3 x1 o) U6 b$ L
思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:094 s. k- s: r& J! b6 q3 s2 H! B
我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...

4 ~( v1 U  C5 W请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器
* Y/ x; P( K; Q/ f7 F; x- Z5 S
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
% b, }& S4 T6 UMCU是跑72Mhz 吗?
9 E; q( L  g& ]1 Z1 y. |
是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 手机版