首页 > 编程知识 正文

stm32单片机入门(stm32单片机gpio)

时间:2023-05-06 03:41:46 阅读:98281 作者:1882

大家好,我是xndts,高职教育的青椒,一直从事单片机、嵌入式系统、物联网等课程的教学。对于高职教育的学生水平,同龄人应该都知道,老师上课授课几乎没有意义。正是这样,我们才有了借助头条平台寻求认同感和成就感的想法。在这里,我将分享我花了很多时间设计的教学设计。如果你是MCU的粉丝或者同事,请点赞关注。你的支持是我持续输出的动力。谢谢大家!#我要上头条# #STM32# # MCU #

摆在我们面前的,只是对固件库的大致印象,以及在实际工程中如何一层一层调用库中的代码。这些疑惑需要通过“嵌入式HelloWorld——亮灯仪式”的经典套路来解决。考虑到这是其他后续实践项目的一个“基石”,我已经尽力规划了这部分内容,光是PPT就做了将近100页,试图打通STM32开发的“当省长的第二脉冲”。这个项目真正的价值在于,我们通过项目熟悉了STM32的内存架构、地址映射、时钟树、库文件,以及使用库开发项目的步骤,为我们以后使用库快速开发项目打下了坚实的基础。

PS:因为内容比较多,打算用三个教程来讲解一下。本文是——扩展的第三部分。我为我的学生班级选择了阳涛工作室的“阳涛一号”STM32开发板,因此我在此声明,本文使用的部分图片来自厂家。

00-1010配置系统时钟SYSCLK的时钟源我们知道,使用外设时必须开启外设时钟,但是在开启外设时钟之前,必须配置系统时钟SYSCLK。谁来配置系统时钟?system_stm32f10x.c库文件中有一个SystemInit()函数用于配置系统时钟。在8MHz外接晶振的前提下,系统时钟默认配置为72MHz,感兴趣的可以阅读其源代码。

STM32时钟配置主线

引导文件对系统时钟的指导配置系统时钟属于内核级任务,应该在用户任务之前完成。事实上,引导文件中的一段汇编代码已经被引导。

通过启动文件引导时钟配置

寄存器位操作库函数的本质仍然是配置寄存器(32位),不管这些位的用途是否明确,即使明确,计算一个32位的数字其实也是吃力不讨好的工作。如果结合寄存器手册看库函数的源代码,寄存器配置采用标准位操作方式。

GPIOx_CRL寄存器功能描述

使用位操作配置寄存器信号。

在源代码中检查库函数中的断言。基本上,图片中的红色字体会显示在每个库函数的开头。这里的“assert_param”实际上是一个宏。在库函数中,用于检查输入参数是否满足要求,如果不满足,则执行函数输出警告。

库函数源代码中的断言

该代码的含义是:

如果我们不定义“USE_FULL_ASSERT”宏,那么“assert_param”就是一个空宏(else和#endif之间的语句生效),没有动作。因此,所有库函数中的assert_param实际上是没有意义的,因此是不可见的。如果我们定义了“USE_FULL_ASSERT”宏,那么“assert_param”就是一个操作语句(if #和else之间的语句生效)。宏使用C语言中的问号表达式来判断参数表达式。如果expr的值为真,则没有操作(void 0)。如果表达式的值为false,则调用“assert _ fail”。而这个函数的输入参数是“__FILE__”和“__LINE__”,分别代表调用“assert_param”宏时的文件名和行号。为了防止头文件重复包含在固件库的所有头文件和我们自己写的“led.h”头文件中,我们可以看到类似的宏定义。它的优点

能是防止头文件被重复包含,避免引起编译错误。

头文件中防止被重复包含的编译声明

在头文件的开头,使用“#ifndef”关键字,判断标号“__LED_H_”是否被定义,后续理解的思路应该是这样的:

若没有被定义,则从“#ifndef”至“#endif”关键字之间的内容都有效。也就是说,这个头文件若被其它文件“#include”,它就会被包含到其该文件中了。头文件中紧接着使用“#define”关键字定义上面判断的标号“__LED_H_”。因此,当这个头文件被同一个文件第二次“#include”包含的时候,由于有了第一次包含中的“#define __LED_H_”定义,这时再判断“#ifndef __LED_H_”,判断的结果就是假了,从“#ifndef”至“#endif”之间的内容都无效,从而防止了同一个头文件被包含多次,编译时就不会出现“redefine(重复定义)”的错误了。

一般来说,我们不会直接在C 的源文件写两个“#include”来包含同一个头文件,但可能因为头文件内部的包含导致重复。如“led.h”文件中使用了“#include stm32f10x.h”语句,按习惯,可能我们写主程序的时候会写“#include led.h”以及”#include stm32f10x.h”,这个时候“stm32f10x.h”文件就被包含两次了,如果没有这种机制,就会出错。

至于“__LED_H_”这种标号,是一种约定俗成(并非强制)的命名方式——将文件名全部大写并在首尾与单词间加下划线。其实这只是防止它与其它普通宏定义重复了,如我们用“GPIO_PIN_0”来代替这个判断标号,就会因为stm32f10x.h 已经定义了GPIO_PIN_0,结果导致“led.h”文件无效了,“led.h”文件一次都没被包含。

二、Keil5仿真调试与使用技巧——掌握技巧,学会调试,提高效率

仿真环境配置

配置Keil5仿真选项

进入调试界面

调试窗口主要区域和按钮

查看外设状态

查看外设的菜单

查看I/O口电平变化

观察I/O口波形变化的配置

运行程序观察波形

Keil编译过程解读

源文件到目标文件的过程

我们下载到芯片Flash代码中的代码就是 .hex文件,上电后,内核把Flash中的代码加载到SRAM,就可以开始执行代码了。对于可执行映像文件(.axf格式),如果把它直接加载到芯片的 SRAM,那么芯片就可以直接运行保存在该文件上的代码了,即实现了调试。

批量注释与取消注释

批量注释与取消注释的按钮

快速查找宏和函数定义

查找宏定义

查找函数定义

根据标签查找函数

通过函数标签栏查找函数定义

三、更多LED控制效果——举一反三,学以致用

两个LED交替闪烁

核心板上的两个LED

实现这个效果,需要在LED_Init()函数中加入LED2端口的初始化代码。再根据前面介绍的四种方法,在主函数中加入库函数控制LED2端口的代码。这就当一个小小的作业吧!

LED呼吸灯基本原理视觉暂留效应:当LED亮灭交替慢的时候,我们看到的是LED闪烁效果,但是当交替变化很快的时候,其实已看不到闪烁效果了,而是保持一个亮度。占空比控制亮度:所谓占空比,就是一个周期内高电平时间所占的百分比。很显然,占空比越大,亮度越高;占空比越小,亮度越低。控制代码

呼吸灯控制关键代码

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。