stm32学习:(寄存器2)GPIO总体说明

news2024/11/15 7:18:51

目录

GPIO的主要特点

GPIO的8种工作模式

GPIO电路结构

GPIO输出模式

输出流程

复用输出模式

GPIO输入模式

输入流程

模拟输入流程

GPIO相关的7个寄存器

GPIOx_CRL

GPIOx_CRH

GPIOx_IDR

GPIOx_ODR

GPIOx_BSRR

GPIOx_BRR

GPIOx_LCKR

 实例   三个灯流水灯

main.c 

Delay.h   

Delay.c   

Driver_LED.h 

Driver_LED.c


STM32有多组GPIO,比如我们使用的芯片:STM32F103ZET6共有7GPIO端口,他们分别是GPIOxxA-G),每组控制16个引脚,共有112GPIO引脚。具体一个其他STM32芯片有多少组GPIO,可以去查看他们的对应的数据手册

每个引脚的电平是0-3.3V,部分引脚最高可以兼容到5V。

GPIO的主要特点

  1. 不同型号,IO口的数量可能不一样
  2. 快速翻转。最快可以达到每2个时钟周期翻转一次
  3. 每个IO都可以作为外部中断
  4. 支持8种工作模式

GPIO的8种工作模式

GPIO端口的每个位(引脚)可以由软件分别配置成8种模式,当然对同一个引脚同一时间只能处于某一种模式中

  1. 输入浮空(Input floating)
  2. 输入上拉(Input pull-up)
  3. 输入下拉(Input-pull-down)
  4. 模拟输入(Analog)
  5. 通用开漏输出(Output open-drain)
  6. 通用推挽式输出(Output push-pull)
  7. 推挽式复用功能(Alternate function push-pull)
  8. 开漏复用功能(Alternate function open-drain)

每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字节被访问

输出模式下可以控制端口输出高电平低电平,用于驱动LED,蜂鸣器等,如果是大功率器件(比如电机),还需要加上驱动器(小电流控制大电流)。

输入模式下可以读取端口的高低电平,用于读取外接按键,外接模拟信号的输入,ADC电压采集,模拟通信协议接受数据等。

GPIO电路结构

GPIO输出模式

输出流程

  1. 输出缓冲器被激活
  2. 推挽模式:输出寄存器上的 1 将激活P-MOS,输出高电平。0 将激活N-MOS,输出低电平。
  3. 开漏模式:PMOS永远关闭。 输出寄存器上的 0 激活N-MOS,而输出寄存器上的1 将端口置于高阻状态,所以外部必须要接上拉电阻。
  4. 施密特触发输入被激活。
  5. 弱上拉和下拉电阻被禁止。
  6. 出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器。
  7. 在开漏模式时,对输入数据寄存器的读访问可得到I/O状态。
  8. 在推挽模式时,对输出数据寄存器的读访问得到最后一次写的值。

复用输出模式

  1. 在开漏或推挽式配置中,输出缓冲器被打开。
  2. 内置外设的信号驱动输出缓冲器(复用功能输出)。
  3. 施密特触发输入被激活。
  4. 弱上拉和下拉电阻被禁止。
  5. 在每个APB2时钟周期,出现在I/O脚上的数据被采样到输入数据寄存器。
  6. 开漏模式时,读输入数据寄存器时可得到I/O口状态。
  7. 在推挽模式时,读输出数据寄存器时可得到最后一次写的值。

GPIO输入模式

输入流程

  1. 2个保护二极管的作用是保护我们的芯片不会由于电压过高或过低而烧毁。
    1. VDD是接电源(3.3V),VSS接地(0V)。如果IO引脚的输入电压高于VDD的值到一定程度,上方保护二极管导通,则引脚电压被拉低到VDD。如果IO引脚的输入电压(负电压)低于VSS到一定程度,则下方保护二极管导通,电压被拉高到VSS
  2. 2个开关控制引脚没有输入的时候是上拉,下拉还是浮空。当上面的开关闭合的时候,输入被拉高到高电平。当下面的开关闭合的时候,输入被拉低到低电平。如果两个都不闭合,输入就是悬空状态。两个同时闭合,就是费电了,不会这么做的
  3. TTL触发器是包含正反馈的比较器电路。可以对信号进行波形整形
  4. 从TTL触发起出来的数据,进入到输入数据寄存器中,我们就可以从中读取数据了

模拟输入流程

当配置为模拟输入时:

  1. 输出部分被禁止
  2. 禁止TTL触发输入,实现了每个模拟I/O引脚上的零消耗。施密特触发输出值被强置为0
  3. 弱上拉和下拉电阻被禁止
  4. 读取输入数据寄存器时数值永远为0

GPIO相关的7个寄存器

每个GPIO端口有7个相关的

  1. 2个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)
  2. 2个32位数据寄存器(GPIOx_IDR和GPIOx_ODR)
  3. 1个32位置位/复位寄存器(GPIOx_BSRR)
  4. 1个16位复位寄存器(GPIOx_BRR)
  5. 1个32位锁定寄存器(GPIOx_LCKR)

GPIOx_CRL

端口配置低寄存器,x可以是A-G

 该寄存器配置的每个GPIO的 0-7 这个8个位,所以叫低寄存器

  • MODE:每个端口有2个MODE位进行控制
    • 00:输入模式(复位后的状态)
    • 01:输出模式,最大速度10MHz
    • 10:输出模式,最大速度2MHz
    • 11:输出模式,最大速度50MHz
  • CNF:每个端口有2个CNF位进行控制
    • 当MODE是00 (输入模式)
      • 00:模拟输入模式
      • 01:浮空输入模式(复位后的状态)
      • 10:上拉/下拉输入模式
      • 11:保留
    • 当MODE>00(输出模式)
      • 00:通用推挽输出模式
      • 01:通用开漏输出模式
      • 10:复用功能推挽输出模式
      • 11:复用功能开漏输出模式

GPIOx_CRH

端口配置高寄存器

该寄存器配置的是每个端口的 8-15引脚,配置方式和低位寄存器完全一样

GPIOx_IDR

端口输入数据寄存器,

 保留位始终读为0。剩下的分别对应每个引脚的输入值

GPIOx_ODR

端口输出数据寄存器

保留位始终读为0。剩下的分别对应每个引脚的输出值 

GPIOx_BSRR

端口位设置/清除寄存器

 高16位是用清除对应的数据输出寄存器的位(0-15)的值:设置为0不影响,设置为1会清除ODR对应的位的值(置为0)

低16位是用设置对应的数据输出寄存器的位(0-15)的值:设置为0不影响,设置为1会设置ODR对应的位的值(置为1)

GPIOx_BRR

端口位清除寄存器

这个寄存器具有了GPIOx_BSRR一半的功能:清除

GPIOx_LCKR

端口配置锁定寄存器

该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置

每个锁定位锁定控制寄存器(CRL,CRH)中相应的4个位(CNF2位和MODE2位)。

第16位用来激活锁定寄存器,必须按照规定的时序来操作才行: 写1 -> 写0 -> 写1 -> 读0 -> 读1

对0-15位:

  • 0:不锁定对应端口的配置
  • 1:锁定对应端口的配置 

 实例   三个灯流水灯

一共有好几个文件,

main.c 

#include "Driver_LED.h"
#include "Delay.h"

int main()
{
    uint32_t leds[] = {LED_1, LED_2, LED_3};
    /* 1. 初始化LED */
    Driver_LED_Init();

    Drviver_LED_OffAll(leds, 3);

    while (1)
    {
        for (uint8_t i = 0; i < 3; i++)
        {
            Drviver_LED_OffAll(leds, 3);
            Drviver_LED_On(leds[i]);
            Delay_ms(500);
        }

        Drviver_LED_OffAll(leds, 3);
        Drviver_LED_On(leds[1]);
        Delay_ms(500);
    }
}

Delay.h   

#ifndef __delay_h
#define __delay_h
#include "stm32f10x.h"                  // Device header

void Delay_us(uint16_t us);
void Delay_ms(uint16_t ms);
void Delay_s(uint16_t s);

#endif

Delay.c   

#include "delay.h" // Device header

void Delay_us(uint16_t us)
{
    /* 定时器重装值 */
    SysTick->LOAD = 72 * us;
    /* 清除当前计数值 */
    SysTick->VAL = 0;
    /*设置内部时钟源(2位->1),不需要中断(1位->0),并启动定时器(0位->1)*/
    SysTick->CTRL = 0x5;
    /*等待计数到0, 如果计数到0则16位会置为1*/
    while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG));
    /* 关闭定时器 */
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE; 
}

void Delay_ms(uint16_t ms)
{
    while (ms--)
    {
        Delay_us(1000);
    }
}

void Delay_s(uint16_t s)
{
    while (s--)
    {
        Delay_ms(1000);
    }
}

Driver_LED.h 

#ifndef __DRIVER_LED_H
#define __DRIVER_LED_H

#include "stm32f10x.h"

#define LED_1 GPIO_ODR_ODR0
#define LED_2 GPIO_ODR_ODR1
#define LED_3 GPIO_ODR_ODR8

void Driver_LED_Init(void);

void Drviver_LED_On(uint32_t led);

void Drviver_LED_Off(uint32_t led);

void Drviver_LED_Toggle(uint32_t led);

void Drviver_LED_OnAll(uint32_t leds[], uint8_t size);

void Drviver_LED_OffAll(uint32_t leds[], uint8_t size);

#endif

Driver_LED.c

#include "Driver_LED.h"

/**
 * @description: 对LED进行初始化
 */
void Driver_LED_Init(void)
{
    /* 1. 打开GPIOA的时钟 */
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    /* 2. 给用到的端口的所有 PIN (PA0 PA1 PA8) 设置工作模式: 通用推挽输出 MODE:11  CNF:00 */
    GPIOA->CRL |= (GPIO_CRL_MODE0 | GPIO_CRL_MODE1);
    GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_CNF1);

    GPIOA->CRH |= GPIO_CRH_MODE8;
    GPIOA->CRH &= ~GPIO_CRH_CNF8;

    /* 3. 关闭所有灯  */
    Drviver_LED_Off(LED_1);
    Drviver_LED_Off(LED_2);
    Drviver_LED_Off(LED_3);
}

/**
 * @description: 点亮指定的LED
 * @param {uint32_t} led 要点亮的LED
 */
void Drviver_LED_On(uint32_t led)
{
    GPIOA->ODR &= ~led;
}

/**
 * @description: 关闭指定的LED
 * @param {uint32_t} led 要关闭的LED
 */
void Drviver_LED_Off(uint32_t led)
{
    GPIOA->ODR |= led;
}

/**
 * @description: 翻转LED的状态
 * @param {uint32_t} led 要翻转的LED
 */
void Drviver_LED_Toggle(uint32_t led)
{
    /* 1. 读取引脚的电平,如果是1(目前是关闭), 打开, 否则就关闭 */
    if ((GPIOA->IDR & led) == 0)
    {
        Drviver_LED_Off(led);
    }
    else
    {
        Drviver_LED_On(led);
    }
}

/**
 * @description: 打开数组中所有的灯
 * @param {uint32_t} leds 所有灯
 * @param {uint8_t} size 灯的个数
 */
void Drviver_LED_OnAll(uint32_t leds[], uint8_t size)
{

    for (uint8_t i = 0; i < size; i++)
    {
        Drviver_LED_On(leds[i]);
    }
}

/**
 * @description: 关闭数组中所有的灯
 * @param {uint32_t} leds 所有灯
 * @param {uint8_t} size 灯的个数
 */
void Drviver_LED_OffAll(uint32_t leds[], uint8_t size)
{
    for (uint8_t i = 0; i < size; i++)
    {
        Drviver_LED_Off(leds[i]);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939128.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0305-0308TTL逻辑门电路

逻辑门电路-逻辑描述中的问题 3.5TTL逻辑门电路3.5.1BJT的开关特性BJT的开关时间 3.5.2TTL反相器的基本电路1.电路组成2.TTL反相器的工作原理 3.5.3改进型TTL门电路-抗饱和TTL门电路1.抗饱和TTL门电路2.其他TTL门电路 3.7逻辑描述中的几个问题3.7.1正负逻辑问题3.7.2 基本逻辑门…

VirtualBox安装增强功能时报错:未能加载虚拟光盘VBoxGuestAdditions.iso 到虚拟电脑

VirtualBox安装增强功能时报错&#xff1a;未能加载虚拟光盘VBoxGuestAdditions.iso 到虚拟电脑 选中一个虚拟机 进入设置点击存储 再点击光盘样子的加号进入后就可以选择 添加 选中双击就好&#xff0c;我已经添加过了 所以我的会在上面 选中一个虚拟机 进入设置 点击存储 再点…

基于单片机的智能窗帘系统设计

【 摘 要 】 随着物联网技术的发展,智能家居越来越受到业界的关注,针对目前市场上智能窗帘的弊端,设计了一款基于单片机的智能窗帘 。 普遍窗帘需要手工进行控制,遥控窗帘通常需要远程控制,智能窗帘与之相比,可以实现自主控制。 系统前端探测器采用光敏传感器,对光线进行…

小程序中视频课程下载工具使用教程,一键下载小程序中的视频课程!

前言&#xff1a; 现代随着知识付费时代的发展&#xff0c;我们很多视频课程或需要学习的资料是保存在小程序当中的&#xff0c;但是现在很多小程序它是禁止让我们下载我们所观看到的视频课程的&#xff0c;这就给我们带来了很多不方便。今天我就教大家如何一键下载小程序中的…

python实现图像对比度增强算法

python实现直方图均衡化、自适应直方图均衡化、连接组件标记算法 1.直方图均衡化算法详解算法步骤公式Python 实现详细解释优缺点 2.自适应直方图均衡化算法详解算法步骤公式Python 实现详细解释优缺点 3.连接组件标记算法详解算法步骤8连通与4连通公式Python 实现详细解释优缺…

Qt 使用Installer Framework制作安装包

Qt 使用Installer Framework制作安装包 引言一、下载安装 Qt Installer Framework二、简单使用2.1 创建目录结构 (文件夹结构)2.2 制作程序压缩包2.3 制作程序安装包 引言 Qt Installer Framework (安装程序框架)是一个强大的工具集&#xff0c;用于创建自定义的在线和离线安装…

DP-适配器模式代码重新理解

package com.designpatterns.adapter;/*** 定义鸭子接口*/ public interface Duck {/*** 定义鸭子呱呱叫(quack)*/public void quack();public void fly(); }package com.designpatterns.adapter;/*** 实现一个绿头鸭*/ public class MallarDuck implements Duck{Overridepubl…

德国汉堡大学、清华大学联合英国布里斯托机器人实验室的研究工作分享:基于视觉遥操作的多指机械手灵巧操作

德国汉堡大学&#xff08;张建伟院士团队&#xff09;、清华大学&#xff08;孙富春教授和方斌&#xff09;联合英国布里斯托机器人实验室等单位在基于视觉信息遥操作的多指机械手灵巧操作研究方面取得进展。该工作得到了德国科学基金会&#xff08;DFG&#xff09;与中国国家自…

C++合作开发项目:美术馆1.0

快乐星空MakerZINCFFO 合作入口&#xff1a;CM工作室 效果图&#xff1a; 代码&#xff1a; &#xff08;还有几个音乐&#xff01;&#xff09; main.cpp #include <bits/stdc.h> #include <windows.h> #include <conio.h> #include <time.h> #in…

E16.【C语言】练习:输入一个正的整数,逆序打印这个整数的每一位

输入一个正的整数&#xff0c;逆序打印这个整数的每一位 输入&#xff1a;123 输出&#xff1a;321 步骤&#xff1a;1.取出整数的每一位 2.倒序打印 分析&#xff1a;123%103-->123/1012(3被去除了)-->12%102-->12/101(2被去除了)-->1%101(取出最后一位)->…

Michael.W基于Foundry精读Openzeppelin第66期——ProxyAdmin.sol

Michael.W基于Foundry精读Openzeppelin第66期——ProxyAdmin.sol 0. 版本0.1 ProxyAdmin.sol 1. 目标合约2. 代码精读2.1 getProxyImplementation(ITransparentUpgradeableProxy proxy)2.2 getProxyAdmin(ITransparentUpgradeableProxy proxy) && changeProxyAdmin(ITr…

【计算机网络】0 课程主要内容(自顶向下方法,中科大郑烇、杨坚)(待)

1 教学目标 掌握计算机网络 基本概念 工作原理 常用技术 为将来学习、应用和研究计算机网络打下坚实基础 2 课程主要内容 1 计算机网络和互联网2 应用层3 传输层4 网络层&#xff1a;数据平面5 网络层&#xff1a;控制平面6 数据链路层和局域网7 网络安全8 无线和移动网络9 多…

C2W1.LAB.Vocabulary Creation+Candidates from String Edits

理论课&#xff1a;C2W1.Auto-correct 文章目录 Vocabulary CreationImports and DataPreprocessingCreate Vocabulary法1.集合法法2.词典加词频法Visualization Ungraded Exercise Candidates from String EditsImports and DataSplitsDelete Edit Ungraded Exercise 理论课&…

Linux_实现线程池

目录 1、线程池的实现逻辑 2、创建多线程 3、对线程池分配任务 3.1 任务类 3.2 发送与接收任务 结语 前言&#xff1a; 在Linux下实现一个线程池&#xff0c;线程池就是创建多个线程&#xff0c;然后对这些线程进行管理&#xff0c;并且可以发放任务给到线程池…

【springboot】中使用--WebMvcConfigurer

WebMvcConfigurer 一、页面跳转控制器step1:创建视图&#xff0c;resources/templates/index.htmlstep2:创建SpringMVC配置类step3:测试功能 二、数据格式化step1:创建 DeviceInfo 数据类step2&#xff1a;自定义 Formatterstep3: 登记自定义的 DeviceFormatterstep4: 新建 Con…

杭州外贸网站建设 最好用wordpress模板来搭建

防护服wordpress外贸网站模板 消防服、防尘服、隔热服、防化服、防静电服、电焊服wordpress外贸网站模板。 https://www.jianzhanpress.com/?p4116 工业品wordpress外贸网站模板 机械及行业设备、五金工具、安全防护、包装、钢铁、纺织皮革等工业品wordpress外贸网站模板。…

实现高效离职管理,智慧校园人事管理功能全解析

智慧校园人事管理系统中的离职管理功能&#xff0c;为教职工提供了一个高效、透明且合规的离职流程&#xff0c;同时为学校管理层提供了优化人力资源配置的有力工具。教职工可以在线轻松提交离职申请&#xff0c;系统随即自动记录并启动后续流程&#xff0c;从申请审核到工作交…

C语言 | Leetcode C语言题解之第241题为运算表达式设计优先级

题目&#xff1a; 题解&#xff1a; #define ADDITION -1 #define SUBTRACTION -2 #define MULTIPLICATION -3int* diffWaysToCompute(char * expression, int* returnSize) {int len strlen(expression);int *ops (int *)malloc(sizeof(int) * len);int opsSize 0;for (in…

任务2:python+InternStudio 关卡

任务地址 https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Python/task.md 文档 https://github.com/InternLM/Tutorial/tree/camp3/docs/L0/Python 任务 Python实现wordcount import re import collectionstext """ Got this panda plush to…

Qt Creator配置以及使用Valgrind - 检测内存泄露

Qt Creator配置以及使用Valgrind - 检测内存泄露 引言一、下载安装1.1 下载源码1.2 安装 二、配置使用2.1 Qt Creator配置2.2 使用2.3 更多详细信息可参考官方文档&#xff1a; 三、参考链接 引言 Valgrind是一个在Linux平台下广泛使用的开源动态分析工具&#xff0c;它提供了一…