1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码 手册 视频下载地址:http://www.openedv.com/thread-318813-1-1.html 4)正点原子官方B站:https://space.bilibili.com/394620890 5)正点原子STM32MP157技术交流群:691905614 
第十二章 呼吸灯实验
呼吸灯最早由苹果发明并应用于笔记本睡眠提示。一旦展出,它立即吸引了许多科技制造商效仿,并广泛应用于各种电子产品,特别是智能手机。呼吸灯实际上是在微处理器的控制下,从暗到暗,然后从亮到暗,模仿人们的呼吸方式LED灯。 本章分为以下章节: 1.1 呼吸灯简介 1.2 实验任务 1.3 硬件设计 1.4 程序设计 1.5 下载验证 ? 1.1 呼吸灯简介 呼吸灯采用PWM在固定频率下,通过调整空比来控制LED灯亮度的变化。PWM(Pulse Width Modulation),即脉冲宽度调制,由微处理器输出PWM信号是一种非常有效的模拟电路控制技术,广泛应用于测量、通信、功率控制等领域。 固定周期由计数器生成PWM在信号下,如果占空比为0,LED灯不亮;如果占空间的100%,LED灯最亮。因此,从0到100%的空间比例,再从100%到0不断变化,就可以实现LED灯的呼吸效果。 PWM空比调节示意图如下图所示:
图 7.5.13.1 呼吸灯PWM占空比示意图 从上图可以看出,LED如果高电平时间由长逐渐变短,再由短逐渐变长,LED灯是高电平点亮的,然后LED灯会呈现出亮度由亮到暗,再由暗到亮的过程。 1.2 实验任务 本节的实验任务是使用正点原子ZYNQ开发板(核心板)上的PL LED,实现呼吸灯的效果,即由灭逐渐亮,再由亮逐渐灭。 1.3 硬件设计 发光二极管的原理图如下图所示,PL LED发光二极管位于核心板上,阴极通过330欧姆的电阻连接到地面(GND),阳极与ZYNQ的IO相连,LED当地面之间的电阻限流时。PL_LED平时输出高电,点亮LED灯,当PL LED输出低电平时,LED灯熄灭。
图 7.5.13.1 呼吸灯硬件原理图 在本实验中,系统时钟、按键复位和LED如下表所示: 表 12.3.1 呼吸灯实验管脚分配 信号名 方向 管脚 端口说明 电平标准 sys_clk input U18 系统时钟,50MHz LVCMOS33 sys_rst_n input N16 系统复位按钮,低电平有效 LVCMOS33 led output J16 PL LED(核心板) LVCMOS33 对应的XDC约束语句如下所示: #IO管脚约束
set_property -dict {
PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk] set_property -dict {
PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n] set_property -dict {
PACKAGE_PIN J16 IOSTANDARD LVCMOS33} [get_ports led] 1.4 程序设计 模块端口和结构框图如下图所示。 图 7.5.13.1 模块端口和信号连接图 周期信号计数器用于生成驱动器LED本实验的脉冲信号周期信号频率为1Khz,其空比由后逻辑在每个周期后增减,最后比较当前计数值和空比计数值,输出空比可调脉冲信号。 呼吸灯代码如下:
1 module breath_led( 2 input sys_clk , //时钟信号50Mhz 3 input sys_rst_n , ///复位信号 4 5 output led //LED 6 ); 7 8 //reg define 9 reg [15:0] period_cnt ; //周期计数器频率:1khz 周期:1ms 计数值:1ms/20ns=50000 10 reg [15:0] duty_cycle ; //占空比值 11 reg inc_dec_flag ; //0 递增 1 递减 12 13 //*****************************************************
14
//** main code
15
//*****************************************************
16
17
//根据占空比和计数值之间的大小关系来输出LED
18 assign led
=
(period_cnt
>= duty_cycle
)
?
1
'b1 : 1'b0
;
19
20
//周期计数器
21 always @
(posedge sys_clk or negedge sys_rst_n
) begin
22
if
(
!sys_rst_n
)
23 period_cnt
<=
16'd0
;
24
else
if
(period_cnt
==
16'd50000
)
25 period_cnt
<=
16'd0
;
26
else
27 period_cnt
<= period_cnt
+
1'b1
;
28 end
29
30
//在周期计数器的节拍下递增或递减占空比
31 always @
(posedge sys_clk or negedge sys_rst_n
) begin
32
if
(
!sys_rst_n
) begin
33 duty_cycle
<=
16'd0
;
34 inc_dec_flag
<=
1'b0
;
35 end
36
else begin
37
if
(period_cnt
==
16'd50000
) begin
//计满1ms
38
if
(inc_dec_flag
==
1'b0
) begin
//占空比递增状态
39
if
(duty_cycle
==
16'd50000
)
//如果占空比已递增至最大
40 inc_dec_flag
<=
1'b1
;
//则占空比开始递减
41
else
//否则占空比以25为单位递增
42 duty_cycle
<= duty_cycle
+
16'd25
;
43 end
44
else begin
//占空比递减状态
45
if
(duty_cycle
==
16'd0
)
//如果占空比已递减至0
46 inc_dec_flag
<=
1'b0
;
//则占空比开始递增
47
else
//否则占空比以25为单位递减
48 duty_cycle
<= duty_cycle
-
16'd25
;
49 end
50 end
51 end
52 end
53
54 endmodule
第21-28行是1KHz周期信号的计数器,用于产生1KHz的LED驱动信号。第31-52行的always块为占空比设定模块,每次计数完了一个周期,就根据递增/递减标志来对占空比计数值(duty_cycle)进行递增/递减25个计数值,这个递增或者递减的数值大小可以用来控制呼吸灯的呼吸频率。 如果占空比计数值(duty_cycle)已经递增到了最大,则呼吸灯已经处于最亮的状态,接下来开始递减;反之,如果占空比计数至已经递减到了最小,即0,则呼吸灯处于熄灭的状态,接下来开始递增;如此循环往复,最终实现了流水灯的效果。 在代码的第18行通过组合逻辑把当前的周期计数值和占空比计数值进行比较,来判断LED的输出电平。在一个周期内,如果当前的周期计数值小于等于占空比计数值,则LED输出高电平,即点亮;如果当前的周期计数值大于占空比计数值,则LED输出低电平,即熄灭。 1.5 下载验证 编译工程并生成比特流.bit文件。将下载器一端连接电脑,另一端与开发板上的JTAG下载口连接,连接电源线,并打开开发板的电源开关。 点击Vivado左侧“Flow Navigator”窗口最下面的“Open Hardware Manager”,此时Vivado软件识别到下载器,点击“Hardware”窗口中“Progam Device”下载程序,在弹出的界面中选择“Program”下载程序。 程序下载完成后,可以看到核心板的PL LED灯由暗慢慢变亮,再由亮慢慢变暗,即呈现出“呼吸”的效果,如下图所示: 在这里插入图片描述
图 7.5.13.1 开发板实验现象