拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

实验2_3实验报告

实验2_3实验报告 STM32F103C8T6 流水灯实验二、三实验背景与接线实验一我用寄存器方式做了四灯流水其中一只是板载 PC13。实验二要求用同一个端口控制外接灯所以我把三只灯改接到 GPIOA 的 PA8、PA9、PA10不再用板载灯。实验三沿用这组接线只增加 PA0 接地模拟按键做完实验二后换程序就能接着做实验三。对象引脚与电平在本实验中的作用外接 LED 1PA8高电平亮流水第 1 步外接 LED 2PA9高电平亮流水第 2 步外接 LED 3PA10高电平亮流水第 3 步按键替代接法PA0 用杜邦线短接 GND 一下实验三内部上拉、下降沿触发实验二用标准外设库写流水灯建立工程与加入库文件我把标准外设库版放在实验2_SPL流水灯没有覆盖实验一的寄存器工程。目录如下实验2_SPL流水灯/ ├─ User/main.c ├─ Libraries/CMSIS/Core/Include/... ├─ Libraries/CMSIS/Device/Include/stm32f10x.h ├─ Libraries/STM32F10x_StdPeriph_Driver/inc/ │ ├─ stm32f10x_gpio.h │ └─ stm32f10x_rcc.h ├─ Libraries/STM32F10x_StdPeriph_Driver/src/ │ ├─ stm32f10x_gpio.c │ └─ stm32f10x_rcc.c ├─ startup/startup_stm32f10x_md.s ├─ linker/STM32F103C8T6_FLASH.ld ├─ 实验2_SPL流水灯.uvprojx └─ Makefile、build.ps1建 Keil 工程时我选 STM32F103C8T6中容量 STM32F10xTarget 时钟填 8 MHzFlash 64 KB、RAM 20 KB。从电脑上安装的 ST STM32F10x 标准外设库中取出 GPIO 和 RCC 的.c、.h再加入 CMSIS 核心头文件、stm32f10x.h和中容量启动文件。这次只用到 GPIO、RCC我就没有把整个库的.c全部加进编译组。Keil 分组中User 放main.cDriver 放stm32f10x_gpio.c、stm32f10x_rcc.cStartup 放startup_stm32f10x_md.s。在Options for Target → C/C里设置宏STM32F10X_MD,USE_STDPERIPH_DRIVERInclude Paths 设置为User、Libraries/CMSIS/Core/Include、Libraries/CMSIS/Device/Include和Libraries/STM32F10x_StdPeriph_Driver/inc。Output 勾选生成 HEX。工程已保存这些设置打开.uvprojx后可以直接 Rebuild。若要上板在 Debug/Utilities 中选择 CMSIS-DAP 调试器和相应 Flash Download 算法观察软件波形时则在 Debug 页选 Use Simulator不需要插 DAPLink。SPL 版本按本机 STM32F10x Device Pack 2.3.0 中的标准外设库 3.5.0 文件组织。工程还附有 GNU Arm 工具链的Makefile和build.ps1以下延时估算针对 Keil 工程。程序流程复位后使用内部 HSI 8 MHz。程序打开 GPIOA 的 APB2 时钟把 PA8、PA9、PA10 配成 2 MHz 推挽输出。三只外接灯都是高电平点亮。主循环每次先关三灯再点亮数组中的下一只灯记录辅助状态最后执行软件循环延时。staticconstled_tg_leds[]{{GPIOA,GPIO_Pin_8,0U},{GPIOA,GPIO_Pin_9,0U},{GPIOA,GPIO_Pin_10,0U}};for(;;){for(index0UL;indexLED_COUNT;index){all_leds_off();led_write(g_leds[index],1U);logic_trace_update(index);delay_loop_approximately_1s();}}完整注释代码在实验2_SPL流水灯/User/main.c。通过GPIO_WriteBit()改变单个 GPIO 的输出位三只灯在同一端口初始化时一次配置 PA8、PA9、PA10。软件延时到底有多长实验二保留题目要求的软件循环计数上限为888889。循环每轮包含计数、NOP、递增、比较和回跳。按每轮约 810 个 CPU 周期粗略估算8 MHz 的 HSI 每个周期为 0.125 μs因此单步延时 ≈ 888889 × (810) / 8,000,000 s ≈ 0.891.11 sGPIO 函数调用和换灯也需要时间因此 0.891.11 s 只是粗算范围。编译器、优化设置或时钟变化都会改变延时。下面再用 Keil 的仿真时间轴核对。对于三灯流水某一灯亮大约一个节拍、灭大约两个节拍同一灯再次亮起约隔三个节拍即估算 2.673.33 s。这里“换灯间隔约 1 s”和“同一 LED 的闪烁周期约 3 s”不是一个量。Keil Logic Analyzer 的观察方法与时序判断我先在 Keil 中 Rebuild再到Options for Target → Debug选Use Simulator按 CtrlF5 进入调试从View → Analysis Windows打开 Logic Analyzer。开始尝试把PORTA/PORTA.8加入波形窗口但这台电脑上的仿真器不识别它们直接运行又在 RCC 地址0x40021018报访问错误。后来我在 Command 窗口输入MAP 0x40010000, 0x4002FFFF READ WRITE让仿真器接受这段外设地址并把程序里同步记录灯状态的g_logic_pa8、g_logic_pa9、g_logic_pa10加进 Logic Analyzer显示类型选 Bit再按 F5 运行。看完波形后我已把 Debug 设置切回 CMSIS-DAP便于继续用 DAPLink 下载。这三个变量由程序在每次切换 LED 后更新。它们能用于核对程序的输出顺序和软件延时但不是 PA8、PA9、PA10 的物理电平下面的读数只称为“软件仿真”不称为示波器实测。记录到的状态依次为100 → 010 → 001 → 100顺序为 PA8、PA9、PA10。每一路高电平约一个节拍低电平约两个节拍。Logic Analyzer 导出的原始数据保存在assets/实验2_Keil仿真数据.csv。前几次上升沿分别在 PA8 的 0.000217 s、PA9 的 0.889127 s、PA10 的 1.778038 s。对全部 90 次换灯取相邻上升沿的平均值约为 0.888910 sPA8 连续两次上升沿相差约 2.666730 s。波形的轮流次序正确单灯周期约为换灯间隔的三倍。观察项目粗略估算Keil 软件仿真读数相邻两灯换灯间隔0.891.11 s外加少量切换开销平均 0.888910 sPA8 高电平持续约一拍首次约 0.888910 sPA8 两次点亮的周期约 2.673.33 s首个周期 2.666730 s实验二检查结果我分别用 GNU Arm 工具链和 Keil Arm Compiler 5 编译过工程。Keil 日志是 0 Error、0 WarningAXF 和 HEX 都已生成。从软件仿真数据算出的换灯间隔约 0.889 s这不能代替示波器对真实引脚的测量。实验三HAL 按键中断控制暂停、继续工程与初始化实验3_HAL按键中断流水灯单独保存 HAL 版工程带Core/Src/main.c、Core/Src/stm32f1xx_it.c、Core/Inc/stm32f1xx_hal_conf.h、CMSIS 与 STM32F1 HAL Driver、启动文件、Keil 工程以及 GCC 构建脚本。HAL 驱动来自 ST 官方 STM32CubeF1 源码编译宏为STM32F103xB,USE_HAL_DRIVER只编进用到的 HAL、GPIO、RCC、Flash、PWR、Cortex 相关.c。时钟仍使用 HSI 8 MHzHAL_Init()设置 1 ms SysTick 节拍。三只 LED 引脚和实验二相同PA0 配成内部上拉输入接按键到 GND设为下降沿 EXTI0NVIC 开启EXTI0_IRQn。没有独立按键时用杜邦线把 PA0 与 GND 瞬间短接一下即可模拟按下移开导线后再次短接可切换回运行状态。按下后EXTI0_IRQHandler()调用HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0)HAL 再调用回调。voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){if(GPIO_PinGPIO_PIN_0){constuint32_tnowHAL_GetTick();if((uint32_t)(now-g_last_button_tick)50UL){g_last_button_ticknow;g_running^1U;/* 一次有效按下切换一次运行状态 */}}}中断里只做 50 ms 的简单去抖判断和状态切换不放阻塞延时。g_running由中断写、主循环读声明为volatile。主循环用HAL_GetTick()的差值判断一秒到了没有而不是在HAL_Delay(1000)里等待这样按键中断响应不会被软件大循环拖慢。本程序的“暂停”是让当前已亮的灯保持原状PA0 再次接地后从这只灯继续重新计算这一拍的 1 秒。这个语义在main.c中由was_running与last_step_tick处理主循环会在恢复时先重置计时起点避免刚恢复立刻跳到下一灯。上板检查使用 DAPLinkCMSIS-DAP烧录后复位重新运行PA8、PA9、PA10 按预期轮流点亮。PA0 是内部上拉输入杜邦线从 PA0 瞬间接到 GND 用来模拟按键触发一次后暂停并保持当前灯移开导线后再次短接才恢复运行。PA0 不要接到 3.3 V也不要把它当输出脚与其他信号短接。图中是 Keil 打开的实验三main.c和编译结果可以看到 PA8、PA9、PA10 的 LED 配置。实验三的 GCC 与 Keil 工程都编译过Keil 日志为 0 Error、0 WarningHEX 已生成。烧录后我一开始忘了复位看不到预期的流水按下复位键后三只外接灯正常轮流亮起。PA0 接地操作当时没有拍照所以这里的图片只能证明工程打开和编译完成不能充当按键操作的照片。实验总结这两次实验没有重新换一套 LED 接线实验二让 PA8、PA9、PA10 按顺序亮实验三在相同接线上加了 PA0 中断来控制暂停和继续。软件仿真中相邻换灯约 0.889 s同一只灯再次亮起约隔 2.667 s。实物烧录后复位键这一环不能省复位后我看到了三灯流水。两份工程都能在 Keil 编译但我没有用仪器量过 PA8、PA9、PA10 的真实电平时长报告中的周期只对应软件仿真。资料STSTM32F10x 标准外设库STSW-STM32054STSTM32CubeF1 官方源码STM32CubeF1KeilLogic Analyzer 使用说明Logic AnalyzerArmCortex-M3 技术参考手册Cortex-M3 TRM
返回列表