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

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑 & d) I6 d; I& ^

( [9 h+ F) O! b- {# P其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。
9 m" _+ W0 G& _% x今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。3 y& v/ v# C7 z: G. i2 j- X
还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。
* x- F" T6 L2 U& r( i# n驱动芯片:STM32F103RBT6 频率:72M
# `8 t+ O# u+ M) V1 p; Z" ~" o说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V
, v7 U# n' i- A* V# f: d" B7 s好吧,上程序:2 n2 m8 Y( r- T0 Y1 m0 j, U5 K
void WS2811_SendByte(u8 dat)//发送1BIT的数据% Z5 O5 f5 t; \8 u4 q
{
8 j% z1 m; J4 ~2 f9 I9 X! E        u8 i;
/ s2 y2 ]$ a2 ]# N        for(i=0;i<8;i++)
4 W% m, G$ v6 C6 B4 @        {
: P; T) O: Y+ U) G& M                if(dat & 0x80) //发送数据1" K# M: H7 ?0 u( w  w# X' e' p
                {' R( j$ i. h* O6 Z# d) ]0 ?
             Light_SDA=1;. b  I& q8 _. e- @3 t" E2 j
             delay_us(1);
( m# V* j- ^! r3 G            Light_SDA=0;3 s. E1 y4 C+ T. [
            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
6 Y# z/ D! x5 R; C) {3 x. i1 }                }% o) s" T" R- |
                else                        //发送数据0
# c4 `6 b- ]1 k" H; R+ l% ]                {
: |  A  @$ ?' b* y1 S            Light_SDA=1;//0
; K( E% h- B5 [1 Q' z# K6 j            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
2 w6 l% \+ N* o- l! `  T             Light_SDA=0;
: h: c5 Y6 [- t' P8 H1 o: y            delay_us(1);
4 t8 u7 I' p, V- U                }7 y5 A, y) X3 r& ?* P; \- ]
                dat <<= 1;
. H. @( w3 U+ u        }( X+ d: Z. `! h" d
}
' x$ S* J( A$ h$ X
+ u# w* x9 ?5 a- d# W+ P* \
' }$ r4 @0 n$ r. B7 Rvoid Reset(void)                 
( l) D. F- O7 g/ O* J" S{        ) ^% N. i8 l$ {+ V$ W
    Light_SDA=0;
$ S  j' ^$ w, B5 E) N    delay_ms(30);
$ R, L& X/ e6 a}8 q4 d6 v, p9 W/ a$ r

2 j) D8 e8 Y' Q- N  l基本的发数据程序就这样了; }% N9 S! F. u6 ]$ q  U
void send_data(u8 R,u8 G,u8 B)
. o; G% C# p- Z* `4 c5 ~{5 O# X& _( c1 t, a
                u8 i;! k6 j0 K2 E9 A$ X
                for(i=0;i<led_size;i++)) I- {- ~( J3 S
                {
. O3 v+ {; X- O2 K7 n                        WS2811_SendByte(G);# `" @  S! I5 M  M1 A& W2 L
                        WS2811_SendByte(R);  ~" L$ q! P) R0 w! @6 r& A. B
                        WS2811_SendByte(B);- i( P% Y0 P: f! Q
                }, J& z& \( r' r, B
                   Reset();
. d  Q' A* T/ B' p5 ^/ g}. N! j; H! {9 F7 W3 o4 x1 |* m

' F7 G. e2 f  L% N" z% r" t6 dvoid ls_mode(void)5 H, b* m9 y6 s0 i* i
{" B" |8 g8 ]- Z- `+ j% T- v
        u8 i=0,ys=0,yz=0;( f. h* g$ L% Y& u8 `, |5 H
        for(i=led_size;i>0;i--)
, v1 G- J2 H9 F; d        {
$ B  J$ X. y7 v+ n$ j/ c  b                if(i<=ls_t)' W' q, U9 \% {; Y9 Y" L& ^( J
                {
7 U) C$ B- }% ~* ^% V; E6 b; g                        if(ys<ls_t)% P' ^6 P! V. t( }
                        {
9 d, x' `+ g: {" p( b( j# K                          ys++;
8 N  i. J! ?* w9 C9 i) e% r; U                        }
6 v! I+ x4 J  s6 r                        else% y0 ~8 Z  f" x  `
                                ys=0;
6 ]4 r8 `7 D# a9 |7 ~                        WS2811_SendByte(LED_data[45-(ys%45)][1]);
. b9 ~# }$ k0 ?& [+ C1 W# R                        WS2811_SendByte(LED_data[45-(ys%45)][0]);
& |8 c6 s! O# u* N. g, y8 T6 z                        WS2811_SendByte(LED_data[45-(ys%45)][2]);
6 e% \% Q4 m5 {                }% X7 y' f' k- W
                else8 g  v. w! X: L- z9 y
                {
1 F8 A. S) N4 P0 E' y                        if(yz>0)* [: H* o- i! z
                        {
0 X* |. v" t$ ]. w! @& k) M                          yz--;4 ?7 S# u3 i! o% m/ l% r: _* e4 l' O
                        }, _8 l) C$ Q0 z
                        else
+ y5 f# b4 z. D7 P  x                                yz=led_size-ls_t;* a- _/ e, |* Z
                        WS2811_SendByte(LED_data[yz%45][1]);
" ^2 U$ V% |/ c+ _& [                        WS2811_SendByte(LED_data[yz%45][0]);
* g7 T; J. Y! y5 G( _! T% P! U8 M                        WS2811_SendByte(LED_data[yz%45][2]);
4 j7 E2 I7 Y6 {- h2 P                }: P: W$ `1 p! T# b) m7 w
        }( T! k1 Y4 F( h# |: k  y6 ~" v5 {
          Reset();8 i3 |- D8 j- [1 x/ T
}
/ e. T& S  h5 {. b- I% `4 f% U# D/ ~+ N2 x, i

8 h3 \+ y/ E7 p% Y这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!
! ^6 q, z$ }7 f- |, q+ ~. Xconst u8 LED_data[45][3]={8 i; Z. ?4 V. a- N# F
        {55,0,255},//G,R,B
# ]. c7 Y2 W& m1 h' R1 A        {100,0,200},. w) Q* v9 N4 c5 z
        {155,0,155},
7 c5 e+ z. z; T( m8 @+ X        {200,0,100},2 i% ?. b8 a& n
        {255,0,55},//55 ~) \) `1 [1 h: q) `/ y+ s2 y# s
        {255,0,0},
$ k4 z$ a6 X0 O" w( n        {255,0,0},
4 }0 s# A5 D: a3 P        {255,0,0},
% u/ c8 }; j/ t: o        {255,0,0},; U" E! u7 P4 E  A: x
        {255,0,0},9 U; `8 k( ~/ j4 T6 @* R2 E
        {255,0,0},
1 G' n5 k( n- e8 C" @/ g        {255,0,0},& h+ ?$ g6 A: b+ j. C9 }
        {255,0,0},
( t8 M# e0 n1 ?7 i* M        {255,0,0},( B6 d& n4 `; s4 ]7 K; e- s4 ~% A
        {255,0,0},//15
4 x! ?2 R8 Z8 q) l  B) H: I: y& y: c        {255,55,0},7 m% z7 W" e5 n3 l
        {200,100,0},
- ?4 N5 q% R5 c- W0 q7 H        {155,155,0},
# S% j1 q( f7 ?9 J4 Y7 {! Q+ k        {100,200,0},
! d, V/ U' b2 c  O        {55,255,0},//20/ ^* F' k# C7 `0 }' I3 i9 n
        {0,255,0},//G,R,B
* V/ l0 U. ~5 W; w* z& x* w) q        {0,255,0},
% T4 n  o* P  C' ]5 ~, X0 k# k  w        {0,255,0},2 |, D3 z0 D! k) z+ d
        {0,255,0},
3 ^! R6 {+ \1 @& s3 o, B0 b        {0,255,0},0 L- c% r6 G: f: j3 S* a, u
        {0,255,0},. X1 j. h4 v1 Y7 H
        {0,255,0},4 Z9 s7 @$ L- V2 X/ \
        {0,255,0},1 _2 [4 M2 k, V- |
        {0,255,0},5 |/ T6 m6 ~* |/ _; B" k
        {0,255,0},//30
. ?2 B: w: A9 E% x1 F        {0,255,55},//G,R,B6 F% R/ }" ?; U- l0 m
        {0,200,100},
) ~; N7 S" @/ z5 b! o* R& \* P4 Z        {0,155,155},( r! p" S# I  h0 |
        {0,100,200},5 p6 s  {* ^% Z2 Z% }
        {0,55,255},0 Y1 J" N' R3 r8 y. k5 b
        {0,0,255},//35" _8 e8 h+ V7 b; h, t' ]3 ?* Y9 I
        {0,0,255},
- X9 [! Q: T& S! G6 H" R        {0,0,255},
$ [. b, Z( G+ q6 K/ u8 W        {0,0,255},6 H$ z- v" D! S$ v& Y6 ?
        {0,0,255},
. _& M& |1 w( _( C4 }/ t/ p        {0,0,255},
& P& `0 n. r/ w/ g        {0,0,255},
' y1 o3 s/ k- o* Q, {        {0,0,255},1 I8 h, F( Q) y1 z  h* {' T
        {0,0,255},' G: s) {% [- g
        {0,0,255}//45
0 O* Z2 q  L8 p                           };' s* }# n- F- r2 j! H9 N0 S
6 {, h  X4 E1 @, U$ b1 ^

' C; J3 E: ]3 f6 l4 j3 l$ d  J这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式9 Q% @- F+ b( S" f
单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:
/ F9 l5 j4 @/ I4 m4 uvoid TIM2_IRQHandler(void)  // 1s enter
; C, v- T" w! L3 T" P{8 D; B2 N  ?1 G9 W% _7 B& E
     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
8 ~7 v# }) M# h     {
. W0 T; i- ]+ E3 e* o. K//                        ls_mode12();( n: P. D" g' h3 [% Y9 z8 H' A
                if(++t2>=ls_speed)) y3 v  S8 L4 i" L0 e
                {# q% T1 e1 g; ^7 |' Z
                        t2=0;
2 \- w4 X& ^- p( G5 B5 A                        if(++ls_t>=led_size) //注意!!( S1 d  T: R. g6 R( H- V1 o# u- O
                                {
7 T% ?& n3 W* m" U  K  Z                                        ls_t=0;
- D3 A6 d8 ^7 o/ R                                }' f0 ]6 n+ c, f
                        }, c& e8 P( g7 c
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        
; `7 m; D1 T8 d) u0 W     }  : \# r  _% J0 Z9 T; B/ m* a7 K
}8 b* \" {* x+ G' |

# c& l! p0 y* Z# N( T( C9 H& l+ v3 K# ]9 L+ ~; }' A0 |
这样在main函数调用ls_mode()灯就流起来了!!% m" U6 b: y, x% s6 s
漂亮的东西怎么没有视频:; b0 ]# h/ n) d- `1 C, s
6 O6 v4 j  l9 ]( x# n# n) |% O
P70614-085819.gif 1 }! q# l) ]! I. V. b

评分

参与人数 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 ?3 `+ ?, x( k兄弟,分享一下SPI是怎么驱动的?
$ c. e% B% ~; ]/ ]
思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:09- K$ [. b& D& q) |8 o
我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...
" h# M* N* B1 @# O: v6 e5 N
请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器7 u6 k- }" n) 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
/ b+ l8 c  b0 h7 _MCU是跑72Mhz 吗?
" n2 N5 J, E! k8 F) X7 \* ^: l+ j2 [
是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 手机版