#import "../template.typ": *

#show: project.with(
  title: "实验报告 1",
  authors: (
    "absolutex",
  )
)

= 跑马灯实验（寄存器版本）

== 实验目的

通过代码控制 ALIENTEK 阿波罗 STM32 开发板上的两个 LED 灯 DS0 和 DS1 交替闪烁，实现类似跑马灯的效果。

修改代码，初步掌握 STM32F429 基本 IO 口的使用。

== 代码描述

#include_code_file("../代码/1.c","main.c", "c")

用到了两个 for 循环，外层循环控制占空比，内层循环起到延时作用，使人眼能够观测到占空比变化。

变量 d 用来控制闪烁周期，sist 控制每个亮度持续的周期数。

== 实验结果

观察到 DS1 由暗到亮，再由亮到暗的循环闪烁。

== 心得体会

想要达到比较好的观察效果需要细致地调整参数。LED 的占空比在 0.3 以下时可以明显看出亮度变化，而在 0.4 以上时，LED 较亮，导致亮度变化不明显。

= 跑马灯实验（HAL 库版本）

== 实验目的

通过代码控制 ALIENTEK 阿波罗 STM32 开发板上的两个 LED 灯 DS0 和 DS1 交替闪烁，实现类似跑马灯的效果。

使用 HAL 库版本重写上述跑马灯程序，同样使 DS1 发生由暗到亮，再由亮到暗的循环闪烁。
== 代码描述

#include_code_file("../代码/2.c","main.c", "c")

== 实验结果

观察到了与实验 1 相同的跑马灯闪烁。

== 心得体会

了解了HAL库的使用方法，以及在STM32开发板上通过HAL库控制LED灯的方法。学习了如何使用GPIO端口和时钟，并逐步构建复杂的应用程序。

= 按键输入实验

== 实验目的

利用板载的 4 个按键，来控制板载的两个 LED 的亮灭，熟悉 STM32F4 的 IO 口作为输入口的使用方法。

== 代码描述

#include_code_file("../代码/3.c","main.c", "c")

将调节亮度的占空比调节过程抽象成 `space_ratio()` 函数，通过不同按键，控制灯的亮度。代码中 `f = f == x ? 0 : x;` 的设计，目的是附加一个功能，在第二次按下按钮时熄灭 LED。

== 实验结果

通过不同按键，实现 LED 的亮度调节。按动 `WKUP` 键后关闭 LED，按动 `KEY2` 后调整亮度为低，而按动 `KEY1` 后亮度调整为较高，按动 `KEY0` 后亮度调整为高。

== 心得体会

由于占空比在 0.3 以上时亮度变化不明显，因此设置占空比为 0, 0.05, 0.2, 0.8，可以很好地观察到 LED 的亮度变化。

经过测试，使用 `KEY_Scan(0)` 只能监测到按键按下时的一次信号发送。如果需要监测按键持续时间或 release 时机，可能需要修改库函数代码。

= 外部中断实验

== 实验目的

学习如何使用 STM32F429 的外部输入中断，了解中断优先级的设置方法与表现，学习将中断线映射为 GPIO 的方法，在中断服务函数中处理逻辑。

== 代码描述

#include_code_file("../代码/4.c","exti.c 片段", "c")

通过改进的 `space_ratio()` 函数实现了双 LED 灯的亮度调节，通过按键按照优先级进入中断程序，执行对应的服务。

== 实验结果

在本次的实验中，使用外部中断来实现控制灯的暗灭。利用占空比的原理实现了让灯从暗至亮再从亮至暗的过程。

== 心得体会

由于不熟悉串口调试工具的使用，在串口调试时遇到了麻烦。需要接对串口线，选中正确的波特率，才可以看到正常输出。选择了错误的波特率可能导致接收的信息乱码。

一开始发现灯频闪的很快，而不是缓慢变亮，因为频率慢，没有让灯的图像在人眼中滞留，后增加了频率改善了这一问题。但由于未知原因没有实现中断优先级，即不能用其他优先级高的按钮中断当前灯的状态。
