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

STM32MP1嵌入式Linux驱动开发指南V1.7-呼吸灯实验

[复制链接]
STMCU小助手 发布时间:2022-9-28 14:22
呼吸灯实验
& x- a! }3 j6 J# T呼吸灯最早由苹果公司发明并应用于笔记本睡眠提示上,其一经展出,立刻吸引众多科技厂商争相效仿,并广泛用于各种电子产品中,尤其是智能手机。呼吸灯其实是在微处理器的控制下,由暗渐亮、然后再由亮渐暗,模仿人呼吸方式的LED灯。* {7 G4 [3 I% r: I( \

  |/ }' t3 x" a9 N7 I, s1.1 呼吸灯简介
" Y  {9 K" g; a' Y+ S0 \8 x0 M; Y0 W4 B呼吸灯采用PWM的方式,在固定的频率下,通过调整占空比的方式来控制LED灯亮度的变化。PWM(Pulse Width Modulation),即脉冲宽度调制,它利用微处理器输出的PWM信号,实现对模拟电路控制的一种非常有效的技术,广泛应用于测量、通信、功率控制等领域。4 k" C9 F4 L. l. G: r4 w, @& X
在由计数器产生的固定周期的PWM信号下,如果其占空比为0,则LED灯不亮;如果其占空比为100%,则LED灯最亮。所以将占空比从0到100%,再从100%到0不断变化,就可以实现LED灯的“呼吸”效果。
! n% C! S. p1 d9 q. u4 @PWM占空比调节示意图如下图所示:
! _6 q5 C8 {0 Z7 }7 m! ^7 ?" e
" r9 W# T6 m% }9 u" `5 F6 W/ _ 01b2bc22a1bc4e3fa0893208a743a7ff.png - k; {4 P9 |) W, r* V

% g, f' c, r9 L+ Y# s+ _图 7.5.13.1 呼吸灯PWM占空比示意图
# d) Z7 s+ K6 Q9 ^由上图可知,LED高电平的时间由长渐渐变短,再由短渐渐变长,如果LED灯是高电平点亮,则LED灯会呈现出亮度由亮到暗,再由暗到亮的过程。& m2 S) }# ]' l) a" \- }& l4 g
1.2 实验任务
/ Y( c, Q3 k7 I7 B本节实验任务是使用正点原子ZYNQ开发板(核心板)上的PL LED,实现呼吸灯的效果,即由灭渐亮,然后再由亮渐灭。, d. i2 X% ]8 x" M) S

& O4 B1 j& B) r( L1.3 硬件设计
+ f7 M, H5 g3 _5 M9 I1 m2 F发光二极管的原理图如下图所示,PL LED发光二极管位于核心板上,其阴极通过330欧姆的电阻连到地(GND),阳极与ZYNQ的IO相连,LED与地之间的电阻起到限流作用。当PL_LED输出高电平时,点亮LED灯,当PL LED输出低电平时,LED灯熄灭。) r0 B, q) h: C& M* f$ ]* a* J( }# y) o

4 E: ^3 ?: ?4 f( H7 ^ 50f9535f3c1745d59752ef57a78bdb14.png 0 {6 ?- u' i, n7 ~
9 p5 J' i) }4 W$ G. E5 R4 R
图 7.5.13.1 呼吸灯硬件原理图
' f0 g. y1 }4 j! N0 Q! ~* a! ]* `本实验中,系统时钟、按键复位以及LED端口的管脚分配如下表所示:  j, Y! ~- Y$ [" d* p6 ]) m
表 12.3.1 呼吸灯实验管脚分配
2 f; o8 ~( W0 {# M1 H) j! J: S信号名 方向 管脚 端口说明 电平标准* E# @' c" [+ J; `! {8 M/ ~& W
sys_clk input U18 系统时钟,50MHz LVCMOS33% w. i' e7 x+ {/ n8 |. W
sys_rst_n input N16 系统复位按键,低电平有效 LVCMOS33
1 x  F, y: p  D4 mled output J16 PL LED(核心板) LVCMOS33
0 A. H0 p4 z: y% G9 W0 n对应的XDC约束语句如下所示:
0 x% s: _* V4 `+ J- {6 a#IO管脚约束8 i" O4 }: F* h+ c- e3 ^* {# M: a
  1. set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]' ^; u3 L5 _( q
  2. set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]! ?& o; ]' {0 F7 m
  3. set_property -dict {PACKAGE_PIN J16 IOSTANDARD LVCMOS33} [get_ports led]
复制代码
+ f, u' d, M. ?6 `2 R
1.4 程序设计
; i; g. u. y$ V本次实验的模块端口及结构框图如下图所示。
$ \* Y. m9 [# u图 7.5.13.1 模块端口及信号连接图% X# O- T) s, u9 m- E
周期信号计数器用于产生驱动LED的脉冲信号,本次实验的周期信号频率为1Khz,其占空比由后级逻辑在每个周期之后进行递增或递减,最后再对当前计数值和占空比计数值进行比较,以输出占空比可调的脉冲信号。
, D( V( @; H, \呼吸灯代码如下:) S  [& h7 n$ L- M5 R
1 c" e5 D2 J0 t+ ^3 D, R% Z
  1. 1  module breath_led(1 a; E3 u* o8 j7 j  b7 I3 [8 p  j1 L
  2. 2      input   sys_clk   ,  //时钟信号50Mhz% L% G- W: H" c9 \
  3. 3      input   sys_rst_n ,  //复位信号1 K9 `2 Z5 G8 ?8 V
  4. 4  $ J7 L  i7 S- d% \1 }* K2 n, F
  5. 5      output  led          //LED8 n; s+ k- \% Z; S3 f. Q
  6. 6  );3 P, D( x3 A% z  k! ^! O8 e; c; P
  7. 7  2 r0 Y4 f" z/ R' S* b  j
  8. 8  //reg define
    $ `3 u1 k7 G& R
  9. 9  reg  [15:0]  period_cnt ;   //周期计数器频率:1khz 周期:1ms  计数值:1ms/20ns=50000
    2 l$ f* `1 J+ t! S' G- J
  10. 10 reg  [15:0]  duty_cycle ;   //占空比数值+ W: A# i) ~/ {3 q# {1 U1 K! i7 G( y
  11. 11 reg          inc_dec_flag ; //0 递增  1 递减# h4 [8 I9 |1 e, s! r4 s
  12. 12
    ) m( i8 Q) Y/ l1 G, ~
  13. 13 //*****************************************************( _9 b* ~3 [/ L/ F8 G2 _( N
  14. 14 //**                  main code
    0 W  k% j3 q2 h( v
  15. 15 //*****************************************************
    . x9 G* l! W5 B# O: y: y
  16. 16
    & W7 E2 A+ T( V3 A' V; I
  17. 17 //根据占空比和计数值之间的大小关系来输出LED9 ~3 \# U. b8 D! d6 t, h3 R
  18. 18 assign   led = (period_cnt >= duty_cycle) ?  1'b1  :  1'b0;
      Y& q8 C+ _% ~* W
  19. 19 8 ]; U+ }- H" I4 F; w' o3 S2 W
  20. 20 //周期计数器
    5 G" s7 p' {3 P) N; R& E! z
  21. 21 always @(posedge sys_clk or negedge sys_rst_n) begin, O3 b$ t5 n# d
  22. 22     if(!sys_rst_n)( L0 I( i/ P& C6 x& j* Y4 v  A1 U& M
  23. 23         period_cnt <= 16'd0;1 K7 ?$ B, t8 L1 D
  24. 24     else if(period_cnt == 16'd50000)
      D, Y9 D; L: @; f  ]' ]
  25. 25         period_cnt <= 16'd0;
    & k* y7 Q- D3 O) u. b
  26. 26     else8 a' ]2 C; P9 Z1 c
  27. 27         period_cnt <= period_cnt + 1'b1;
    % V3 `2 [5 y" R1 V7 J* ?
  28. 28 end; ]+ F1 B+ ^( V+ ^
  29. 29
    - b2 l$ [, t1 M$ r+ Y, T7 ?* V/ \
  30. 30 //在周期计数器的节拍下递增或递减占空比
      n1 Q& v+ `$ X, g# Q& G/ ?
  31. 31 always @(posedge sys_clk or negedge sys_rst_n) begin
    ! d& }9 D4 _) W4 [# r) h* @
  32. 32     if(!sys_rst_n) begin
    6 k  R1 I. D2 u
  33. 33         duty_cycle   <= 16'd0;" g3 }; V8 c1 g
  34. 34         inc_dec_flag <= 1'b0;6 ~8 `2 ?) \5 g. h0 l" K$ B7 m
  35. 35     end3 d; h/ E  h+ d
  36. 36     else begin
    / {6 a' [" M) k& o; H2 @
  37. 37         if(period_cnt == 16'd50000) begin    //计满1ms
    " j! B0 z7 N" D8 K, _" A: v
  38. 38             if(inc_dec_flag == 1'b0) begin   //占空比递增状态: ?3 O' ~- m! R) p# I
  39. 39                 if(duty_cycle == 16'd50000)  //如果占空比已递增至最大
    ( p6 H' q( l0 N. w
  40. 40                     inc_dec_flag <= 1'b1;    //则占空比开始递减
    8 J$ d' L% `! f' P5 L
  41. 41                 else                         //否则占空比以25为单位递增; \/ Q& \' i" m$ n0 F3 U% S6 x
  42. 42                     duty_cycle <= duty_cycle + 16'd25;
    6 d2 ^5 X9 D0 n) O
  43. 43             end
    + r; N% f) ?; r# B' f
  44. 44             else begin                       //占空比递减状态0 n- h  S# [1 `6 {( ^( ]
  45. 45                 if(duty_cycle == 16'd0)      //如果占空比已递减至0
    ' ^1 j$ [+ g) }* |+ p& W
  46. 46                     inc_dec_flag <= 1'b0;    //则占空比开始递增
    6 l/ }- s' y" y$ @; }0 ?
  47. 47                 else                         //否则占空比以25为单位递减  [: s; G7 G1 }& q: B+ W) V
  48. 48                     duty_cycle <= duty_cycle - 16'd25;+ C& q9 r2 Q/ I/ W+ z) S5 |
  49. 49             end( ^3 M" l" q& x; j' B3 C
  50. 50         end
    ! `$ l' D+ N3 [5 W0 V! I
  51. 51     end! N" g8 {' Y6 V. l2 T
  52. 52 end
    4 ~) s( [7 b9 }
  53. 53   j& b6 `$ K, M7 R
  54. 54 endmodule
复制代码
* b, W& v  w; |
第21-28行是1KHz周期信号的计数器,用于产生1KHz的LED驱动信号。第31-52行的always块为占空比设定模块,每次计数完了一个周期,就根据递增/递减标志来对占空比计数值(duty_cycle)进行递增/递减25个计数值,这个递增或者递减的数值大小可以用来控制呼吸灯的呼吸频率。( t0 R- z+ r' \2 T
如果占空比计数值(duty_cycle)已经递增到了最大,则呼吸灯已经处于最亮的状态,接下来开始递减;反之,如果占空比计数至已经递减到了最小,即0,则呼吸灯处于熄灭的状态,接下来开始递增;如此循环往复,最终实现了流水灯的效果。
. w! j' b% ^4 b; X4 e在代码的第18行通过组合逻辑把当前的周期计数值和占空比计数值进行比较,来判断LED的输出电平。在一个周期内,如果当前的周期计数值小于等于占空比计数值,则LED输出高电平,即点亮;如果当前的周期计数值大于占空比计数值,则LED输出低电平,即熄灭。5 |& ^4 z6 ?( P! L/ ?) {

! ?. O6 Q& j* a1.5 下载验证
1 I+ d& _9 {2 Q; b5 y8 N编译工程并生成比特流.bit文件。将下载器一端连接电脑,另一端与开发板上的JTAG下载口连接,连接电源线,并打开开发板的电源开关。
* R; R4 s' t" a) h" b点击Vivado左侧“Flow Navigator”窗口最下面的“Open Hardware Manager”,此时Vivado软件识别到下载器,点击“Hardware”窗口中“Progam Device”下载程序,在弹出的界面中选择“Program”下载程序。4 a4 k5 n7 t% d% X+ J7 j
程序下载完成后,可以看到核心板的PL LED灯由暗慢慢变亮,再由亮慢慢变暗,即呈现出“呼吸”的效果,如下图所示:
3 g. F6 }0 z: |  j" n在这里插入图片描述
( K* F$ V% j, a7 h8 |) S
4 V: `2 J8 k; x' p. t( k d77e4d2d055c45ecb361a6765cbf9c77.png
0 w4 A% H4 b8 T. A, [( o) R6 R6 J" S0 u, z/ I" p) b; C
图 7.5.13.1 开发板实验现象
+ D: j! p3 j# z; Z0 o————————————————: X) h) _9 h  J$ J* _
版权声明:正点原子! M1 K% f% v8 m+ m, Q
' c8 w. n6 W/ I) E' T6 |
, K2 P# b5 s; n# y
赞 收藏 评论0 发布时间:2022-9-28 14:22

举报

0个回答

所属标签

相似技术帖

官网相关资源

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