【STM32炒冷饭】GPIO和外部中断

【STM32炒冷饭】GPIO和外部中断(标准外设库)

用STM32系列单片机做项目已经一年了,突然想开个新坑写点东西,相当于自己的理解吧,有空就更,搭建开发环境和配置工程就不多说了,网上大把教程,介于本人实在是看不惯MDK的UI风格,所以一直使用VSCode+Keil Assist+MDK-ARM的开发方式


直接进入主题,本系列会写标准外设库和HAL库两版,使用的单片机为STM32F407ZGT6,使用了正点原子提供的SYSTEM文件夹,因为库函数本没有提供延时函数,为了方便直接使用正点原子提供的延时函数,后面也会讲如何使用系统滴答时钟构建延时函数。


关于F4系列的系统时钟

在我们使用STM32CubeMX构建工程的时候,在时钟树内可以直观的看到系统的锁相环时钟、分频、倍频,更为简单的可以直接设置你所想要的频率,STM32CubeMX会帮你自动配置好,那么在使用标准外设库时,我们没有类似的工具,而且F4系列与F1不同的是,F1已经默认为外部高速晶振为8MHz,并且将系统时钟设置为最高的72MHz,在F4系列中,我的板子HSE晶振为8MHz,那么我们想使用F407能跑到的最高168MHz,在system_stm32f4xx.c这个文件中,将宏定义改为#define PLL_M 8即可


一、什么是GPIO

GPIO的全程是(General-purpose input/output)通用输入输出口,简单的理解就是可以输出1或者0;我们来看STM32的GPIO的基本结构:
在这里插入图片描述可以看到通过下方的P-MOS和N-MOS可以设置引脚为推挽或者开漏,通过内部的上拉或者下拉电阻可以直接把引脚输出强高电平。这里的5V容忍是指引脚可以承受5V的电压,但并不是所有的引脚都可以承受5V的电压,在STMF4xx系列的数据手册中有明确标明能够容忍5V电压的管脚,在这里并不推荐直接给管脚接入5V电压,该芯片的VDD电压标称3.3V,不建议给GPIO直接输入5V电压。
下面我们分别通过发光二极管、蜂鸣器、按键来验证引脚的输入输出功能:

二、代码编写

1.输出部分

首先我们配置LED和蜂鸣器的相关管脚:
在这里插入图片描述在这里插入图片描述LED的阴极与STM32的GPIO相连,阳极通过一个分压电阻接到3.3V,那么当我们的GPIO输出低电平时,LED就能正常点亮;
通过宏定义先定义相关的管脚,使用宏定义的目的是为了提高代码的可移植性,也为了美观和便于理解阅读。这里也使用到了正点原子sys.c文件中提供的直接操作GPIO寄存器的接口函数,便于我们用51的思想去理解GPIO,51的寄存器数量在STM32面前九牛一毛,背寄存器显然是不太现实的,但是并不能完全不懂寄存器的操作。

/* LED Macro */
#define LEDx_GPIO_PROT GPIOF
#define LEDx_RCC_CLOCK RCC_AHB1Periph_GPIOF
#define LED0_PIN_NUM GPIO_Pin_9
#define LED1_PIN_NUM GPIO_Pin_10

#define LED_NUM_0 PFout(9)
#define LED_NUM_1 PFout(10)

/* LED Status */
typedef enum
{
   
    LED_ON = 0,
    LED_OFF
} LedStatus_TypeDef_t;

上面我们枚举了LED的两种状态,便于理解;

在GPIO的初始化中,根据实际硬件,将GPIO设置为推挽输出模式;这里设置上拉或者下拉都无所谓,推挽输出本就可以直接输出强力高电平和低电平,开漏输出只能输出低电平,需要外部上拉电阻才能输出高电平。
下面提供了两个函数,只是对ST提供的GPIO相关函数进行了封装方便使用;

/**
  * @name   Led_Init
  * @brief  LedPin Init Function
  * @param  InitState: Leds initial state
  * @retval None
  */
void Led_Init(LedStatus_TypeDef_t InitState)
{
   
    GPIO_InitTypeDef GPIO_InitSturcture;
    RCC_AHB1PeriphClockCmd(LEDx_RCC_CLOCK, ENABLE);

    GPIO_InitSturcture.GPIO_Pin = LED0_PIN_NUM | LED1_PIN_NUM;
    GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitSturcture.GPIO_OType = GPIO_OType_PP;
    GPIO_InitSturcture.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_2MHz;

    GPIO_Init(LEDx_GPIO_PROT, &GPIO_InitSturcture);
    LED_NUM_0 = InitState;
    LED_NUM_1 = InitState;
}

/**
  * @name   Led_SetState
  * @brief  LedPin set level function
  * @param  LedPinx: Leds pin number
  * @param  LedState: Leds State
  * @retval None
  */
void Led_SetState(uint16_t LedPinx
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值