STM32F4(正点原子)学习笔记(一):GPIO及其小实验

目录

一、写在前面:

二、GPIO基本情况

1.概述

2.引脚说明

3.GPIO工作方式

(1)4种输入模式

(2)4种输出模式

(3)4种最大输出速度

(4)主要特性

4.GPIO相关配置寄存器

三、GPIO的那一堆寄存器

1.端口模式寄存器 (GPIOx_MODER)

GPIO port mode register

2.端口输出类型寄存器(GPIOx_OTYPER)

GPIO port output type register

3.端口输出速度寄存器(GPIOx_OSPEEDR)

GPIO port output speed register

4.端口上拉/下拉寄存器(GPIOx_PUPDR)

GPIO port pull-up/pull-down register

5.端口输入数据寄存器(GPIOx_IDR)

GPIO port input data register

6.端口输出数据寄存器(GPIOx_ODR)

GPIO port output data register

7.端口置位/复位寄存器(GPIOx_BSRR)

GPIO port bit set/reset register

8.GPIO端口配置锁定寄存器 (GPIOx_LCKR) (x = A..I)

GPIO port configuration lock register

9.GPIO 复用功能低位寄存器 (GPIOx_AFRL) (x = A..I)

GPIO alternate function low register

10.GPIO 复用功能高位寄存器 (GPIOx_AFRH) (x = A..I)

GPIO alternate function high register

四、GPIO小实验:跑马灯

1.硬件

2.库函数版(library function):

(1)重要函数

(2)led.c

3.寄存器版(register):

(1)RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR)

(2)led.c

4.位操作版(Bit-band operations):

(1)位带操作

(2)步骤

(3)led.c


一、写在前面:

        之前上过嵌入式的课程,也曾用rt1052/64把别人的程序编编改改,但对于单片机的理解仅停留在胎教的阶段。此次利用老师给的stm32f4(探索者)开发板,对单片机进行一个全面的学习。

        该文章为学习笔记,内容主要来自《Cortex M3与M4权威指南》、《STM32F4xx中文参考手册》、《STM32F4开发指南-寄存器版本_V1.2》、《STM32F4开发指南-库函数版本_V1.2》、正点原子的教学视频及网络。环境选择Keil uVision5。

        由于我编程和模电水平确实较差,望大家多批评指正了😏

二、GPIO基本情况

1.概述

        GPIO(General-purpose input/output),通用型输入输出的简称。既然一个引脚可以用于输入、输出或其他特殊功能,那么一定有寄存器用来选择这些功能。对于输入,一定可以通过读取某个寄存器来确定引脚电位的高低;对于输出,一定可以通过写入某个寄存器来让这个引脚输出高电位或者低电位;而对于其他特殊功能,则有另外的寄存器来控制它们。

2.引脚说明

        ①一共有7组IO口:GPIOA—GPIOG

        ②每组IO口有16个IO:GPIOA_0—GPIOA_15

        ③一共7*16=112个IO

        ④所有IO口都可以作为中断输入

3.GPIO工作方式

 图1、2  5V容忍I/O端口位的基本结构

(1)4种输入模式

        输入浮空(input floating)

                😃逻辑器件与引脚即不接高电平,也不接低电平,电压不确定

        ②输入上拉(input pull-up)

                🙀将不确定的信号通过一个电阻嵌位在高电平,上拉电阻同时可起到限流作用,IO口的常态为高电平

        ③输入下拉(input pull-down)

                🍟把电压拉低到GND,IO口的常态为低电平

        ④模拟功能(analog)

                👼关闭施密特触发器,将电压信号传送到片上外设模块,不接上下拉电阻

(2)4种输出模式

        ①带上拉或下拉的开漏输出(output open-drain) 

                🙊相当于三极管的集电极

                🙊开漏输出只可以输出强低电平 ,高电平靠外部电阻拉高

                🙊利用外部电路的驱动能力,减少IC(integrated circuit)内部的驱动。驱动电流从外部的VCC流出,IC内部仅需很小的栅极驱动电流

        ②带上拉或下拉开漏复用功能(alternate function open-drain)

                🤡可同时当作普通GPIO及内部外设(片上外设)控制器的引脚来使用

                🤡I/O引脚通过一个复用器连接到板载外设,该复用器一次仅允许一个外设的复用功能(AF)连接到I/O引脚,确保共用同一个I/O引脚的外设之间不会发生冲突

        ③带上拉或下拉的推挽输出(output push-pull)

                🐶推挽输出可输出强高低电平,连接数字器件。

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

                🐶推挽电路是两个参数一样的三极管以推挽形式置于电路中,每次只有一个导通,导通功耗小、效率高。输出即可向负载灌电流,也可从负载抽取电流。因此可提高电路的负载能力以及开关速度。

        ④带上拉或下拉的推挽复用功能(alternate function push-pull)

               🤯同②

        关于推挽输出和开漏输出可用图3来概括:

6ebd493549d90459cb6e7&690

  图3  左为推挽、右为开漏

(3)4种最大输出速度

        2MHz / 25MHz / 50MHz 100MHz

(4)主要特性

        🦞受控 I/O 多达 16 个

        🦞输出状态:推挽或开漏 + 上拉/下拉

        🦞从输出数据寄存器 (GPIOx_ODR) 或外设(复用功能输出)输出数据

        🦞可为每个 I/O 选择不同的速度

        🦞输入状态:浮空、上拉/下拉、模拟

        🦞将数据输入到输入数据寄存器 (GPIOx_IDR) 或外设(复用功能输入)

        🦞置位和复位寄存器 (GPIOx_BSRR),对 GPIOx_ODR 具有按位写权限

        🦞锁定机制 (GPIOx_LCKR),可冻结 I/O 配置

        🦞模拟功能

        🦞复用功能输入/输出选择寄存器(一个 I/O 最多可具有 16 个复用功能)

        🦞快速翻转(toggle),每次翻转最快只需要两个时钟周期

        🦞引脚复用非常灵活,允许将 I/O 引脚用作 GPIO 或多种外设功能中的一种

4.GPIO相关配置寄存器

        🤑每组IO口含下面10个寄存器,即10个寄存器可以控制一组GPIO的16个IO口。

        🤑均为32位

        🤑每个通用 I/O 端口包括:

                4 个 32 位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR 和GPIOx_PUPDR)

                2 个 32 位数据寄存器(GPIOx_IDR 和GPIOx_ODR)

                1 个 32 位置位/复位寄存器 (GPIOx_BSRR)

                1 个 32 位锁定寄存器 (GPIOx_LCKR)

                2 个 32 位复用功能选择寄存器(GPIOx_AFRH 和 GPIOx_AFRL)

三、GPIO的那一堆寄存器

1.端口模式寄存器 (GPIOx_MODER)

GPIO port mode register

        👵MODER寄存器每2位控制一个IO。32个位控制一组IO的16个IO

        👵00:输入(复位状态)

        👵01:通用输出状态

        👵10:复用功能模式

        👵11:模拟模式

2.端口输出类型寄存器(GPIOx_OTYPER)

GPIO port output type register

        🐎位31-16保留,必须保持复位值。

        🐎位15-0 端口x配置位,每位控制一个IO  0:输出推挽(复位状态)1:输出开漏

3.端口输出速度寄存器(GPIOx_OSPEEDR)

GPIO port output speed register

        🐼每2位控制一个IO口。32位控制一组IO口的16个IO

        🐼00:2MHz(低速)

        🐼01:25MHz(中速)

        🐼10:50MHz(快速)

        🐼11:30pF时为100MHz(高速)【15pF时为80MHz(高速)】        皮法 (pF)

4.端口上拉/下拉寄存器(GPIOx_PUPDR)

GPIO port pull-up/pull-down register

        🤠00:无上拉或下拉

        🤠01:上拉

        🤠10:下拉

        🤠11:保留

5.端口输入数据寄存器(GPIOx_IDR)

GPIO port input data register

        🤢31:16保留,必须保持复位值

        🤢15:0这些位为只读形式,只能在字模式下访问。它们包含相应I/O端口的输入值

6.端口输出数据寄存器(GPIOx_ODR)

GPIO port output data register

        🦁31:16保留,必须保持复位值

        🦁15:0  通过写入该寄存器,可分别对ODR位进行置位(1)和复位(0)

7.端口置位/复位寄存器(GPIOx_BSRR)

GPIO port bit set/reset register

        🦥31:16BRy用于端口复位

                这些位为只写形式,只能在字、半字或字节模式下访问。读取这些位可返回值0x0000

                0:不会对相应的ODRx位执行任何操作

                1:对相应ODRx位进行复位

        🦥15:0  BSy用于端口置位

                这些位为只写形式,只能在字、半字或字节模式下访问。读取这些位可返回值0x0000

                0:不会对相应的ODRx位执行任何操作

                1:对相应ODRx位进行置位

        🦥如果同时对BSxBRx置位,则BSx的优先级更高

8.GPIO端口配置锁定寄存器 (GPIOx_LCKR) (x = A..I)

GPIO port configuration lock register

9.GPIO 复用功能低位寄存器 (GPIOx_AFRL) (x = A..I)

GPIO alternate function low register

   图4  引脚0到7所用复用器

         💩31:0ADRLy端口x位y的复用功能选择(Alternate function selection for port x bit y) (y = 0..7) 这些位通过软件写入,用于配置复用功能 I/O。AFRLy 选择:

        0000: AF0
        0001: AF1
        0010: AF2
        0011: AF3
        0100: AF4
        0101: AF5
        0110: AF6
        0111: AF7
        1000: AF8
        1001: AF9
        1010: AF10
        1011: AF11
        1100: AF12
        1101: AF13
        1110: AF14
        1111: AF15

10.GPIO 复用功能高位寄存器 (GPIOx_AFRH) (x = A..I)

GPIO alternate function high register

        

    图5  引脚8到15所用复用器

         🙄功能同复用功能低位寄存器。

四、GPIO小实验:跑马灯

        注:任何方式操作IO口,都必须先使能相应的IO口时钟

                go to defination的快捷键为F12

1.硬件

        GPIO:推挽输出(上拉)

2.库函数版(library function)

(1)重要函数

        1个初始化函数:

                🤡void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

                🤡作用:初始化一个或者多个IO口(同一组)的工作模式,输出类型,速度以及上下拉方式。也就是一组IO口的4个配置寄存器。

                🤡(GPIOx->MODER, GPIOx->OSPEEDR,GPIOx->OTYPER,GPIOx->PUPDR)

        2个读取输入电平函数:

                😛uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

                😛作用:读取某个GPIO的输入电平。实际操作的是GPIOx_IDR寄存器。

                😛uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

                😛作用:读取某组GPIO的输入电平。实际操作的是GPIOx_IDR寄存器。

        2个读取输出电平函数:

                🙉uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

                🙉作用:读取某个GPIO的输出电平。实际操作的是GPIO_ODR寄存器。

                🙉uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

                🙉作用:读取某组GPIO的输出电平。实际操作的是GPIO_ODR寄存器。

        4个设置输出电平函数:

                👾void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

                👾作用:设置某个IO口输出为高电平(1)。实际操作BSRRL寄存器

                👾void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

                👾作用:设置某个IO口输出为低电平(0)。实际操作的BSRRH寄存器。

                👾void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

                👾void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

                👾这两个函数不常用,也是用来设置IO口输出电平。

        使能IO口时钟

                🐖RCC_AHB1PeriphClockCmd();

(2)led.c

#include "led.h"
#include "stm32f4xx.h"
void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE); //IO口时钟使能
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10; //对结构体进行赋值
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOF,&GPIO_InitStructure);
	GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10); //置位
}

3.寄存器版(register)

(1)RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR)

        🐲RCC(Reset Clock Controller)

        🐲RCC AHB1 peripheral clock enable register

(2)led.c

#include "stm32f4xx.h"

void LED_Init(void)
{
	RCC->AHB1ENR|= 1<<5; //IO口时钟使能
	//PF9
	GPIOF->MODER &= ~(3<<2*9); //通用输出
	GPIOF->MODER |= 1<<(2*9);
	GPIOF->OSPEEDR &= ~(3<<2*9); //50MHz
	GPIOF->OSPEEDR |= 2<<(2*9);
	GPIOF->OTYPER &= ~(1<<9); //推挽
	GPIOF->OTYPER |= (0<<9);
	GPIOF->PUPDR &= ~(3<<2*9); //上拉
	GPIOF->PUPDR |= 1<<(2*9);
	GPIOF->ODR |= 1<<9; //高电平
	//PF10
	GPIOF->MODER &= ~(3<<2*10);
	GPIOF->MODER |= 1<<(2*10);
	GPIOF->OSPEEDR &= ~(3<<2*10);
	GPIOF->OSPEEDR |= 2<<(2*10);
	GPIOF->OTYPER &= ~(1<<10);
	GPIOF->OTYPER |= (0<<10);
	GPIOF->PUPDR &= ~(3<<2*10);
	GPIOF->PUPDR |= 1<<(2*10);
	GPIOF->ODR |= 1<<10;
}

4.位操作版(Bit-band operations):

(1)位带操作

        位带别名区(Bit Band alias address)把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。

(2)步骤

        😤使能IO口时钟,调用RCC_AHB1PeriphClockCmd();

        😤初始化IO口模式

        😤位带操作

(3)led.c

#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"

int main(void)
{
	delay_init(168); //初始化延时函数
	LED_Init();
	while(1)
	{
		PFout(9) = 1; //PFout()为IO口操作宏定义
		PFout(10) = 1;
		delay_ms(500);

		PFout(9) = 0;
		PFout(10) = 0;
		delay_ms(500);
	}	
}

本文结束🐮

STM32F4学习笔记(二):时钟树及SysTick定时器

  • 11
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liutangplease

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值