STM32学习笔记(3_2)- GPIO输入和C语言

news2024/11/17 21:41:39

无人问津也好,技不如人也罢,都应静下心来,去做该做的事。

最近在学STM32,所以也开贴记录一下主要内容,省的过目即忘。视频教程为江科大(改名江协科技),网站jiangxiekeji.com

本期介绍GPIO的输入,典型的有按键控制LED、光敏传感器控制蜂鸣器。上期忘记了,这期会补上C语言的部分知识。

CTRL+空格或CTRL+ALT+空格:弹出代码提示

按键控制LED

这个实验要注意的点是按键抖动

硬件电路 

接线图 

 新建工程封装LED驱动程序

具体方式参考前几期

1、在工程下新建文件夹Hardware

2、keil5中三个箱子按钮添加Hardware路径

3、keil5中右键Hardware添加.c(存放主体代码)和.h文件(对外提供函数或变量的声明)

代码展示

 主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t KeyNum;		//定义用于接收按键键码的变量

int main(void)
{
	/*模块初始化*/
	LED_Init();		//LED初始化
	Key_Init();		//按键初始化
	
	while (1)
	{
		KeyNum = Key_GetNum();		//获取按键键码
		
		if (KeyNum == 1)			//按键1按下
		{
			LED1_Turn();			//LED1翻转
		}
		
		if (KeyNum == 2)			//按键2按下
		{
			LED2_Turn();			//LED2翻转
		}
	}
}

 LED函数

#include "stm32f10x.h"                  // Device header

/**
  * 函    数:LED初始化
  * 参    数:无
  * 返 回 值:无
  */
void LED_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);						//将PA1和PA2引脚初始化为推挽输出
	
	/*设置GPIO初始化后的默认电平*/
	GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);				//设置PA1和PA2引脚为高电平
}

/**
  * 函    数:LED1开启
  * 参    数:无
  * 返 回 值:无
  */
void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_1);		//设置PA1引脚为低电平
}

/**
  * 函    数:LED1关闭
  * 参    数:无
  * 返 回 值:无
  */
void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_1);		//设置PA1引脚为高电平
}

/**
  * 函    数:LED1状态翻转
  * 参    数:无
  * 返 回 值:无
  */
void LED1_Turn(void)
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)		//获取输出寄存器的状态,如果当前引脚输出低电平
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_1);					//则设置PA1引脚为高电平
	}
	else													//否则,即当前引脚输出高电平
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);					//则设置PA1引脚为低电平
	}
}

/**
  * 函    数:LED2开启
  * 参    数:无
  * 返 回 值:无
  */
void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);		//设置PA2引脚为低电平
}

/**
  * 函    数:LED2关闭
  * 参    数:无
  * 返 回 值:无
  */
void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_2);		//设置PA2引脚为高电平
}

/**
  * 函    数:LED2状态翻转
  * 参    数:无
  * 返 回 值:无
  */
void LED2_Turn(void)
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0)		//获取输出寄存器的状态,如果当前引脚输出低电平
	{                                                  
		GPIO_SetBits(GPIOA, GPIO_Pin_2);               		//则设置PA2引脚为高电平
	}                                                  
	else                                               		//否则,即当前引脚输出高电平
	{                                                  
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);             		//则设置PA2引脚为低电平
	}
}

Key函数 

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

/**
  * 函    数:按键初始化
  * 参    数:无
  * 返 回 值:无
  */
void Key_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);						//将PB1和PB11引脚初始化为上拉输入
}

/**
  * 函    数:按键获取键码
  * 参    数:无
  * 返 回 值:按下按键的键码值,范围:0~2,返回0代表没有按键按下
  * 注意事项:此函数是阻塞式操作,当按键按住不放时,函数会卡住,直到按键松手
  */
uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;		//定义变量,默认键码值为0
	
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)			//读PB1输入寄存器的状态,如果为0,则代表按键1按下
	{
		Delay_ms(20);											//延时消抖
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);	//等待按键松手
		Delay_ms(20);											//延时消抖
		KeyNum = 1;												//置键码为1
	}
	
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)			//读PB11输入寄存器的状态,如果为0,则代表按键2按下
	{
		Delay_ms(20);											//延时消抖
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);	//等待按键松手
		Delay_ms(20);											//延时消抖
		KeyNum = 2;												//置键码为2
	}
	
	return KeyNum;			//返回键码值,如果没有按键按下,所有if都不成立,则键码为默认值0
}

光敏传感器控制蜂鸣器

接线图

 新建工程封装BUZZER驱动程序

具体方式参考前几期

1、在工程下新建文件夹Hardware

2、keil5中三个箱子按钮添加Hardware路径

3、keil5中右键Hardware添加.c(存放主体代码)和.h文件(对外提供函数或变量的声明)

代码展示

主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Buzzer.h"
#include "LightSensor.h"

int main(void)
{
	/*模块初始化*/
	Buzzer_Init();			//蜂鸣器初始化
	LightSensor_Init();		//光敏传感器初始化
	
	while (1)
	{
		if (LightSensor_Get() == 1)		//如果当前光敏输出1
		{
			Buzzer_ON();				//蜂鸣器开启
		}
		else							//否则
		{
			Buzzer_OFF();				//蜂鸣器关闭
		}
	}
}

蜂鸣器函数

#include "stm32f10x.h"                  // Device header

/**
  * 函    数:蜂鸣器初始化
  * 参    数:无
  * 返 回 值:无
  */
void Buzzer_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	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);						//将PB12引脚初始化为推挽输出
	
	/*设置GPIO初始化后的默认电平*/
	GPIO_SetBits(GPIOB, GPIO_Pin_12);							//设置PB12引脚为高电平
}

/**
  * 函    数:蜂鸣器开启
  * 参    数:无
  * 返 回 值:无
  */
void Buzzer_ON(void)
{
	GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//设置PB12引脚为低电平
}

/**
  * 函    数:蜂鸣器关闭
  * 参    数:无
  * 返 回 值:无
  */
void Buzzer_OFF(void)
{
	GPIO_SetBits(GPIOB, GPIO_Pin_12);		//设置PB12引脚为高电平
}

/**
  * 函    数:蜂鸣器状态翻转
  * 参    数:无
  * 返 回 值:无
  */
void Buzzer_Turn(void)
{
	if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_12) == 0)		//获取输出寄存器的状态,如果当前引脚输出低电平
	{
		GPIO_SetBits(GPIOB, GPIO_Pin_12);						//则设置PB12引脚为高电平
	}
	else														//否则,即当前引脚输出高电平
	{
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);						//则设置PB12引脚为低电平
	}
}

光敏传感器函数

#include "stm32f10x.h"                  // Device header

/**
  * 函    数:光敏传感器初始化
  * 参    数:无
  * 返 回 值:无
  */
void LightSensor_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	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);						//将PB13引脚初始化为上拉输入
}

/**
  * 函    数:获取当前光敏传感器输出的高低电平
  * 参    数:无
  * 返 回 值:光敏传感器输出的高低电平,范围:0/1
  */
uint8_t LightSensor_Get(void)
{
	return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);			//返回PB13输入寄存器的状态
}

 

C语言 

数据类型

宏定义 

 typedef

和宏定义区别:一是句末需加;、二是新名字在右边、三是只能换特定变量类型。

但用typedef会更安全,不是变量类型的名字便用不了。

 结构体

数组是相同类型的组合,结构体可以是不同类型的组合

引用方式 

 搭配前面的typedef,再把结构体里的成员换行就变成STM32中常见的结构体样子。

 枚举

限制取值的范围,只能在给的参数列表里赋值。比如星期八这种情况。

 

总结GPIO使用方法

1、初始化时钟

2、定义结构体、赋值结构体

3、用GPIO_Init()函数,初始化指定的GPIO口

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

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

相关文章

idea maven配置

修改maven的路径&#xff08;使用本地的Maven&#xff09;&#xff0c;以及修改settings文件的位置和本地仓库的位置。 -DarchetypeCataloginternal 配置阿里云镜像&#xff08;在setting.xml文件中配置&#xff09; <!-- 配置阿里云 --> <mirror> <id>…

javase day11笔记

第十一天课堂笔记 构造代码块 { } 给 所有对象 共性特点 进行初始化操作 创建对象时在堆区对象中存放实例变量,同时执行构造代码块 执行顺序:静态代码块—>非静态代码块—>构造方法 继承★★★ 将多个类中相同的实例变量和实例方法 , 单独存放到一个类中,成为父类…

政安晨:【深度学习部署】—— TensorFlow Extended(TFX)介绍

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 前言 TensorFlow Extended&#xff08;TFX&a…

代数结构与数理逻辑:3.环

图1 环 14.1 环的定义与性质 环&#xff1a;代数系统 [ R ; ; ∗ ] [R;;*] [R;;∗]&#xff0c;其中&#xff0c;*为定义在 R R R上的二元运算&#xff0c;满足下述条件&#xff0c;对任意 a , b , c ∈ R a,b,c\in R a,b,c∈R, ​ 可结合、交换&#xff0c;且有单位元、逆元…

【Redis教程0x04】详解Redis的4个高级数据类型

引言 在【Redis教程0x03】中&#xff0c;我们介绍了Redis中常用的5种基础数据类型&#xff0c;我们再来回顾一下它们的使用场景&#xff1a; String&#xff1a;存储对象、url、计数、分布式锁&#xff1b;List&#xff1a;消息队列&#xff1b;Hash&#xff1a;存储对象、购…

2024年大模型面试准备(二):LLM容易被忽略的Tokenizer与Embedding

分词和嵌入一直是LM被忽略的一部分。随着各大框架如HF的不断完善&#xff0c;大家对tokenization和embedding的重视程度越来越低&#xff0c;到现在初学者大概只能停留在调用tokenizer.encode这样的程度了。 知其然不知其所以然是很危险的。比如你要调用ChatGPT的接口&#xf…

mysql迁移达梦数据库 Java踩坑合集

达梦数据库踩坑合集 文章目录 安装达梦设置大小写不敏感Spring boot引入达梦驱动&#xff08;两种方式&#xff09;将jar包打入本地maven仓库使用国内maven仓库&#xff08;阿里云镜像&#xff09; 达梦驱动yml配置springboot mybatis-plus整合达梦,如何避免指定数据库名&…

进程和线程,线程实现的几种基本方法

什么是进程&#xff1f; 我们这里学习进程是为了后面的线程做铺垫的。 一个程序运行起来&#xff0c;在操作系统中&#xff0c;就会出现对应的进程。简单的来说&#xff0c;一个进程就是跑起来的应用程序。 在电脑上我们可以通过任务管理器可以看到&#xff0c;跑起来的应用程…

C语言 04 基本数据类型

整数 整数就是不包含小数点的数字&#xff0c;整数包含以下几种类型&#xff1a; short &#xff1a;占用 2 个字节&#xff0c;16 个 bit 位。int&#xff1a;占用 4 个字节&#xff0c;32 个 bit 位&#xff0c;能够表示 -2^32 到 2^32 之间的数字&#xff0c;默认使用这种…

Open CASCADE学习|最小二乘法拟合直线

最小二乘法&#xff0c;又称最小平方法&#xff0c;起源于十八世纪的大航海探索时期&#xff0c;发展于天文领域和航海领域。其历史可以追溯到法国科学家马里勒让德于1805年首次提出这一概念&#xff0c;而1809年&#xff0c;高斯在他的著作《天体运动论》中也提出了最小二乘法…

LangChain核心模块 Model I/O

Model I/O 任何语言模型应用程序的核心元素都是模型。LangChain 为您提供了与任何语言模型交互的构建块。 Models llm 和 chat_model 都是表示特定模型配置的对象。 LLM 对象将字符串作为输入和输出字符串。ChatModel 对象将消息列表作为输入并输出消息。 LLM 返回一个字符…

idea创建angular项目

1.idea创建项目 idea&#xff1a;2023.2.3版本 不做赘述&#xff0c;我这里是创建模块&#xff0c;创建项目的话大同小异 2.创建完成后注意一下红色部分&#xff0c;后期需要 3.进入项目根目录 注意&#xff1a;一定要进入项目根目录&#xff0c;就是我们上面红色方框部分&a…

研华工控机610L学习笔记1:基本了解与认识

今日开始学习一些工控机的基本知识&#xff1a; 目录 目录 1、工控机介绍&#xff1a; 2、研华610L说明书参数了解&#xff1a; 3、基本结构了解&#xff1a; 前面板&#xff1a; 后窗&#xff1a; 4.RS232串口&#xff1a; ​编辑 5、工控机分类&#xff1a; 6、工控上…

第四十五周:文献阅读

目录 摘要 Abstract 文献阅读&#xff1a;基于注意力的双向LSTM和编码器-解码器的水质预测 现有问题 提出方法 创新点 方法论 1、EMD&#xff08;经验模态分解&#xff09; 2、VMD&#xff08;变分模态分解&#xff09; 3、VBAED模型 研究实验 数据集 数据预处理 …

AC和AP wlan使用案例

关于AC和AP的一篇 拓补图&#xff1a; AC1 sysn AC vlan 10int g0/0/1 p l t p t a v 10 port trunk pvid vlan 10 q int g0/0/2 p l t p t a v 10 port trunk pvid vlan 10 q int vlan 10 ip add 192.168.10.1 24 q dhcp enable int vlan 10 dhcp select interface q capwa…

算法打卡day24|回溯法篇04|Leetcode 93.复原IP地址、78.子集、90.子集II

算法题 Leetcode 93.复原IP地址 题目链接:93.复原IP地址 大佬视频讲解&#xff1a;复原IP地址视频讲解 个人思路 这道题和昨天的分割回文串有点类似&#xff0c;但这里是限制了只能分割3次以及分割块的数字大小&#xff0c;根据这些不同的条件用回溯法解决就好啦 解法 回溯…

三.寄存器(内存访问)

1.内存中字的存储 2.并不是所有cpu都支持将数据段送入段寄存器&#xff0c;所以有时候用个别的寄存器先把数据段存储起来&#xff0c;再把该寄存器mov到段寄存器。 3.字的传送 4.栈 5.栈机制 举例说明 6.栈顶超界问题 push超界 pop超界 7.栈段

管理自由,体验简单,使用安全 | 详解威联通全套多用户多权限管理方案【附TS-466C产品介绍】

管理自由&#xff0c;体验简单&#xff0c;使用安全 | 详解威联通全套多用户多权限管理方案【附TS-466C产品介绍】 哈喽小伙伴们好&#xff0c;我是Stark-C~。今天我们来解决一个之前评论区多次被提及的问题--多用户权限管理。 对于我们NAS用户来说&#xff0c;基本都会面临这…

Windows server 2008 R2 在VMware虚拟机上的安装

Windows server 2008 R2 在VMware虚拟机上的安装 准备工作VMware 新建并配置虚拟机安装和启动Windows server 2008 R2 准备工作 Windows server 2008 R2 ISO镜像的下载&#xff1a;Windows server 2008 R2 ISO VMware 新建并配置虚拟机 第一步&#xff0c;点击新建虚拟机 第…

leetcode每日一题2671

目录 一.题目原型 二.思路解析&#xff1a; 三.具体代码实现&#xff1a; 一.题目原型 二.思路解析&#xff1a; 其实我们可以用两个哈希表来解决这道题&#xff0c;一个哈希表hash1用来存这个数字出现了几次。另一个哈希表hash2用来存出现了几次的次数有几次&#xff0c;由于…