这里写自定义目录标题
本次任务
一. 了解并掌握STM32中断原理,HAL库函数开发方法。安装 stm32CubeMX,配合Keil,使用HAL库方式完成下列任务:
1、重做上一个LED流水灯作业,即用GPIO端口完成3只LED红绿灯的周期闪烁。
2、用stm32F103核心板的GPIOA端某一管脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED流水灯工作;
接低电平时,LED流水灯停止工作。
二. 在没有示波器条件下,可以使用Keil的软件仿真逻辑分析仪功能观察管脚的时序波形,更方便动态跟踪调试和定位代码故障点。
请用此功能观察第1题中3个GPIO端口流水灯的输出波形,并分析时序状态正确与否,高低电平转换周期(LED闪烁周期)实际为多少。
一、 使用HAL库点亮流水灯
1.安装stm32cubeMX
Ⅰ 安装java
STM32CubeMX需要JDK支持,如果已经下载可以跳过此流程
下载地址: https://www.java.com/zh_CN/download/windows-64bit.jsp(尽量安装最新版 64 位的Java)
点击同意并开始免费下载
Ⅱ、 CubeMX下载
下载地址:
官网下载
点击download:
选择版本,这里选择windows:
点击ACCEPT接受:
输入信息后即可下载(邮箱真实即可)
Ⅲ、 CubeMX 安装
打开 SetupSTM32CubeMX-6.0.0.exe 文件,如果未安装 Java 环境,将会出现报错;
安装 Java 后,打开 SetupSTM32CubeMX-6.0.0.exe 文件,其他系统安装参考 Readme.html,点击 Next;
勾选 I accpt,点击 Next;
勾选第一个,点击 Next;
(第二个勾选表示参加改善用户体验计划,即上传用户日志数据,若勾选安装后,可在软件 Help > User Preferences > General Settings 里取消)
选择合适的安装路径,点击 Next;(若路径未创建,会提示路径将被创建)
根据需求勾选,点击 Next;
程序自动安装,安装完成后,点击 Next;
提示安装成功和一个卸载程序被创建在安装目录的 Uninstaller 文件夹中,点击 Done;
配置:
点击图示
联网状态下点击:
点击进入软件包管理
选择F1型号进行下载
2. 创建项目
启动cubeMX
新建项目:
选择芯片型号,这里选择F103C8T6,双击即可
在Pinout&Configiration界面单击要使能的GPIO管脚,并选择GPIO_Output()设置为推挽输出
在SYS栏中选择serial wire:
在Project Manager里面填入创建项目的基本信息
注:IDE一定要选好,这里选择MDK_ARM
然后就可以点击GENERATE CODE创建项目了
创建完成之后可以点击Open Project从KEIL打开项目
找到main.c的这个位置即可开始编程
3. 写代码
将以下代码复制至main.c的main函数里的while循环里
//红灯亮
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_Delay(1000);
代码解释:
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
这段函数将某管脚置零(GPIO_PIN_SET)或者置一(GPIO_PIN_RESET)
前两个参数则是代表操作的管脚是GPIOA10
编译一下
发现编译失败,报错为:
原因是ARM Complier的版本选择错误
点击魔法棒,进入target栏,选择正确的版本:
再编译试试看
将程序烧录进开发板中
4. 结果:
5. 通过keil仿真模拟器查看波形
如何打开逻辑分析仪可以参考:
https://blog.csdn.net/lxr0106/article/details/134065777
选择管脚:
运行观察:
可以看到三个灯完成流水的周期已经非常接近1s了
二、 中断点亮LED灯
1. 新建项目
打开cubeMX,在原有的基础上,选择一个管脚(这里选择A8)用于触发中断,选择GPIO_EXIT8,然后再NVIC里面勾选该选项:
在GPIO栏里面找到中断管脚选择:
生成
找到stm32f1xx_it.c
往最下翻即可找到中断函数:
先编译以下,然后找到该函数定义
一般选择重写这个callback函数来定义中断功能
2. 填写代码
进入main.c
①编写全局变量:
int flag=0; //led亮灭判断 int HIGH_NUM=0; //PA8高电平次数 int LIGHT_NUM=0; //PA8低电平次数
② 重写回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ HIGH_NUM+=1; if (flag==0){ flag=1; } }
该函数的功能为:
高电平时,将flag置为1,点亮led
累加PA8高电平次数
③ 编写main函数中的循环函数
if (flag==1){ int TEST_NUM=HIGH_NUM; HAL_Delay(20); if (TEST_NUM==HIGH_NUM){ flag=0; HIGH_NUM=0; LIGHT_NUM=0; } } /* USER CODE END WHILE */ if (flag==1){ if (LIGHT_NUM%3==0){ //红灯亮 HAL_GPIO_WritePin(GPIOA, >GPIO_PIN_10, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, >GPIO_PIN_5, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOC, >GPIO_PIN_13, GPIO_PIN_SET); } else if (LIGHT_NUM%3==1){ HAL_GPIO_WritePin(GPIOA, >GPIO_PIN_10, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, >GPIO_PIN_5, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC, >GPIO_PIN_13, GPIO_PIN_SET); } else if (LIGHT_NUM%3==2){ HAL_GPIO_WritePin(GPIOA, >GPIO_PIN_10, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, >GPIO_PIN_5, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOC, >GPIO_PIN_13, GPIO_PIN_RESET); } LIGHT_NUM+=1; HAL_Delay(1000); } else { HAL_GPIO_WritePin(GPIOA, >GPIO_PIN_10, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, >GPIO_PIN_5, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOC, >GPIO_PIN_13, GPIO_PIN_SET); }
函数逻辑为:
Ⅰ 若flag=1,通过判断20ms之内高电平次数有无累加PA8来判断高电平是否结束,若高电平结束则重置所有参数,flag=0,熄灭所有灯
Ⅱ 通过LIGHT_NUM判断该点亮哪一个灯
3. 编译运行
设计电路:
这里我有开关就直接连接开关,没有开关可以通过杜邦线进行gnd管脚和3v3管脚的切换
参考链接:STM32CubeMX 下载及安装教程