完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前言
相信在看完上一篇非常详细的“简单”教程之后,即便是一个小白,对与STM32CubeMX也是了如指掌了。那么接下来进入单片机学习最关键的环节,点灯,俗话说:点灯是芯片开发最精髓的部分(我说的都是俗话)。那么学习完点灯也就对STM32HAL库的学习有着质的飞跃了。通过点灯我将对GPIO的用法进行一个最全面的介绍。 材料 正点原子探索者开发板,芯片为STM32F407ZGT6 开发板的原理图 STM32F4系列HAL库开发手册 STM32CubeMX keil5 新建及配置工程 具体新建过程就不详细说了,还不懂的小朋友看STM32CubeMX实战教程(一)——软件入门。好我们直接来到这个界面,老办法,先配置一下时钟,这个实验具体时钟是多少影响不大。 那么接下来打开我们STM32开发板的原理图,分别找到按键和LED的位置,可以看到有两个可编程LED,和四个按键,从中我们可以获得几点信息。
另外找到芯片对应的引脚号,LED分别是PF9、PF10,按键分别是PE2、PE3、PE4 记下来之后直接回到我们新建的STM32CubeMX工程中找到对应的引脚,这里我们使能五个引脚,其中LED对应的PF9、PF10选择GPIO_Output 而按键对应的则是PE2、PE3、PE4,选择GPIO_Input即输入 接下来我们在左侧的System Core一栏里面找到GPIO一项可以对刚刚使能的GPIO进行配置 先看到LED的配置,这五行分别是
在进入代码之前,先要给大家介绍一下HAL库里面的GPIO部分,和标准库一样,HAL库将所有的外设库都分了类并封装在不同的 .c文件下,那么我们该怎么去学会运用给我们提供的库函数呢。理所应当地,要会用一样东西当然就要知道它的功能,以及适用的情况,HAL库也是这么一个道理,这时候我比较推荐去看HAL库的HAL库开发手册,虽然在封装后的 .c 文件中已经有对于函数相对全面的介绍,但是在手册中不但更加完善清晰,而且有很多的适用场合说明,方便理解 ,接下来我以GPIO为例,去对手册进行一个较为全面的说明。 ps:手册是全英的,经费不够,没法全文翻译,见谅 外设结构 从目录可以看到,手册将每一种外设都封装成如下结构,前文介绍的是程序寄存器层面的封装,中间介绍的是库函数接口描述(这里也是我们重点要看的部分),最下面是一些宏定义,上下两层一般情况也不需要看。 继续展开中间层,从函数的介绍描述到使用方法都一目了然了,那么对于GPIO这种简单的外设就不从最开始介绍起了,可以直接进入函数功能的讲解。 API HAL库中给我们驱动GPIO提供的API函数接口并不多,但也足矣,每个函数都可以直接点击,便会直接跳转到具体函数功能描述界面。
进入代码 接下来,生成代码,进入工程,编译,喜提两个鸭蛋,这些就不多说了,遇到什么bug也可以回STM32CubeMX实战教程(一)——软件入门看看。 int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } 进来直接看到main函数里面的**MX_GPIO_Init();**然后追到GPIO初始化的地方 void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOF, LED0_Pin|LED1_Pin, GPIO_PIN_SET); /*Configure GPIO pins : PEPin PEPin PEPin */ GPIO_InitStruct.Pin = key0_Pin|key1_Pin|key2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /*Configure GPIO pins : PFPin PFPin */ GPIO_InitStruct.Pin = LED0_Pin|LED1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); } 可以看到这里确实是调用了HAL_GPIO_Init();对我们刚刚在STM32CubeMX上面配置的GPIO进行了初始化,具体是怎么初始化的不需要我们深入了解,总之现在可以直接用啦。 另外,我们可以打开main.h这个头文件,可以看到我们之前的命名,也就是端口号的宏定义 /* Private defines -----------------------------------------------------------*/ #define key0_Pin GPIO_PIN_2 #define key0_GPIO_Port GPIOE #define key1_Pin GPIO_PIN_3 #define key1_GPIO_Port GPIOE #define key2_Pin GPIO_PIN_4 #define key2_GPIO_Port GPIOE #define LED0_Pin GPIO_PIN_9 #define LED0_GPIO_Port GPIOF #define LED1_Pin GPIO_PIN_10 #define LED1_GPIO_Port GPIOF 这就意味着我们可以直接使用刚刚的命名进行GPIO的操作也是没有问题的 随后回到main函数的while循环中并添加如下代码,这里说明一下,HAL_Delay(); 是HAL库提供的毫秒级延时函数,这里有一个坑,就是有时候会卡死,具体原因会在后面的教程中进行分析。 /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(HAL_GPIO_ReadPin(key0_GPIO_Port,key0_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(key0_GPIO_Port,key0_Pin)==0) { HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET); } } if(HAL_GPIO_ReadPin(key1_GPIO_Port,key1_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(key1_GPIO_Port,key1_Pin)==0) { HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET); } } if(HAL_GPIO_ReadPin(key2_GPIO_Port,key2_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(key2_GPIO_Port,key2_Pin)==0) { HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin); } } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ 经过前面的介绍,这段代码也是非常容易了,key0按下时点亮LED0,key1按下时熄灭LED0,key2按下时反转两个LED的状态。可能这个时候会有疑问,为什么SET是熄灭,RESET是点亮呢。其实SET和RESET在这里的意思仅仅是输出高/低电平,并不知道LED在什么状况下会亮,而我们之前在STM32CubeMX上面所配置的高/低电平有效仅仅是保证了初始化完毕之后LED是熄灭的,这也可以回到GPIO的初始化函数中看到调用了 /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOF, LED0_Pin|LED1_Pin, GPIO_PIN_SET); 从而得知。 下载验证 具体下载方法这里不再重复,可查看STM32CubeMX实战教程(一)——软件入门,工程源文件我已经上传,非常抱歉由于CSDN官网上传的资源必须要设定积分,否则几乎无法通过审核,这里就没有办法免费开发给大家,不过源码在教程里已经非常详细了。 另外如果没有HAL库开发手册可以去ST官网自行下载,都是免费的。 这是工程及源码《按键点个灯——基于STM32CubeMX》 结语 非常感谢大家的阅读,如有不当或者错误的地方,欢迎指正,谢谢支持。 一个字一个字敲出来不容易,如果觉得有帮助,点个赞再走呗 祝大家事业蒸蒸日上! |
|
|
|
只有小组成员才能发言,加入小组>>
3277 浏览 9 评论
2950 浏览 16 评论
3454 浏览 1 评论
8983 浏览 16 评论
4044 浏览 18 评论
1092浏览 3评论
566浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
561浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2297浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1854浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-19 16:34 , Processed in 1.119153 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号