STM32GPIO输入和输出

目录

一、先看IO端口位的结构

1、I/O输入:

2、I/O输出:

二、GPIO模式

三、枚举类型

四、GPIO输出点亮LED

五、LED流水灯

六、让蜂鸣器响起来

七、光敏传感器控制蜂鸣器


一、先看IO端口位的结构

上面部分是输入,下面是输出。

1、I/O输入:

首先,从I/O引脚开始,有两个保护二极管,主要作用是对输入电压限幅,保护内部电路。上面二极管接VDD为3.3V,下面二极管接VSS为0V。当输入电压为超过3.3V,则会导通上面的二极管;当输入电压小于0V也就是负电压,则会导通下面的二极管;如果输入电压为0~3.3V,则二极管不会导通,会正常输入。

接着,来到上拉电阻和下拉电阻。上拉电阻接的VDD,下拉电阻接的VSS,开/关是可以通过程序配置的。如果上面导通,下面断开,就是上拉输入模式;如果下面导通,上面断开,就是下拉输入模式;如果上面和下面都断开,则为浮空输入模式上拉和下拉的作用为了给输入提供一个默认的输入电平。如果什么都不接,输入为浮空模式,输入的电平就很容易受到干扰。这里的阻值都是很大的,是一种弱上拉和弱下拉,目的是尽量不影响正常的输入操作。

接着,来到TTL肖特基触发器,实际上这个是施密特触发器,这里翻译错误。这个施密特触发器的作用是对输入电压进行整形的。它的执行逻辑是:如果输入电压大于某一阈值,输出就会瞬间升为高电平;如果输入电压小于某一阈值,输出就会瞬间降为低电平;这样可以有效地避免因信号波动造成的输出抖动现象。如下图,输入的电压不稳定,有两个阈值,高于高阈值或小于高阈值且大于低阈值都为高电平;低于低阈值或大于低阈值且小于高阈值都为低电平。

接着,经过施密特整形的波形就可直接写入数据寄存器中了,就可以直接读取高低电平了。

接着,至片上外设是连接外设的,其中有模拟输入,连接到ADC上的,因为ADC需要接收模拟量,所以是连接到施密特触发电路前面的。另一个是复用功能输入,是连接到其他需要读取端口的外设上,比如串口的输入引脚等,这根线接收的是数字量,所以在施密特触发器后面。

2、I/O输出:

首先,数字部分可以由输出数据寄存器或片上外设控制。如果选择输出数据寄存器进行控制,就是普通的IO口输出,写这个寄存器的某一位就可以操作对应的某个端口;

位设置/清除寄存器可以用来单独操作输出数据寄存器的某一位,而不影响其他位在C语言中就是&=和|=,则在stm32中电路设置好了,只需要配置就行。如果我们要对某一位进行置1的操作(类似于|=),在位设置寄存器的对应位写1即可,剩下不需要操作的位写0,这样它内部就会有电路,自动将输出数据寄存器中对应位置为1,而剩下写0的位则保持不变;如果我们要对某一位进行置0的操作(类似于&=),在位设置寄存器的对应位写0即可,剩下不需要操作的位写1。

接着,通过输出控制,来到两个MOS管,上面为P-MOS,下面为N-MOS,这个MOS管就是一种电子开关通过信号来控制开关的导通和关闭,开关负责将IO口接到VDD或者VSS,这里可以选择推推挽、开漏或者关闭三种输出方式。

推挽输出模式下,P-MOS和N-MOS均有效。数据寄存器为1时,上管导通,下管断开,输出直接接到VDD,就是输出高电平;数据寄存器为0时,下管导通,上管断开,输出直接接到VSS,就是输出低电平;在这种模式下,高低电平均有较强的驱动能力,所以推挽输出模式也可以叫强推输出模式。在推挽输出模式下,stm32对IO口具有绝对的控制权,高低电平都由stm32说的算。

开漏输出模式下,这个P-MOS是无效的,只有N-MOS在工作。数据寄存器为1时,下管断开,这时输出相当于断开,也就是高阻模式。数据寄存器为0时,下管导通,这时输出直接接到VSS,也就是输出低电平。作用:可以作为通信协议的驱动方式。另外开漏模式还可以用于输出5V的电平信号,但必须要有上拉电阻的配合,因为本身是不能输出高电平,比如在IIC总线中。

剩下一个状态就是关闭,这个是当引脚配置为输入模式的时候,两个MOS管都无效,也就是输出关闭,端口的电平由外部信号控制。一个端口只有一个输出,但可以由多个输入。

二、GPIO模式

端口可以配置成8个模式,如下:

三、枚举类型

关键字枚举:enum

用途:定义一个取值受限制的整形变量,用于限制变量取值范围;宏定义的集合,里面的值也可以被其他类型引用。其实枚举本质也就是宏定义
定义枚举变量:
enum{FALSE =0,TRUE=1} EnumName;
引用枚举成员:
        EnumName =FALSE;
        EnumName =TRUE;//限制了EnumName;

由于名字过长,一般用typedef进行取个名字。

typedef enum{

FALSE =0,

TRUE=1

}week_t;

然后用week_t定义枚举类型。在32中直接写具体值时必须强转化为枚举类型。
 

四、GPIO输出点亮LED

利用A端0口即PA0,首先配置时钟使能,GPIO初始化。

注意:PA15、PB3、PB4是调试端口,别选,如果当作普通端口,还需要配置。

用到的函数:

    GPIO_InitTypeDef GPIO_InitStruct;                     //写在最前面RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //使能//GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;         //推挽输出GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_OD;     //开漏输出,没有高电平驱动那个能力GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 ;           //PC13口GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    //选择50HZ就可以了GPIO_Init(GPIOA,&GPIO_InitStruct);              //GPIO初始化

输出函数:

将GPIO某端某口即某一位引脚设置为高电平

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
或
//BitAction BitVal参数为:
// Bit_SET: to set the port pin
GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)

 将GPIO某端某口即某一位引脚设置为低电平

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
或
//BitAction BitVal参数为:
//Bit_RESET: to clear the port pin
GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)

 延时函数:

delay.c

#include "stm32f10x.h"/*** @brief  微秒级延时* @param  xus 延时时长,范围:0~233015* @retval 无*/
void Delay_us(uint32_t xus)
{SysTick->LOAD = 72 * xus;				//设置定时器重装值SysTick->VAL = 0x00;					//清空当前计数值SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器while(!(SysTick->CTRL & 0x00010000));	//等待计数到0SysTick->CTRL = 0x00000004;				//关闭定时器
}/*** @brief  毫秒级延时* @param  xms 延时时长,范围:0~4294967295* @retval 无*/
void Delay_ms(uint32_t xms)
{while(xms--){Delay_us(1000);}
}/*** @brief  秒级延时* @param  xs 延时时长,范围:0~4294967295* @retval 无*/
void Delay_s(uint32_t xs)
{while(xs--){Delay_ms(1000);}
} 

delay.h

#ifndef __DELAY_H   //防止头文件重复包含
#define __DELAY_Hvoid Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);#endif

main.c

#include  "stm32f10x.h"                  // Device header
#include  "Delay.h"
int main(void)
{GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //使能//GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;         //推挽输出GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_OD;     //开漏输出,没有高电平驱动那个能力GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 ;           GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    //选择50HZ就可以了GPIO_Init(GPIOA,&GPIO_InitStruct);while(1) {GPIO_SetBits(GPIOA,GPIO_Pin_0);               //设置为高电平Delay_ms(500);GPIO_ResetBits(GPIOA,GPIO_Pin_0);            //设置为低电平Delay_ms(500);GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET); Delay_ms(500);GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);Delay_ms(500);GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)1);  //也可以直接写数,但必须转为枚举类型BitActionDelay_ms(500);GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)0);Delay_ms(500);}}

五、LED流水灯

使用的是GPIOA端0~7引脚作为流水灯的输出引脚。

可以利用如下函数,可直接向GPIO端口写入值,也就是多位数据。

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)

main.c:

#include  "stm32f10x.h"                  // Device header
#include  "Delay.h"
int main(void)
{GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;     //推挽输出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_All;           //PA所有引脚GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    //选择50HZ就可以了GPIO_Init(GPIOA,&GPIO_InitStruct);while(1) {GPIO_Write(GPIOA,~0x0001); //0000 0000 0000 0001,写入值Delay_ms(100);GPIO_Write(GPIOA,~0x0002); //0000 0000 0000 0010Delay_ms(100);GPIO_Write(GPIOA,~0x0004); //0000 0000 0000 0100Delay_ms(100);GPIO_Write(GPIOA,~0x0008); //0000 0000 0000 1000Delay_ms(100);GPIO_Write(GPIOA,~0x0010); //0000 0000 0001 0000Delay_ms(100);GPIO_Write(GPIOA,~0x0020); //0000 0000 0010 0000Delay_ms(100);GPIO_Write(GPIOA,~0x0040); //0000 0000 0100 0000Delay_ms(100);GPIO_Write(GPIOA,~0x0080); //0000 0000 1000 0000Delay_ms(100);}}

六、让蜂鸣器响起来

这里蜂鸣器用的有源的,自带振荡源,只需给蜂鸣器一个高电平或低电平即可。我用的蜂鸣器是高电平驱动的。

main.c,代码如下:使用的是B12引脚。

#include  "stm32f10x.h"                  // Device header
#include  "Delay.h"
int main(void)
{GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;     //推挽输出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;          GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    //选择50HZ就可以了GPIO_Init(GPIOB,&GPIO_InitStruct);while(1) {GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET); Delay_ms(100);GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET); Delay_ms(100);GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET); Delay_ms(100);GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET); Delay_ms(700);}}

七、光敏传感器控制蜂鸣器

光敏传感器使用的是DO引脚输出,只输出0和1。原理是利用的电阻分压。光暗DO输出1,光强DO输出1。DO与B13引脚相连接。

首先,利用分模块文件进行编写程序,代码便于管理和移植。

蜂鸣器代码:

Buzzer.c"

#include "stm32f10x.h"                  // Device headervoid Buzzer_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;          //推挽输出GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);	}void Buzzer_ON(void)        //响
{GPIO_SetBits(GPIOB,GPIO_Pin_12);
}void Buzzer_OFF(void)       //不响
{GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}

Buzzer.h

#ifndef _BUZZER_H
#define _BUZZER_Hvoid Buzzer_Init(void);void Buzzer_ON(void);void Buzzer_OFF(void);#endif

光敏传感器:

LightSernsor.c:

#include "stm32f10x.h"                  // Device header
#include  "Delay.h"void LightSensor_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;          //上拉电阻GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);	}uint8_t LightSensor_GetNum(void)
{uint8_t LightSensorNum=0;if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==0)   //光暗DO输出1,光强DO输出0{LightSensorNum=1; }return LightSensorNum;
}

LightSernsor.h:

#ifndef _LIGHTSENSOR_H
#define _LIGHTSENSOR_Hvoid LightSensor_Init(void);uint8_t LightSensor_GetNum(void);#endif

main.c:

#include  "stm32f10x.h"                  // Device header
#include  "Delay.h"
#include  "Buzzer.h"
#include  "LightSensor.h"uint8_t LightSensorNum=0;int main(void)
{Buzzer_Init();LightSensor_Init();while(1) {LightSensorNum=LightSensor_GetNum();if(LightSensorNum==1)   //光强,使蜂鸣器响{Buzzer_ON();}else{Buzzer_OFF();}}}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA基础语法 Day11

一、Set集合 Set特点:无序(添加数据的顺序和获取出的数据顺序不一致),不重复,无索引 public class demo1 {public static void main(String[] args) {//1.创建一个集合//HashSet特点:无序,不重…

【操作系统】体系结构

🌹😊🌹博客主页:【Hello_shuoCSDN博客】 ✨操作系统详见 【操作系统专项】 ✨C语言知识详见:【C语言专项】 目录 操作系统的内核 操作系统结构——分层结构 操作系统结构——模块化 操作系统结构——宏内核、微内核…

Unity各个操作功能+基本游戏物体创建与编辑+Unity场景概念及文件导入导出

各个操作功能 部分功能 几种操作游戏物体的方式: Center:有游戏物体父子关系的时候,中心点位置 Global/Local:世界坐标系方向/自身坐标系方向 :调试/暂停/下一帧 快捷键 1.Alt鼠标左键:可以实现巡游角度查看场景 2.鼠标滚轮…

Linux忘记root用户密码怎么重设密码

直接说步骤: 1.重启客户机 2.在选择内核页面快速按e键,进入编辑模式 进入后应该是这个样子 在这里只能按上下键切换行 找到Linux16这里 3.按右方向键切换到行尾,也就是UTF-8处,在后面添加一个空格,然后加上这段话 …

【回眸】Tessy 单元测试软件使用指南(四)常见报错及解决方案与批量初始化的经验

前言 分析时Tessy的报错 1.fatal error: Tricore/Compilers/Compilers.h: No such file or directory 2.error: #error "Compiler unsupported" 3.warning: invalid suffix on literal;C11 requires a space between literal and string macro 4.error: unknown…

C0004.Qt中QComboBox设置下拉列表样式后,下拉列表样式无效的解决办法

问题描述 我们平时在使用Qt Creator对控件QComboBox的样式进行设置后,在运行程序启动界面时,发现设置的样式无效,效果如下: /* 设置下拉菜单框的样式 */ QComboBox QAbstractItemView {border: 1px solid rgb(161,161,161); /* …

【D3.js in Action 3 精译_028】3.4 小节 DIY 实战:使用 Observable 在线绘制 D3 条形图

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一部分 D3.js 基础知识 第一章 D3.js 简介(已完结) 1.1 何为 D3.js?1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践(上)1.3 数据可…

leetcode135:分发糖果

步骤1:计算问题性质的定义 我们需要解决的题目是一个典型的贪心算法问题,要求分发糖果的数量,满足特定条件。以下是问题的详细定义: 输入: ratings:长度为 n 的数组,表示每个孩子的评分&#x…

【51单片机】点亮LED之经典流水灯

开发环境 开发板:普中51-单核-A2单片机:STC89C52RC(双列直插40引脚 DIP40)Keil uVision5 v9.61 最新版破解方法自行百度,相关文档和视频资料很多,我自己将这一操作记录下来当做博客发布,CSDN以…

Pikachu-Unsafe FileUpload-客户端check

上传图片,点击查看页面的源码, 可以看到页面的文件名校验是放在前端的;而且也没有发起网络请求; 所以,可以通过直接修改前端代码,删除 checkFileExt(this.value) 这部分; 又或者先把文件名改成…

职业技术学校开设无人机培训技术详解

职业技术学校开设无人机培训技术,是一个涉及多个方面的综合性教学过程。以下是对该培训技术的详细解析: 一、培训目标 无人机培训技术的目标在于培养学员掌握无人机的基本原理、组装调试、飞行操作、安全规范及维修保养等技能,使其成为具备…

【Android】中级控件

其他布局 相对布局RelativeLayout RelativeLayout下级视图的位置是相对位置,得有具体的参照物才能确定最终位置。如果不设定下级视图的参照物,那么下级视图默认显示在RelativeLayout内部的左上角。用于确定视图位置的参照物分两种,一种是与…

Linux环境基础开发工具使用(2)

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Linux环境基础开发工具使用(2) 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. Li…

Qt Quick 3D 入门:QML 3D场景详解

随着 Qt 6 的发布,QtQuick3D 模块带来了新的 3D 渲染和交互能力,使得在 Qt 中创建 3D 场景变得更加简单和直观。本文将带您从一个简单的 QML 3D 应用开始,详细讲解各个相关领域的概念、代码实现以及功能特点。 什么是 Qt Quick 3D&#xff1…

git维护【.gitignore文件】

在工程下添加 .gitignore 文件【git忽略文件】 *.class .idea *.iml *.jar /*/target/

订阅ROS2中相机的相关话题并保存RGB、深度和点云图

系统:Ubuntu22.04 ROS2版本:ROS2 humble 1.订阅ROS2中相机的相关话题并保存RGB图、深度图和点云图 ros2 topic list/stellar_1/rgb/image_raw /camera/depth/image_raw /stellar_1/points2CMakeLists.txt cmake_minimum_required(VERSION 3.15) projec…

Docker安装人大金仓(kingbase)关系型数据库教程

人大金仓数据库(KingbaseES)是由中国人民大学金仓公司研发的一款自主知识产权的关系型数据库管理系统。 官网地址:https://www.kingbase.com.cn/ 本章教程,主要介绍如何用Docker安装启动人大金仓(kingbase)关系型数据库。 一、下载镜像 下载地址:https://www.kingbase.c…

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习04(环境准备)

4 创建docker容器 4.1创建网络 [rootlocalhost wutool]# docker network create -d macvlan --subnet192.168.137.0/24 --gateway192.168.137.2 --ip-range192.168.137.0/24 -o parentens33 nat 52af11381bfd655d175e4168265b2a507793e8fe48f119db846949ffd4dd27de [rootlocal…

​IAR全面支持国科环宇AS32X系列RISC-V车规MCU

全球领先的嵌入式系统开发软件解决方案供应商IAR与北京国科环宇科技股份有限公司(以下简称”国科环宇”)联合宣布,最新版本IAR Embedded Workbench for RISC-V将全面支持国科环宇AS32X系列RISC-V MCU,双方将共同助力中国汽车行业开…

文件上传之%00截断(00截断)以及pikachu靶场

pikachu的文件上传和upload-lab的文件上传 目录 mime type类型 getimagesize 第12关%00截断, 第13关0x00截断 差不多了,今天先学文件上传白名单,在网上看了资料,差不多看懂了,但是还有几个地方需要实验一下&#…