【stm32f407】GPIO原理以及跑马灯的应用

发布者:JoyfulMelody最新更新时间:2019-02-12 来源: eefocus关键字:stm32f407  GPIO  跑马灯 手机看文章 扫描二维码
随时随地手机看文章

1.    GPIO介绍

1)介绍:GPIO:(GeneralPurpose Input Output (通用输入/输出)简称为GPIO) 


基本结构:



stm32f407VGT6这款单片机上共有PA‐PE共5×16共80个复用IO口,


每个通用I / O端口有4个32位配置寄存器(GPIOx_MODERGPIOx_OTYPER GPIOx_OSPEEDR GPIOx_PUPDR),两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),一个32位的置位/复位寄存器(GPIOx_BSRR),32位锁定寄存器(GPIOx_LCKR)和两个32位的备用功能选择寄存器(GPIOx_AFRH GPIOx_AFRL),如图:



2)GPIO的工作模式:


2.    GPIO的八种工作模式详解


浮空输入_IN_FLOATING

带上拉输入_IPU

带下拉输入_IPD

模拟输入_AIN

开漏输出_OUT_OD

推挽输出_OUT_PP

开漏复用输出_AF_OD

推挽复用输出_AF_PP

4输入 + 2输出 + 2复用输出,一共是8种模式,以下是八种模式的工作原理:


GPIO浮空输入_IN_FLOATING模式工作原理


以上截图就是浮空输入模式的原理图,


图中阴影的部分在浮空输入模式下是处于不工作状态的,尤其是下半部分的输出电路实际上这时的输出电路与输入的端口处于隔离状态。


黄色的高亮部分显示了数据传输通道,外部的电平信号通过左边编号1的I/O端口进入STM32内部经过编号2的施密特触发器整形以后送入编号为3的“输入数据寄存器”,在“输入数据寄存器”的另一端(编号4),CPU通过内部的数据总线可以随时读出I/O端口的电平变化的状态。


GPIO带上拉输入_IPU模式工作原理:


上图是STM32的GPIO带上拉输入模式的原理图。


与前面介绍的浮空输入模式相比,仅仅是在数据通道上面,接入了一个上拉电阻,根据STM32的数据手册,这个上拉电阻阻值介于30K~50K欧姆。


同样,CPU可以随时在“输入数据寄存器”的另一端,通过内部的数据总线读出I/O端口的电平变化的状态。


GPIO带下拉输入_IPD模式工作原理:



对于输入下拉模式的输入,是在数据通道的下部,接入了一个下拉电阻。

根据STM32的数据手册,这个下拉电阻阻值也是介于30K~50K欧姆。


对于要加上拉或下拉电阻:

1.当作单片机作为输入时,假设我们直接在IO端口接一个按键到地(或电源)。

因为按键按,于不按管脚都是悬空的。单片机就很难检测按键是否按下。

所以人为的接一个上拉(或下拉)。以确定未按下的时候IO输入电平的状态

2.可以提高芯片的抗干扰能

3.当单片机的IO口作输出时,如果不接上拉电阻只能提供灌电流。无法输出电流驱动外接设备。这时也需要考虑上拉电阻。这样才可以使IO输出高电平


GPIO模拟输入_AIN模式工作原理:



如果把STM32配置为模拟输入模式时,工作原理就比较简单了,信号从左边编号为1的端口进从右边编号为2的一端直接进入STM32单片机的AD模块。


细心的朋友可以看到数据通道中上拉、下拉电阻和施密特触发器,这时均处于关断的状态,“输入数据寄存器”就不能反映IO端口上的电平变化的状态了,换句话说,也就是在模拟输入状态下,CPU不能通过“输入数据寄存器”读到IO端口变化的数据了


以上分析的是GPIO模块IO引脚的输入模式的工作原理,下面介绍一下GPIO输出模式的工作原理


GPIO开漏输出_OUT_OD模式工作原理


上图是GPIO开漏输出模式的工作原理图

当CPU在编号1端通过“位设置/清除寄存器”或“输出数据寄存器”写入数据后

该数据位将通过编号2的输出控制电路传送到编号4的I/O端口。

如果CPU写入的是逻辑“1 ”,则编号3的N-MOS管将处于关闭状态

此时I/O端口的电平将由外部的上拉电阻决定

如果CPU写入的是逻辑“0 ”,则编号3的N-MOS管将处于开启状态

此时I/O端口的电平被编号3的N-MOS管拉到了“地”的零电位。


在图中的上半部,施密特触发器处于开启状态

这意味着CPU可以在“输入数据寄存器”的另一端,随时可以监控I/O端口的状态

通过这个特性,还可以实现了虚拟的I/O端口双向通信:假如CPU输出逻辑“1 ”

由于编号3的N-MOS管处于关闭状态,I/O端口的电平将完全由外部电路决定

因此,CPU可以在“输入数据寄存器”读到外部电路的信号,而不是它自己输出的逻辑“1 ”


GPIO口的输出模式下,有3种输出速度可选(2MHz、10MHz和50MHz)

这个速度是指GPIO口驱动电路的响应速度,而不是输出信号的速度

输出信号的速度与程序有关(芯片内部在I/O口的输出部分安排了多个响应速度不同的输出驱动电路

用户可以根据自己的需要选择合适的驱动电路)。

通过选择速度来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。

高频的驱动电路,噪声很高  

当我们的项目不需要比较高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能。

当然如果我们的项目要求输出较高频率的信号,但却选用了较低频率的驱动模块,很可能会得到比较失真的输出信号

GPIO推挽输出_OUT_PP模式工作原理



GPIO的推挽输出模式是在开漏输出模式的基础上,在“输出控制电路”之后,增加了一个P-MOS管

当CPU输出逻辑“1 ”时,编号3处的P-MOS管导通,而下方的N-MOS管截止,达到输出高电平的目的

当CPU输出逻辑“0 ”时,编号3处的P-MOS管截止,而下方的N-MOS管导通,达到输出低电平的目的

在这个模式下,CPU仍然可以从“输入数据寄存器”读到该IO端口电压变化的信号


GPIO开漏复用输出_AF_OD模式工作原理



GPIO的开漏复用输出模式与开漏输出模式的工作原理基本相同

不同的是编号为2的输入的源不同,它是和复用功能的输出端相连

此时的“输出数据寄存器”被输出通道给断开了。

从上面的这个图,我们还可以看到CPU同样可以从“输入数据寄存器”读取到外部IO端口变化的电平信号。


GPIO推挽复用输出_AF_PP模式工作原理



最后介绍一下GPIO推挽复用输出模式的工作原理

编号2“输出控制电路”输入是与复用功能的输出端相连

此时“输出数据寄存器”被从输出通道断开了,片上外设的输出信号直接与“输出控制电路”的输入端想连接。

我们将GPIO配置成复用输出功能后,假如相应的外设模块没有被激活,那么此时IO端口的输出将不确定。

其它部分原理与前面叙述的模式一样,包括对“输入数据寄存器”的读取方式也是一样的。跑马灯硬件



跑马灯接的是PD12,PD13,PD14,PD15 4个PIN脚


3.    跑马灯库函数编程

1)    需要的库函数文件:


头文件:stm32f4xx_gpio.h


源文件:stm32f4xx_gpio.c


2)    重要函数


1个初始化函数:


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


2个读取输入电平函数:


uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin);


uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);


2个读取输出电平函数:


uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);


uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);


4个设置输出电平函数:


void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);


void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);


void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitActionBitVal);


void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);


3)    GPIO_Init初始化样例


GPIO_InitTypeDef GPIO_InitStructure;


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//使能GPIOF时钟


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;//LED0和LED1对应IO口


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式


GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz


GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉


GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOD12,13


4)    读取输入电平函数


2个读取输入电平函数:


uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin);


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


例如:


GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);//读取GPIOA.5的输入电平


uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);


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


例如:


GPIO_ReadInputData(GPIOA);//读取GPIOA组中所有io口输入电平


5)    读取输出电平函数


uint8_t GPIO_ReadOutputDataBit (GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);


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


例如:


GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_5);//读取GPIOA.5的输出电平


uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);


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


例如:


GPIO_ReadOutputData(GPIOA);//读取GPIOA组中所有io口输出电平


6)    4个设置输出电平函数


void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);


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


void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_tGPIO_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口输出电平。


      以上就是整个GPIO库函数的使用,总结下GPIO库函数的步骤:


1)使能IO口时钟。调用函数RCC_AHB1PeriphClockCmd();


不同的外设调用的时钟使能函数可能不一样


如图:GPIO是在AHB1总线上

2)初始化IO口模式。调用函数GPIO_Init();


3)  3)操作IO口,输出高低电平。


    GPIO_SetBits();


    GPIO_ResetBits();


源码:


Led.h


#ifndef_LED_H_H_H

#define_LED_H_H_H

 

#include"stm32f4xx_gpio.h"

#include"stm32f4xx_rcc.h"

 

#defineLED_GREEN       GPIO_Pin_12

#defineLED_ORANGE      GPIO_Pin_13

#defineLED_RED         GPIO_Pin_14

#defineLED_BLUE        GPIO_Pin_15

 

#defineLED_ON 1

#defineLED_OFF 0

voidLED_Init(void);

voidLED_Operate(uint16_t GPIO_Pin,int32_t operate);

#endif

Led.c


#include"led.h"

 

voidLED_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct;

 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);

  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 |GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;

  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOD,&GPIO_InitStruct);

}

voidLED_Operate(uint16_t GPIO_Pin,int32_t operate)

{

  if(LED_ON == operate)

  {

    GPIO_SetBits(GPIOD,GPIO_Pin);

  }

  else if(LED_OFF == operate)

  {

    GPIO_ResetBits(GPIOD,GPIO_Pin);

  } 

}

Main.c


#include"led.h"

 

voidUser_Delay(__IO uint32_t nCount)

{

  while(nCount--)

  {

  }

}

intmain(void)

{

   LED_Init();

   while(1)

   {

     LED_Operate(LED_GREEN,LED_ON);

     User_Delay(0x3FFFFF);

     LED_Operate(LED_GREEN,LED_OFF);

     LED_Operate(LED_ORANGE,LED_ON);

     User_Delay(0x3FFFFF);

     LED_Operate(LED_ORANGE,LED_OFF);

     LED_Operate(LED_RED,LED_ON);

     User_Delay(0x3FFFFF);

     LED_Operate(LED_RED,LED_OFF);

     LED_Operate(LED_BLUE,LED_ON);

     User_Delay(0x3FFFFF);

     LED_Operate(LED_BLUE,LED_OFF);

     User_Delay(0x3FFFFF);

   }

   

}

关键字:stm32f407  GPIO  跑马灯 引用地址:【stm32f407】GPIO原理以及跑马灯的应用

上一篇:【stm32f407】轮序方式的按键应用
下一篇:【stm32f407】库函数

推荐阅读最新更新时间:2024-03-16 16:23

STM32F107以太网配置函数GPIO_ETH_MediaInterfaceConfig
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface) { assert_param(IS_GPIO_ETH_MEDIA_INTERFACE(GPIO_ETH_MediaInterface)); /* Configure MII_RMII selection bit */ *(__IO uint32_t *) MAPR_MII_RMII_SEL_BB = GPIO_ETH_MediaInterface; } STM32很大的优势就是:内部RAM+内部外设寄存器都可以位寻址,这是很难得的。 MAPR_MII_RMII_SEL_B
[单片机]
STM32F107以太网配置函数<font color='red'>GPIO</font>_ETH_MediaInterfaceConfig
STM8 入门学习与实验(一)GPIO与UART
简介:这一章节将描述如何配置GPIO,以及如何配置UART STM8工程模版:http://download.csdn.net/detail/u012388993/9904051 这两则实验将使用到的基本的系统配置初始化函数 CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);//配置UART1时钟 CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);配置时钟分频为1,则系统时钟频率为16Mhz/1 = 16Mhz CLK_HSICmd(ENABLE);//使能内部振荡器 实验一、点亮LED灯,灯正极接电源负极连接到引
[单片机]
STM8 入门学习与实验(一)<font color='red'>GPIO</font>与UART
第20章 STM32F429的GPIO应用之无源蜂鸣器
20.1 初学者重要提示 学习本章节前,务必保证已经学习了第13,14和15章。 注意有源蜂鸣器和无源蜂鸣器的区别,本章教程的20.2.1小节有专门说明。 开发板是采用的无源蜂鸣器,需要PWM驱动,而截至本章节还没有讲到PWM,会在第XX章节专门为大家讲解(更新到相应章节时再添),程序中是通过一个宏定义控制使能和关闭,所以对于初学者来说,当前阶段仅需了解到使能和关闭方法即可,后面学习到PWM章节了,再深入了解。 无源蜂鸣器的控制采用的非阻塞方式,实际项目中比较实用。 20.2 蜂鸣器硬件设计 蜂鸣器的硬件设计如下: 通过这个硬件设计,有如下两点需要学习: 20.2.1 蜂鸣器分类 蜂鸣器主要有电磁式和电压式两
[单片机]
第20章 STM32F429的<font color='red'>GPIO</font>应用之无源蜂鸣器
STM32F407 外部中断配置步骤
介绍STM32F407外部中断配置步骤,以按键为例,实现外部中断配置,使用按键触发中断进行LED灯控制。 【1】外部中断相关知识介绍 CM4 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。但 STM32F4 并没有使用 CM4 内核的全部东西,而是只用了它的一部分。 STM32F40xx/STM32F41xx 总共有 92 个中断, STM32F42xx/STM32F43xx 则总共有 96 个中断,以下仅以 STM32F40xx/41xx 为例讲解。 STM32F40xx/STM32F41xx 的 92 个中断里面, 包括 10 个内核中断和 8
[单片机]
<font color='red'>STM32F407</font> 外部中断配置步骤
STM32F407——串口显示跑马灯状态
#main.c #include sys.h #include delay.h #include usart.h #include led.h //#include beep.h //#include key.h #include exti.h extern u8 onoff,dir,speed,change,flag; extern u16 time; int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组 delay_init(168); //初始化延时函数 LED_In
[单片机]
<font color='red'>STM32F407</font>——串口显示<font color='red'>跑马灯</font>状态
单片机3.3V GPIO 控制 5V 通断
HUB-RPA项目中,F340 GPIO 输出只有3.3V,用它来控制USB 5V的通断,只用一个PMOS 有问题,电路修改如下后,可正常控制USB 5V的通断。
[单片机]
单片机3.3V <font color='red'>GPIO</font> 控制 5V 通断
STM32F0与STM32F1的GPIO是不同的分析
STM32F0与STM32F1的GPIO是不同的,细说比较乱,直接上图。 STM32F1的GPIO基本结构: 从图上看STM32f1输入只有上下拉,输出有开漏和推挽。 STM32F0的GPIO基本结构: 从图上看STM32f0输入只有上下拉,输出有开漏和推挽,而且后面也有上下拉选项。 既然GPIO基本结构都不同了,寄存器操作方式自然不同了。 比如,STM32F1的GPIO控制寄存器的功能被分解给了几个不同的寄存器等。
[单片机]
STM32F0与STM32F1的<font color='red'>GPIO</font>是不同的分析
GPIO器件增加边缘敏感信号的瞬态检测功能
尽管有许多GPIO器件能够检测信号电平的上升沿和下降沿变化,但有些应用只需捕获信号的前沿,无需监测下降沿。对于这些GPIO器件,我们通过一个简单的电路就能提供边缘敏感信号的瞬态变化检测功能。 Maxim的几款GPIO器件能够检测信号电平的变化,并在信号恢复到初始状态后,仍然可以为这一变化提供标志记录。对于这些器件,无论是信号电平的上升沿,还是下降沿,都能够触发对事件的捕获。有些应用中,只把信号前沿作为监控事件;而下降沿通常标志着事件的结束,不需要对其进行监测。这些应用中,边缘敏感信号的瞬态检测十分必要。 如图1所示,利用几个RC元件和一个斯密特触发器,Maxim器件即可实现信号瞬变的检测,提供高度灵敏的边缘监测。RC电
[电源管理]
为<font color='red'>GPIO</font>器件增加边缘敏感信号的瞬态检测功能
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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