目录

STM32简介

首先介绍一下接口类型

1、普通GPIO接口

2、协议类GPIO接口

3、内存接口

4、模拟接口

2. GPIO简介

GPIO的复用:

3. GPIO的工作模式

1、4种输入模式

2、4种输出模式 

3、4种最大输出速度

 4.GPIO框图剖析

5.GPIO的八种工作模式剖析:

 浮空输入模式

上拉输入模式​编辑 

下拉输入模式                              

模拟输入模式   ​编辑                            

开漏输出模式(带上拉或者下拉)               

推挽输出模式(带上拉或者下拉)​编辑

复用开漏输出(带上拉或者下拉)  ​编辑              

复用推挽输出(带上拉或者下拉)​编辑                           

开漏输出和推挽输出的区别:

 补充介绍三极管NPN PNP

NPN:

PNP:

在STM32中选用IO模式:

F4系列与F1系列区别:

GPIO的初始化(F4)

1.定义一个 GPIO_InitTypeDef 类型的结构体

2开启 LED 相关的 GPIO 外设时钟(时钟必要)

3选择要控制的 GPIO 引脚

4设置所选引脚的模式

5 设定所选引脚的输出类型

6 设定所选管脚的速度

7 设定所选管脚的上拉与下拉

8初始化GPIO

GPIO的初始化(F1)


STM32简介

单片微型计算机简称单片机(MCU(MicrbControl Unit)),我们自己的个人计算机中,CPU、RAM、ROM、I/O这些都是单独的芯片,然后这些芯片被安装在一个主板上,这样就构成了我们的PC主板,进而组装成电脑,而单片机只是将这所有的集中在了一个芯片上而已。单片机又有8位的如51单片机、16位的如MSP430、32位的如STM32,通常我们说的多少位通常指的是内核(CPU)一次处理的数据宽度。也就是说内核一次处理的位数越多单片机的计算速度就越快,性能也就越强悍。

STM32是意法半导体(ST)推出一款32位的单片机。STM32具有超低的价格、超多的外设、丰富的型号、优异的实时性、极低的开发成本等优势。STM32凭借其产品线的多样化、极高的性价比、简单易用的库开发方式,迅速在众多32位单片机中脱颖而出。

STM32芯片内部可以粗略划分两部分:内核+片上外设。如果与电脑类比,内核与片上外设就如同电脑的CPU与主板、内存、显卡、硬盘的关系。
ARM公司只设计内核不生产芯片,他会将有关内核的技术授权给各半导体厂商例如ST、TI、Atme1、NXP等厂商。这些厂商都是基于这个内核自己设计片上外设如SRAM、ROM、FLASH、USART、GPIO等,然后集成到一个硅片上,这就是我们现在用的芯片。

image-20201123192912952

芯片内部内核和外设分别是两个公司设计的,那他们该怎么联系到一起协同高效的工作呢?答案就是总线,学过计算机组成原理的同学都应该知道计算机五大组成部分运算器、控制器、存储器、输入设备、输出设备他们之间的通信就是通过总线。我们上面也说了单片机就是一个集成在硅片上的计算机,所以他内部的连接关系也是靠总线。

我们知道,在嵌入式开发中,比如51和Arduino,我们写程序烧入芯片就可以实现控制。那么我们写的程序怎么就能控制我们的单片机工作呢或者程序在控制什么东西呢?
那个东西就是寄存器,其实不管我们用库开发还是寄存器开发我们本质上就是在控制寄存器上的每个位的通断,并且这些寄存器都有其特定的功能。换句话说每个外设(如GPI0、USART、I2C、SPI.…)都对应有寄存器来对他控制。

所以STM32可以用寄存器开发也可以用库开发。

STM的选型


STM32是ST的所有产品的统称,ST有两大家族STM8和STM32。STM8主要针对于低成本,对主频要求比较低、运算速度要求不是很高的低端市场。STM32主要应用于项目对主频要求较高、运算速度比较快、实时性好的中高端市场。STM32有很多产品大致划分可分为主流MCU、高性能MCU、低功耗MCU。其中主流MCU如STM32F1系列、高性能MCU如STM32F4、STM32F7系列、低功耗MCU如STM32L0系列。并且每个系列产品下面还会根据闪存容量、外设数量、封装大小分为很多种类并且价格也是差别很大。

首先介绍一下接口类型

接口就是芯片之间的连接方式。单片机通过GPIO与各种模块相连接,传输数据、信号。接口类型可分为以下几种:

1、普通GPIO接口

通常只有一个引脚,只负责输出、输入高低电平。

比如输出高低电平控制LED、蜂鸣器;作为按键输入引脚判断按键是否被按下。

2、协议类GPIO接口

一条或多条数据线根据某种协议传输数据,引脚仍是输出输入高低电平,但是输出输入是根据协议决定的,比如IIC协议,只有在时钟线低电平的时候,数据线才能进行高低电平转换,时钟线为高电平的时候,数据线必须保持电平不变(起始信号、结束信号除外)。

这种情况一般是用来传输比较复杂的数据,比如与各种传感器、LCD等连接。

常见的协议有IIC、SPI、CAN、FSMC等。

3、内存接口

比如与Nor Flash、SDRAM、DDR、网卡DM9000等连接。

这类接口有地址总线、数据总线、读数据、写数据和片选信号。

4、模拟接口

之前三种接口GPIO的输入输出的都是高低电平,电平信号不是0就是1。

模拟接口GPIO输入输出是不确定的。简单理解就是输入输出的是模拟信号,是可以连续变化的,能输出0-Vmax之间的任意值。
 

2. GPIO简介


GPIO,即通用I/O(输入/输出)端口,是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。

STM32F407有7组IO。分别为GPIOA~GPIOG,每组IO有16个IO口,共有112个IO口  通常称为 PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。  并且F4系列是基于Cortex-M4内核  

GPIO的复用:

STM32F4 有很多的内置外设,这些外设的外部引脚都是与 GPIO 共用的。也就是说,一个引脚可以有很多作用,但是默认为IO口,如果想使用一个 GPIO内置外设的功能引脚,就需要GPIO的复用,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。    比如说串口  就是GPIO复用为串口

3. GPIO的工作模式

1、4种输入模式

(1)GPIO_Mode_IN_FLOATING 浮空输入
(2)GPIO_Mode_IPU 上拉输入
(3)GPIO_Mode_IPD 下拉输入
(4)GPIO_Mode_AIN 模拟输入

2、4种输出模式 

(5)GPIO_Mode_Out_OD 开漏输出(带上拉或者下拉)
(6)GPIO_Mode_AF_OD 复用开漏输出(带上拉或者下拉)
(7)GPIO_Mode_Out_PP 推挽输出(带上拉或者下拉)
(8)GPIO_Mode_AF_PP 复用推挽输出(带上拉或者下拉)


3、4种最大输出速度

(1)2MHZ  (低速)
(2)25MHZ  (中速)
(3)50MHZ  (快速)
(4)100MHZ  (高速)


关于他们的定义,都在  stm32f4xx_gpio.h 中,都为结构体形式的定义

 4.GPIO框图剖析

我们所用到的每一个GPIO其内部结构都是这样,分别对应着GPIO的八种模式  这里我们简单的介绍下:

  • 保护二极管:  IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD_FT时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁 
  • 上拉、下拉电阻:控制引脚默认状态的电压,开启上拉的时候引脚默认电压为高电平,开启下拉的时候引脚默认电压为低电平
  • TTL施密特触发器:基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO口信号经过触发器后,模拟信号转化为0和1的数字信号    也就是高低电平  并且是TTL电平协议   这也是为什么STM32是TTL电平协议的原因
  •  P-MOS管和N-MOS管:信号由P-MOS管和N-MOS管,依据两个MOS管的工作方式,使得GPIO具有“推挽输出”和“开漏输出”的模式     P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭

注:  VDD_FT  代表IO口,兼容3.3V和5V,如果没有标注“FT”,就代表着不兼容5V      

 在芯片数据手册的引脚定义中,会看到有“I/O电平”一列  有FT即为支持5V

5.GPIO的八种工作模式剖析:

 浮空输入模式

                  
浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器MCU直接读取I/O口电平,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。 (接用电压表测量其引脚电压为1点几伏,这是个不确定值) 以用来做KEY识别

上拉输入模式

 IO内部接上拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为高电平  如果I/O口输入低电平,那么引脚就为低电平,MCU读取到的就是低电平

STM32的内部上拉是"弱上拉",即通过此上拉输出的电流是很弱的,如要求大电流还是需要外部上拉。

下拉输入模式
                              

 IO内部接下拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为低电平  如果I/O口输入高电平,那么引脚就为高电平,MCU读取到的就是高电平

模拟输入模式
                               

当GPIO引脚用于ADC采集电压的输入通道时,用作"模拟输入"功能,此时信号不经过施密特触发器,直接进入ADC模块,并且输入数据寄存器为空 ,CPU不能在输入数据寄存器上读到引脚状态

当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出。

除了 ADC 和 DAC 要将 IO 配置为模拟通道之外其他外设功能一律 要配置为复用功能模式,

开漏输出模式(带上拉或者下拉)               

                           

(P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭)

开漏输出模式时,只有N-MOS管工作,如果我们控制输出为0,低电平,则P-MOS管关闭N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1时,高电平,则P-MOS管和N-MOS管都关闭,输出指令就不会起到作用,此时I/O端口的电平就不会由输出的高电平决定,而是由I/O端口外部的上拉或者下拉决定   如果没有上拉或者下拉 IO口就处于悬空状态

并且此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。,I/O口的电平不一定是输出的电平   

推挽输出模式(带上拉或者下拉)

(P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭)                          

推挽输出模式时,N-MOS管和P-MOS管都工作,如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1 高电平,则P-MOS管导通N-MOS管关闭,使输出高电平,I/O端口的电平就是高电平,  外部上拉和下拉的作用是控制在没有输出时IO口电平

此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。I/O口的电平一定是输出的电平   

复用开漏输出(带上拉或者下拉)
                

GPIO复用为其他外设输出数据寄存器GPIOx_ODR无效;  输出的高低电平的来源于其它外设,施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态    除了输出信号的来源改变 其他与开漏输出功能相同

复用推挽输出(带上拉或者下拉)
                           

GPIO复用为其他外设(如 I2C),输出数据寄存器GPIOx_ODR无效;  输出的高低电平的来源于其它外设,施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态    除了输出信号的来源改变 其他与开漏输出功能相同

开漏输出和推挽输出的区别:

推挽输出:

可以输出强高低电平,连接数字器件 

推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止.

开漏输出:

可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 需要外接上拉电阻,才能实现输出高电平  合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内);

在使用任何一种开漏模式时,都需要接上拉电阻,否则只能输出低电平

 补充介绍三极管NPN PNP

三极管也是只有在某些条件下才会导通。常用做开关电路。

三极管分为PNP和NPN两种,但是原理是类似的。

对于三极管,只需记住通过基极b和发射机e的导通控制集电极c和发射机e的导通。

NPN:

在这里插入图片描述

根据图中箭头判断电流流向。若基极电压Vb大于发射极电压Ve,则be之间导通,从而导致ce之间导通。那么V2就与低相连,V2=0。

通常Vb-Ve > 0.7v就认为be之间导通,根据材质这个电压可能会变化。

Vcon = 1,be导通,ce导通,V2 =0为低电平。

Vcon = 0,be截止,ce截止,V2 = V为高电平。

可以看到,V2电压与Vcon电压相反,所以一个三极管可以做反向电路。

PNP:

PNP型三极管与NPN的类似。

 在这里插入图片描述

根据图中箭头判断电流流向。若发射极电压Ve大于基极电压Vb,则eb之间导通,从而导致ec之间导通。那么V2就与V相连,V2=V,为高电平。

Vcon = 1,eb截止,ec截止,V2 =0为低电平。

Vcon = 0,eb导通,ec导通,V2 = V为高电平。

常见基本电路知识

推挽输出电路: 其中IN端输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当IN端输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平   

开漏输出电路:IN端输出低电平时,三极管导通,使输出接地,IN端输出高电平时,三极管截止,所以引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须接上拉电阻,

在STM32中选用IO模式:

上拉输入、下拉输入可以用来检测外部信号;例如,按键等;
模拟输入 ——应用ADC模拟输入,或者低功耗下省电
开漏输出一般应用在I2C、SMBUS通讯等需要"线与"功能的总线电路中。
 推挽输出模式一般应用在输出电平为0和3.3伏而且需要高速切换开关状态的场合。在STM32的应用中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式
复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL,SDA)
复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS)

F4系列与F1系列区别:

本质上的区别是F4系列采用了Cortex-M4内核  而F1系列采用Cortex-M3内核

F1系列(M3)IO口基本结构

F4系列(M4)IO口基本结构

F4系列设计的更加高级与人性化,他将外部上下拉电阻转移到了输出/输入驱动器外部,使得输出模式下也可以实现内部上拉与下拉,方便了用户的使用,增加了灵活性

GPIO的初始化(F4)


这里我们以初始化LED为例

1.定义一个 GPIO_InitTypeDef 类型的结构体

 GPIO_InitTypeDef GPIO_InitStructure;   /*定义一个 GPIO_InitTypeDef 类型的结构体*/

一共有5个参数

2开启 LED 相关的 GPIO 外设时钟(时钟必要)

RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOB, ENABLE);     /*开启 AHB1时钟*/

   Q:为什么要设置时钟

    任何外设都需要时钟,51单片机,stm32,430等等,因为寄存器是由D触发器组成的,往触发器里面写东西,前提条件是有时钟输入。stm32是低功耗,他将所有的门都默认设置为disable(不使能),在你需要用哪个门的时候,开哪个门就可以,也就是说用到什么外设,只要打开对应外设的时钟就可以,   其他的没用到的可以还是disable(不使能),这样耗能就会减少。

Q:为什么 STM32 要有多个时钟源呢?

因为首 先 STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率, 比如看门狗以及 RTC 只需要几十 k 的时钟即可。同一个电路,时钟越快功耗越大,同时抗电磁 干扰能力也会越弱,所以对于较为复杂的 MCU 一般都是采取多时钟源的方法来解决这些问题。
 

而相对应的外设功能所使用的时钟 在stm32f4xx.h 中即可查看到

RCC_AHB1

RCC_APB1

3选择要控制的 GPIO 引脚

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  /*选择Pin9引脚*/

可选引脚为0-15 一组IO口有16个引脚

4设置所选引脚的模式

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   /*设定为输出模式*/

引脚的模式共有四种,分别为输入,输出,复用,和模拟模式

5 设定所选引脚的输出类型

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /*设置引脚的输出类型为推挽输出*/

输出模式有两种:推挽输出和开漏输出   

只有输出模式才需要配置,输入模式下不需要配置

6 设定所选管脚的速度

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//设定速度为100MHz  高速模式

7 设定所选管脚的上拉与下拉

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /*设置引脚为上拉模式*/

可设置为:上拉,下拉,与浮空

8初始化GPIO

 GPIO_Init(GPIOB, &GPIO_InitStructure);    //初始化所设置的引脚

GPIO_Init() 是官方配置的初始化函数  第一个参数是GPIOX 第二个参数是结构体所对应GPIO各种参数的配置

GPIO的初始化(F1)


F4的初始化相较于F1系列有了很大的改变,在配置F1系列时,结构体只有三个参数  

 GPIO_InitTypeDef 类型的结构体

所选管脚的速度

所选管脚的8种模式

区别:

 F1(M-3)系列管脚速度只有三种模式  并且管脚的模式配置八种模式全部都在一起定义,直接设置即可

总归还是大同小异,不做过多介绍,看下下方配置即可

void led_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;                    //定义初始化结构体
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA时钟
	
	GPIO_InitStruct.GPIO_Mode    = GPIO_Mode_Out_PP;     //配置模式
	GPIO_InitStruct.GPIO_Pin     = GPIO_Pin_0;           //配置哪个IO口
	GPIO_InitStruct.GPIO_Speed   = GPIO_Speed_50MHz;     //配置IO口速度,仅输出有效
	GPIO_Init(GPIOA,&GPIO_InitStruct);                   //初始化GPIOA的参数为以上结构体
}


 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐