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

再发STM32驱动WS2811灯带  

[复制链接]
anny 发布时间:2017-6-14 09:02
本帖最后由 anny 于 2017-6-14 13:07 编辑 5 e+ {, I; |" H

5 i& X6 W4 o& B  h其实社区有朋友发帖子用STM32驱动WS2811灯带了,他们用的是硬件SPI,其实也可以用PWM。
, b& ^  ~3 E3 h3 ~& F- p: {: r今天我的驱动方式不是用单片机外设来驱动,而是用最古老的延时方式,这种方式不适合地方你们自己想了,优点是灵活,想在哪个IO口驱动随便换。  E4 V* c' I4 ~% E3 H( @7 r2 b
还有,我这个驱动方式可以兼容UCS1903、SM16703等等这些灯带。  a3 I9 b# K. S+ m- e# c- P2 r
驱动芯片:STM32F103RBT6 频率:72M
, D6 z8 w9 m% V7 Q3 V- R  Y说明:为了保护单片机我用了块74HC245来隔离,也算是做了电压转换,从3.3V变成了5V
" ~& e! n$ ^, ?( r" \# c7 }好吧,上程序:6 @; ?' [! y$ J2 j
void WS2811_SendByte(u8 dat)//发送1BIT的数据7 Z4 P$ \3 t! |
{
* s( J9 P$ L6 g, [. @5 N6 p        u8 i;4 f3 S. b1 Q! ^' _9 W$ L6 N
        for(i=0;i<8;i++)) F1 a/ W4 M  a& I1 \
        {* A( t% T5 d# m/ p
                if(dat & 0x80) //发送数据1
5 s  M6 P8 T0 N! d" {4 C: Y$ g8 h1 s                {
0 W+ y  a( ]+ ~4 b) E             Light_SDA=1;, ^( Z  Z; }$ w/ w* G4 }
             delay_us(1);
5 S: B- [( m/ y! q            Light_SDA=0;
: T% q( q3 c/ G- n( q: B' B+ K" r            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
9 p. D$ a! y! R4 Y' j4 ]9 L/ O( m                }  J$ u$ u4 A4 d" R% S! v( k! C
                else                        //发送数据0* {& |# P. r2 t$ d5 c1 c  Z5 A6 W
                {
/ i6 t2 K# G0 `, n            Light_SDA=1;//0
* E9 C, r) d2 B& _8 i* ^            __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
: Y. o! q" U% k& F" x, P6 r! e             Light_SDA=0;
% U" o( ]' |8 f1 F+ v8 Q, c            delay_us(1);
6 j: o/ s- d' N4 A: r                }
/ I* F$ q, k9 I% [4 [5 ?                dat <<= 1;
+ `8 k* }+ `( I( l0 d        }
& T2 [; i$ N3 T. ?( E+ L, `. b}  u4 k0 }  z; e, l
1 b  V- ^, d/ a) \, H, S) Z
" K. f) c+ P  J4 `* L
void Reset(void)                 7 ~# b  g9 W, y) n& Q) d
{        4 _* F  F! o9 k; d. @
    Light_SDA=0;
1 R% Z+ L$ C  v3 D, l    delay_ms(30);  Q+ {* Q/ Y2 b5 A/ O* I" F
}  b# a2 p6 @3 f- Z9 {& E! M

1 D) w& g' f1 H基本的发数据程序就这样了8 Z$ S+ v4 H- M7 B+ R
void send_data(u8 R,u8 G,u8 B)
5 K) O3 \' o% s0 K% _" t" _! w{2 v8 Y3 ]/ Z3 s+ H
                u8 i;7 X. W! P7 S8 G; T% D* ]
                for(i=0;i<led_size;i++)
" Z) k3 R7 S' `: ^# i) p                {
! b! D& g0 P0 I7 B- n3 i" Y                        WS2811_SendByte(G);
4 I8 I" \& O1 _* a                        WS2811_SendByte(R);
+ M- u8 x3 |! r8 r; g                        WS2811_SendByte(B);
0 S$ @5 @8 X* e* H                }* R9 ^5 Q; A! g4 D* ?" ~  }0 a, p
                   Reset();
; a, p! |; O0 ^) m1 u}
9 j7 ?1 B. [8 `# U# ~
9 ?: N: m( R5 K3 L$ b$ m. [' Rvoid ls_mode(void)3 k+ I& z% ^" Y
{
; G% b9 R- C8 w6 f2 D        u8 i=0,ys=0,yz=0;
( g* Z" v' D7 g0 z2 Q        for(i=led_size;i>0;i--)2 A! _1 d2 {0 W- y
        {
# u2 S5 o& B0 Q+ C; [/ S% Z9 t                if(i<=ls_t)8 G! W! Z8 O# \/ J" Y6 Y8 u
                {
% }! x9 W, x; f                        if(ys<ls_t)3 M) {$ I9 K5 T4 t
                        {
7 h: I1 B! C: e% f                          ys++;
# w1 G  L' ~! }) [6 u$ o2 J                        }
) v, d+ G! `5 \' Z                        else
3 i% O2 O0 g2 f2 H; y" {/ n. E                                ys=0;. U5 p* n7 y2 [) ?) M9 C
                        WS2811_SendByte(LED_data[45-(ys%45)][1]);
, d- v& A8 j3 v# y/ G/ N                        WS2811_SendByte(LED_data[45-(ys%45)][0]);
. p+ l. ]0 k# e( v4 V                        WS2811_SendByte(LED_data[45-(ys%45)][2]);$ T2 ]0 `1 z6 P
                }
8 f# B3 ]1 e+ N% r3 N9 U3 n                else
& m' M  e; R5 R! V; }  X                {1 S" q. y; }+ H, g" J8 I( k
                        if(yz>0)+ S, X0 B4 e4 h7 z- B$ `( C: ~
                        {
: O9 ^* ~$ R: @# M                          yz--;
3 @$ [& Y( s! m6 u  e0 z                        }
! b& g9 P$ P4 \" Q                        else
, u7 N$ A4 \5 R: f1 p8 i' I                                yz=led_size-ls_t;; N" j0 J9 ]% R+ W8 I0 m
                        WS2811_SendByte(LED_data[yz%45][1]);: g* {. j' {3 T+ `3 ~' a- H* i
                        WS2811_SendByte(LED_data[yz%45][0]);
( h9 A; Y! A. L                        WS2811_SendByte(LED_data[yz%45][2]);
- O3 X8 O- @; e: {0 ^- _5 Y                }+ ?8 K, r$ R. I/ x/ x# X  Y6 R  D
        }' `; x: [* W  W7 d: @7 J' i, @: g1 l+ b
          Reset();% |7 K, [5 i3 z2 f1 E  K% [
}4 D9 b7 ~& m- H; N% b' i" j
0 S3 p# w8 t! h1 f8 P9 e
0 q1 O% m" O# I4 M5 B6 k5 T
这是应用程序,其实就是PLAY一个数组,我刚刚开始的方法是完全用FOR来实现,发现哪样做每种流水方式都要重新写,太痛苦了。PLAY数组里面的内容相对会方便很多,当然也可以在函数名上加指针用来实现PLAY哪个数组,这个就自行改善吧!
+ P3 ~+ P$ T  I+ ~9 ^( D4 Econst u8 LED_data[45][3]={  o" M% I4 d/ }: @2 E- s% S) R0 ^
        {55,0,255},//G,R,B+ f8 |! s' Q8 G
        {100,0,200},
' W. r& S0 c2 S# G& C7 ^        {155,0,155},
' P& v& x" i+ }- T        {200,0,100},3 y1 K- `) f6 m7 n( ]' Z: D4 Z
        {255,0,55},//5
* m1 R9 `0 T# H/ |1 N        {255,0,0},1 }: }# F4 E, Q/ B' u, P; T. I
        {255,0,0},
3 p- |( R8 D: o* L/ Y        {255,0,0},
3 ^$ R2 C5 I& T. W' Y& J        {255,0,0},: \3 F' _/ d1 @& {, A
        {255,0,0},
3 _/ k4 [" o4 f% A. i3 r        {255,0,0},0 I* q; R+ t& w" R+ T% q
        {255,0,0}," @& c1 C0 g" s' H$ W0 s" P
        {255,0,0},
4 ?$ j6 W8 M8 z9 v) Z2 e& Z        {255,0,0},
& t) \, [2 x! `1 m  `6 ~        {255,0,0},//15
9 O/ Q2 f# A+ ?( V& U6 F5 g4 M! u        {255,55,0},
& j4 o* @4 }0 ~8 X. L        {200,100,0},
; M+ m- Z! A$ K! F* D        {155,155,0},# D8 `- E7 O- i, w4 n
        {100,200,0},
& P& Z; l1 b  x2 \/ i8 N        {55,255,0},//209 A; ]$ k+ q% O8 V; u
        {0,255,0},//G,R,B
% b1 d6 Y. G/ N! t" G  ^: L; w        {0,255,0},0 }6 Q! O- N. k) S5 y* ]2 p
        {0,255,0},9 e( [, R1 v) r" U  A2 l- Q
        {0,255,0},0 `, }% l  ^0 e
        {0,255,0},& F2 d! Q' ?! c5 i3 H. v! m
        {0,255,0},  i+ w$ o' B6 s) X
        {0,255,0},
2 {3 w  j) u- B6 h        {0,255,0},
% D3 k. h2 {0 x# |" k3 J- S5 p% Q        {0,255,0},
. G$ _, j: X0 c3 g        {0,255,0},//30
+ f; f% E7 z  Y0 S. Z+ ^# \        {0,255,55},//G,R,B
9 d5 ^1 S2 t' b, @        {0,200,100},
1 F  y/ u) l/ q5 J0 N0 Q& [        {0,155,155},' I. Q' B, O( b& r) R' ~5 H6 U
        {0,100,200},
9 f. J8 l3 I% E) y# c. W) m        {0,55,255},
. y  i9 f$ l  [( d* R$ U        {0,0,255},//35
8 |$ _& _" _0 l& L1 Y        {0,0,255},
: W% f9 v: l% f6 \+ o. i        {0,0,255},8 ~; {1 }4 H) I. j, l) d7 y* ~+ L
        {0,0,255},( `# a, V" A: @; A
        {0,0,255},
$ X1 Z, D0 L  o( r2 c. ~% ?        {0,0,255},
( j; C+ D2 K/ A7 A7 @) k        {0,0,255},8 d6 ?) t( B1 W3 f/ }  x" w3 F( R# f
        {0,0,255},
3 x1 `8 I  D* r! w        {0,0,255},# s  b! t0 i' A! L# @/ |1 `
        {0,0,255}//45/ i* P& o& e$ K; C
                           };
: h. v7 o$ z2 y% s) F& f; D8 L' ~8 D: c
3 u/ b+ s! g$ T: W' M2 U
这是要PLAY的数组,这次实现的是流水灯,在颜色链接的地方加上了渐变,这样更好看。当然也可以换上其它的方式9 N5 k7 a0 x5 T) f- ]( n1 `
单单上面的程序流水灯是流不起来的,在定时中断用变量++来驱动:! T9 a; u6 q9 y9 P
void TIM2_IRQHandler(void)  // 1s enter
* E. A0 U4 w  ?+ u: ?2 v{
1 l; m/ [- I9 {$ F" h     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)4 C. \7 ~) [0 `8 k
     {- O* `8 o) G% {) d. e. G
//                        ls_mode12();6 u( v9 H0 x5 X% a( W
                if(++t2>=ls_speed)9 ?6 N8 l( U) g9 S, r8 N& L
                {. s+ ?+ K& p6 \- c, K
                        t2=0;
' q# S$ l: Q' b6 y                        if(++ls_t>=led_size) //注意!!6 }2 C# u; A% {5 O+ w
                                {
, @2 u* `( H8 {5 M: |                                        ls_t=0;
( m4 {& d" Q* o& x/ U3 H                                }- x: ~& X) n0 y2 _! B
                        }+ R* ^' r% u. j9 g/ ^9 _. Q" l
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );        3 h! L5 I3 F# a. d1 x* ]  F
     }  
; w' e* G) s2 V" I  p! y; G}0 W* Q$ o" `& e$ O0 `2 S
5 f& n' ~! m2 j$ N, \3 ^- _

# a6 A. @0 Z4 Z+ G2 }) E: \: D3 N这样在main函数调用ls_mode()灯就流起来了!!  Q. W: ]9 w3 h
漂亮的东西怎么没有视频:
1 `! W0 R4 S$ q' n/ Y4 ~6 {: }0 n$ x* }
P70614-085819.gif   {% X( r4 D' q$ e' t% D

评分

参与人数 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
& J" b; S5 o) V0 @, r3 `兄弟,分享一下SPI是怎么驱动的?
( w2 u5 o% \" c: s& a* R
思路就是用MOSI脚驱动,然后直接发送数据,用逻辑分析仪看高低电平的时间,然后做调整,比如发SPI发送0xE0,其实就是发送了3个1,5个0,这样低电平的时间就肯定长,然后自己看着来调整就行了。
翔2018 回答时间:2021-5-20 14:03:56
dream2010 发表于 2017-11-3 23:09
- N# e- L( [# |. Z: L. a: R# K我也做了一批这个控制器,插TF卡,将要显示的数据保存成文件放在卡里,STM32读取,DMA传送到 S ...

3 Y0 \- A* z7 k# w- U请问您这边有思路吗,我也是想只使用定时器的PWM实现,补寄有的单片机没有DMA控制器
  M# G9 G* w* z$ h# C5 r
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
5 E3 b# L7 _, Y6 P& Z( ^9 a! @MCU是跑72Mhz 吗?

. `, i  U* h( K5 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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版