首页 > 其他分享 >【STM32基础学习】--GPIO原理

【STM32基础学习】--GPIO原理

时间:2024-06-02 14:04:09浏览次数:20  
标签:HAL PIN Initure -- LED STM32 GPIO include

一.GPIO入门知识

全称:  general purpose intput outpot(通用输入输出端口)。

可以做输入也可以做输出。STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯,控制以及数据采集的功能。

二 .GPIO的八种工作模式

1.4种输入模式(可以读取端口的高低电平或者电压,用于读取按键输入,外接模块,电平信号输入,ADC电压采集,模拟通信协议接收数据(SPI,I2C))

输入浮空:可读取引脚电平,若引脚悬空,则电平不稳定。

输入上拉:可读取引脚电平,内部连接上拉电阻,悬空时默认高电平

输入下拉:可读取引脚电平,内部连接下拉电阻,悬空时默认低电平

模拟输入:GPIO无效,引脚直接接入内部ADC。

2.4种输出模式(带上下拉)--(可以控制端口输出高低电平,可用于驱动LED,控制蜂鸣器,模拟通信协议输出时序)

开漏输出:可输出引脚电平,高电平为高阻态,低电平接VSS

开漏复用输出:由片上外设控制,高电平为高阻态,低电平接VSS

推挽输出:可输出引脚电平,高电平接VDD,低电平接VSS

推挽复用输出:由片上外设控制,高电平接VDD,低电平接VSS

3.4种最大输出速度

2MHZ(低速)

25MHZ(高速)

50MHZ(快速)

100MHZ(高速)

4.上电复位后IO口的状态

上电复位后,GPIO默认为浮空状态,部分特殊功能引脚为特定状态。

复位后,调试引脚处于复用功能上拉/下拉状态。

PA15:JTDI处于上拉状态

PA14:JTCK/SWCLK处于下拉状态

PA13:JTMS/SWDAT处于下拉状态

PB4:NJTRS处于下拉状态

PB 3:JTDO处于浮空状态。

三. GPIO寄存器

每一组IO口都包含10个寄存器,

其中有4个32为配置寄存器

       模式寄存器 GPIOx_MODER

        00:输入模式(复位状态)      01:通用输出模式

        10:复用功能模式                     11:模拟模式

        输出类型寄存器GPIOx_OTYPER

        

        0:推挽输出(复位状态)     1:开漏输出

        输出速度寄存器GPIOx_OSPEEDR

        00:低速          01:中速

        10:快速          11:高速

       上拉下拉寄存器 GPIOx_PUPDR

        00:无上拉或者下拉          01:上拉

        10:下拉                            11:保留

2个32位的数据寄存器

        输入数据寄存器GPIOx_IDR

        1:高电平     0:低电平

        输出数据寄存器GPIOx_ODR

        1:高电平       0:低电平

1个32位置位/复位寄存器

        置位/复位寄存器GPIOx_BSRR

        控制输出的电平状态,

        低16位端口置位  1:高电平      0:不影响

        高16位端口复位  1:复位,输出0    0:不影响

1个32位的锁存寄存器

       配置锁存寄存器 GPIOx_LCKR

2个32位复用功能共寄存器

        复用功能寄存器(低位GPIOx_AFRL&高GPIO_AFRH)

四. 跑马灯实验

1.寄存器

led.h

#ifndef __LED_H_
#define __LED_H_

#include "sys.h"

//LED 端口定义
#define LED0 PBout(1)	// DS0
#define LED1 PBout(0)	// DS1	

void LED_Init(void);

#endif

led.c

#include "LED.h"

void LED_Init(void)
{    	 
	RCC->AHB1ENR|=1<<1;//使能PORTB时钟 
	GPIO_Set(GPIOB,PIN0|PIN1,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB0,PB1设置
	LED0=1;//LED0关闭
	LED1=1;//LED1关闭
}

main

#include "sys.h" 
#include "usart.h" 
#include "delay.h" 
#include "LED.h"


int main(void)
{ 
	Stm32_Clock_Init(360,25,2,8);
	delay_init(180);
	LED_Init();
	while(1)
	{
		LED0=0;  //DS0亮
		LED1=1;  //DS1灭
		delay_ms(500);
		LED1=0;  //DS0灭
		LED0=1;  //DS1亮
		delay_ms(500);
	}
}

2.HAL库版本

led.h

#ifndef _LED_H
#define _LED_H
#include "sys.h"

#define LED0 PBout(1)   //LED0
#define LED1 PBout(0)   //LED1

void LED_Init(void);
#endif

led.c

#include "led.h"

//初始化PB1为输出.并使能时钟	    
//LED IO初始化
void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOB_CLK_ENABLE();           //开启GPIOB时钟
	
    GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1; //PB1,0
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
	
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);	//PB0置1,默认初始化后灯灭
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);	//PB1置1,默认初始化后灯灭
}

main

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"

 
int main(void)
{
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    LED_Init();                     //初始化LED  
    while(1)
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET); //LED0对应引脚PB1拉低,亮,等同于LED0(0)
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);   //LED1对应引脚PB0拉高,灭,等同于LED1(1)
        delay_ms(500);										//延时500ms
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);   //LED0对应引脚PB1拉高,灭,等同于LED0(1)
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET); //LED1对应引脚PB0拉低,亮,等同于LED1(0)
        delay_ms(500);                                      //延时500ms 
    }
}
 

五.按键控制LED

KEY.h

#ifndef _KEY_H
#define _KEY_H
#include "sys.h"

#define KEY0        HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3)  //KEY0按键PH3
#define KEY1        HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2)  //KEY1按键PH2
#define KEY2        HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) //KEY2按键PC13
#define WK_UP       HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)  //WKUP按键PA0

#define KEY0_PRES 	    1
#define KEY1_PRES		2
#define KEY2_PRES		3
#define WKUP_PRES       4

void KEY_Init(void);
u8 KEY_Scan(u8 mode);
#endif

KEY.c

#include "key.h"
#include "delay.h"
							  
//

//按键初始化函数
void KEY_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟
    __HAL_RCC_GPIOH_CLK_ENABLE();           //开启GPIOH时钟
    
    GPIO_Initure.Pin=GPIO_PIN_0;            //PA0
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入
    GPIO_Initure.Pull=GPIO_PULLDOWN;        //下拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    
    GPIO_Initure.Pin=GPIO_PIN_13;           //PC13
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    
    GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2,3
    HAL_GPIO_Init(GPIOH,&GPIO_Initure);
}

//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{
    static u8 key_up=1;     //按键松开标志
    if(mode==1)key_up=1;    //支持连按
    if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
    {
        delay_ms(10);
        key_up=0;
        if(KEY0==0)       return KEY0_PRES;
        else if(KEY1==0)  return KEY1_PRES;
        else if(KEY2==0)  return KEY2_PRES;
        else if(WK_UP==1) return WKUP_PRES;          
    }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
    return 0;   //无按键按下
}

main

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"

{
    u8 key;
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    uart_init(115200);              //初始化USART
    LED_Init();                     //初始化LED 
    KEY_Init();                     //初始化按键
	
    while(1)
    {
        key=KEY_Scan(0);            //按键扫描
				switch(key)
				{				 
					case  WKUP_PRES:	//控制LED0,LED1互斥点亮
								LED1=!LED1;
								LED0=!LED1;
								break;
					case  KEY2_PRES:	//控制LED0翻转
								LED0=!LED0;
								break;
					case  KEY1_PRES:	//控制LED1翻转	 
								LED1=!LED1;
								break;
					case  KEY0_PRES:	//同时控制LED0,LED1翻转 
								LED0=!LED0;
								LED1=!LED1;
								break;
			}
        delay_ms(10);
    }
}

标签:HAL,PIN,Initure,--,LED,STM32,GPIO,include
From: https://blog.csdn.net/m0_62760159/article/details/139375351

相关文章

  • 【Flutter】路由详解
    ......
  • 【Flutter】Getx上篇
    ......
  • 【Flutter】Getx下篇
    ......
  • [AIGC] 广度优先搜索(Breadth-First Search,BFS)详解
    广度优先搜索(Breadth-FirstSearch,简称BFS)是一种用于图或者树的搜索算法,它的特点是按照“广度”进行搜索,即在扩展搜索路线的时候,BFS会先考虑当前节点的所有邻近节点,也就是说,它逐层地进行搜索。文章目录基本原理实现方法应用场景总结基本原理广度优先搜索的基本......
  • C语言之动态内存管理
    目录一、什么是动态内存分配二、malloc和free三、calloc和realloc四、常见的动态内存的错误 五、柔性数组六、总结 一、什么是动态内存分配动态内存分配是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。与静态内存分配不同,动态内存分配不需要......
  • FlashRAG
    文章目录一、关于FlashRAG特点✨......
  • LangChain 0.2 - 构建本地 RAG应用
    本文翻译整理自:BuildaLocalRAGApplicationhttps://python.langchain.com/v0.2/docs/tutorials/local_rag/文章目录一、项目说明二、文档加载三、模型1、LLaMA22、GPT4All3、llamafile四、链式使用五、问答六、检索问答一、项目说明PrivateGPT、llama.cpp、......
  • 设计模式之原型模式
    问题背景在开发一个图形设计软件时,我们面临一个常见的需求:用户需要频繁地创建和编辑各种图形,如圆形、矩形和多边形。其中,许多图形元素在属性上非常相似,比如颜色、大小或样式可能只有细微的差别。用户希望能够快速复制一个已有图形,然后对其进行小的修改,而不是每次都从零开始......
  • 详解C语言system()函数,一个函数让初学者的代码有趣(一)
    一.为什么一定要学习system()函数             对于绝大多数初学者来说,我们在学习C语言的过程中,所写出来的内容大多都只能展现在冰冷的黑白程序框中,所实现的功能也是千篇一律,如果只是完成学习任务,那就够了,但是对于一个希望写出来一点高级东西的程序员,那是远......
  • 浅谈正向代理和反向代理(案例介绍)
    公司一般主要以反向代理为主(最典型的Nginx负载均衡)一、正向代理客户端Client不直接访问服务器Server,通过代理服务器Proxy访问正向代理是客户主动使用的代理正向代理:最典型的案例就是通过爬虫爬取网络数据,如果请求次数过多该网站会屏蔽你的IP(封禁一段时间在访问、无......