STM32自学笔记(一)GPIO配置与使用

发布者:小九分析仪最新更新时间:2020-06-11 来源: eefocus关键字:stm32  GPIO  swd下载 手机看文章 扫描二维码
随时随地手机看文章

由于是stm32学习的第一个章节,会啰嗦一些,旨在帮助和我一样刚接触stm32时一头雾水的朋友,更好地理解、学会它。


很多学过51,刚开始学stm32的朋友可能会和我一样十分不适应,在我看来,stm32与51代码最大的区别在于,stm32几乎所有外设都要进行配置过后才能使用,比如说你想操作一个IO口,那么首先要对这个IO口所挂载的时钟进行使能,再对此IO口进行配置、使能。这也是为什么51点亮一个LED只需要一行代码,你找到的stm32的代码却看着都让人头大的原因。



为什么要进行初始化(配置)?就GPIO来说,51的IO口很简单,能且只能实现高低电平的输入输出;而stm32可以在此基础上,指定GPIO输入输出的类型,速率等一系列参数,正因为stm32可以实现更多的功能,因此要进行初始化,指定GPIO的参数。实际上配置完成后,就使用上来说是不会比51复杂到哪去的。因此,先耐着性子学会GPIO的配置吧。


认识GPIO初始化

首先要适应这种stm32的代码风格:对每个模块都写一个xxx_Init()函数进行初始化(配置)。至于这个函数里要写些什么,视这个模块用到哪些功能而定。比如说我想写一个程序控制LED的亮灭,需要用到GPIO,所以要做以下的事情:对GPIO的时钟进行使能、对GPIO进行初始化。把这两个过程写在一个名为LED_Init()的函数中,这样只需要在main()中调用一下LED_Init()就可以实现LED模块的初始化了。



本章仅讲解GPIO的初始化,其他功能怎么初始化在以后的章节中会进行讲解。


首先,我们要认识下面这个结构体:GPIO_InitTypeDef


typedef struct 

{  

    uint16_t GPIO_Pin;     

    GPIOSpeed_TypeDef GPIO_Speed;    

    GPIOMode_TypeDef GPIO_Mode;  

}GPIO_InitTypeDef; 


它具有三个成员变量:GPIO_Pin,  GPIO_Speed,  GPIO_Mode


对于GPIO的配置其实就是指定这三个参数的值。接下来通过一个实例讲解这三个变量的含义。


GPIO_InitTypeDef  GPIO_InitStructure; 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  //LED0-->PB.5 端口配置 

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽输出 

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度 50MHz 

GPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数配置 GPIO 


这便是GPIO初始化的常用格式(事实上stm32任何外设的初始化都可以参照这种格式)


1.首先,要实例化一个GPIO_InitTypeDef对象,名为GPIO_InitStructure。


2.接下来对它的三个成员变量进行配置。其中GPIO_Pin用来设置是要初始化哪个或者哪些IO口(这里要注意,决定的不是A、B、C...,而是GPIOx后面的数字,也就是16个引脚中的哪一个); GPIO_Mode 是用来设置输出输入模式(GPIO共有8种模式,这里用到的是推挽输出);GPIO_Speed 是IO口速度设置,有2M、10M、50M三个可选值。


3.最后,调用一下GPIO_Init()函数,GPIO的初始化就完成了。GPIO_Init()第一个参数填GPIOx,也就是确定A、B、C...,结合前面设置的GPIO_Pin,就确定了具体是哪一个IO口;第二个参数填 &GPIO_InitStructure,将我们之前设置好的参数通过GPIO_InitStructure这个对象输入进去,实现GPIO的初始化。


完整的GPIO初始化流程

接下来给出一个完整的GPIO初始化实例,用了两个IO口(PB5、PE5)分别控制两个LED。


void LED_Init(void)

{

 GPIO_InitTypeDef  GPIO_InitStructure;

                        //GPIO_InitTypeDef结构体用于配置GPIO,首先实例化一个它的对象

 

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB、PE端口的时钟

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz

 GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定的参数初始化GPIOB.5

 GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高电平

 

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;     //LED1-->PE.5 端口配置

 GPIO_Init(GPIOE, &GPIO_InitStructure);   //推挽输出,IO口速度为50MHz

    //这里虽然配置的是另一个IO口PE.5,但仍旧使用了上面配置PB.5时的对象,是因为两个IO参数一样,若出现参数不一样的情况,要重新实例化一个对象(或者更改之前对象的参数)

 GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高电平

}


认真理解这段代码。其中有两句代码是之前没有提到过的,分别是时钟的使能与GPIO_SetBits() 这个函数。



GPIO 是挂载在 APB2 总线上的外设,在固件库中对挂载在 APB2 总线上的外设时钟使能是通过函数 RCC_APB2PeriphClockCmd()来实现的,至于其他情况下时钟使能是什么函数,在以后的章节中会提到。



至于GPIO_SetBits() 在下文进行讲解。


IO口操作

GPIO配置完成后,就可以对IO口进行操作了。常用两种方式进行操作,效果是一样的。


寄存器

在sys.h中有以下定义


#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出

#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

......

//这里由于篇幅关系仅给出GPIOB的定义,其余GPIO端口都有类似定义


这使IO口的操作变得和51一样简单


#define LED PBout(5) //define下提高程序可读性

...

LED = 1; //输出高电平

LED = 0; //输出低电平

LED_in = PBin(5); //读取PB.5电平


可以直接用PBout(5)=1进行GPIOB.5的高电平输出,也可以像51一样先宏定义改个名称,增强可读性。


库函数版

//输出

GPIO_SetBits(GPIOB,GPIO_Pin_8); //PB.8输出高电平

GPIO_ResetBits(GPIOB,GPIO_Pin_8); //PB.8输出低电平

//输入

GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) //读取PE.2电平

Tips:操作IO口前,必须先进行对应的GPIO初始化

关键字:stm32  GPIO  swd下载 引用地址:STM32自学笔记(一)GPIO配置与使用

上一篇:STM32学习笔记之GPIO的基本使用
下一篇:STM32学习笔记(一)GPIO

推荐阅读最新更新时间:2024-11-07 19:44

STM32使用freertos时在中断中调用系统函数的注意点
CORTEX内核的优先级是数值越小优先级越高,即0是最高优先级。FreeRTOS正好相反,为了满足某些应用对中断实时性要求高的需求,使得中断优先级高于某个值之后,就不能调用操作系统的内核函数来提高实时性。而我们经常所犯的错误就是将中断的优先级设置的高于这个值,却还在中断中调用操作系统提供的API引起的。当把优先级改小也就是数值改大之后,程序能够正常运行。 注意点: 1:首先要将中断的嵌套设置为抢占优先级。 2:将freertos系统内核中断(configKERNEL_INTERRUPT_PRIORITY)的优先级设置成最低。 3:将freertos的最大系统调用中断优先级(configMAX_SYSCALL_IN
[单片机]
多功能STM32开发工具STM32CubeIDE使用指南
工欲善其事,必先利其器。 STM32Cube生态系统是ST为STM32开发者打造的软件生态,是嵌入式开发的利器。 为提升功能丰富且高能效的STM32系列微控制器的易用性,2019年,意法半导体在STM32Cube软件生态系统中增加了一个免费的多功能STM32开发工具:STM32CubeIDE。 为了和商用集成开发环境(IDE)工具一样好用,STM32CubeIDE充分发挥了意法半导体2017年收购的嵌入式开发工具厂商Atollic的技术优势。这套IDE软件采用行业标准的开放式许可条款,为简化和加快基于STM32的嵌入式设计,新增了STM32专用功能,包括功能强大的STM32CubeMX微控制器配置和项目管理工具。 通过整合
[单片机]
多功能<font color='red'>STM32</font>开发工具STM32CubeIDE使用指南
STM32值SPI的使用及SPI初始化注意事项
在STM32F10x系列芯片中,虽然所拥有的SPI同步串口数量不相同,但是初始化的方法都是一样的。其中使用SPI时候我们回忆GPIO的使用,要注意6点,我们这里主要讲解一点。 根据系统对该不同功能的要求,初始化不同功能外设,初始化GPIO,初始化SPI同步串口设备就会比较复杂。STM32F10x系列芯片的所有SIP同步串口都是和GPIO共用,SPI的初始化分为2大块,就是SPI所使用的I/O口的初始化和SPI功能的初始化。对于SPI同步串口要用到的引脚,根据数据的方向,要设置GPIO_Mode_IN_FLOATING或者GPIO_Mode_AF_PP复用推免输出。其他的和GPIO引脚设置一样。 至于低于SPI同步串口参数的初始化方
[单片机]
关于STM32 GPIO配置模式
其实关于GPIO模式,手册有非常详细的说明,可见好好查看Datasheet有多么重要!! 首先关于stm32的GPIO口有输入输出之分,这点与51单片机使用的双向IO口有区别,这就需要根据我们具体是输入还是输出配置为相应的输入输出模式。输入就是输入模式,输出就是输出模式,两者不能混用。 下面这段话是手册这么描述GPIO口的: 通用I/O(GPIO) 复位期间和刚复位后,复用功能未开启, I/O端口被配置成浮空输入模式(CNFx =01b, MODEx =00b)。 复位后, JTAG引脚被置于输入上拉或下拉模式: ─ PA15: JTDI置于上拉模式 ─ PA14: JTCK置于下拉模式 ─ PA13: JTMS置于上拉模式 ─
[单片机]
关于<font color='red'>STM32</font> <font color='red'>GPIO</font>配置模式
关于单片机STM32裸机程序架构设计
本着授人以渔的原则,既提供我一直在用的程序架构,也讲程序架构的设计思路。 如果本文内容,你都能领悟并做到,不管项目多复杂,都将游刃有余。 我研发的那几年,接触大多数工程师,都没有程序架构的概念,基本一个while死循环干到底。 模块之间也没有封装好,导致代码写好以后,扩展性和维护性太差,类似的功能代码,也很难移植到新项目去复用。 早期我也是这样写的,反正实现功能就行了,代码好不好,功能上又看不出区别。 不过,等你接触到复杂的项目时,这招就行不通了,没设计好程序架构,根本做不稳定。 我意识到这个问题,是碰到两种需求的时候: 1.是做一个基于STM32的网关项目,项目做完以后,客户老是要改功能,客户不懂技术,在客户眼里,觉得改一个
[单片机]
关于单片机<font color='red'>STM32</font>裸机程序架构设计
STM32 USB学习笔记7
主机环境:Windows 7 SP1 开发环境:MDK5.14 目标板:STM32F103C8T6 开发库:STM32F1Cube库和STM32_USB_Device_Library 现在来分析一下USB器件库中核心文件usbd_ioreq,相对于usbd_ctlreq来说usbd_ioreq文件的代码量要小一些。该文件的主要作用是为控制端点提供IO请求API,更准确来说是为默认的控制端点0提供的API,该文件只有7个函数体,首先看第一个函数发送数据函数 /** * @brief USBD_CtlSendData * send data on the ctl pipe * @param pdev: d
[单片机]
ubuntu下建立stm32开发环境:程序烧录openocd+openjtag
上一篇博客写了在ubuntu下,建立stm32开发环境,程序也已经编译好生成main.bin,接下来就是要把该文件烧录到stm32上.在Linux下给arm烧录程序主要使用openocd,这个软件开源,而且支持众多芯片,从ARM9到A8都可以,当然STM32也可以.支持的JTAG工具也很多,JLINK ST-LINK OSBDM都可以,我这正好有一个openjtag基于FT2232C的,也是被支持的. 参考: How-to manual Installing a toolchain for Cortex-M3/STM32 on Ubuntu by Peter Seng 博主最近在电脑上自建了博客,以后会更多的用那个了,欢
[单片机]
STM32系统的应用中如何避免数据受断电影响
在嵌入式设备的开发中,断电时通常需要保存一些非易失性数据。如果添加了系统配置,用户定义的信息等,并且添加了额外的ROM IC(例如基于I2C的24C02等),则额外的PCB空间将增加,硬件成本将增加,并且产品将减少。如果仅从实用角度出发,在诸如STM32系统的应用中,作者建议可以尝试以下两种方法并作为参考。 基于备份寄存器 原理:对于大容量MCU系列,它具有42个16位备份寄存器,而中小型微处理器仅具有10个16位备份寄存器。以stm32f103c8t6为例,这42个备份寄存器的地址偏移量为:0x04〜0x28、0x40〜0xbc,可以存储84个字节的数据。备用寄存器取决于备用电源。当外部VDD掉电时,只要系统的Vbat可以正
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved