GPIO的使用--时钟使能含义--代码封装

news2024/9/25 5:21:40

目录

一、时钟使能的含义

1.为什么要时钟使能?

2.什么是时钟使能?

3.GPIO的使能信号?

 二、代码封装

1.封装前完整代码

2.封装结构

封装后代码

led.c

 led.h

key.c

key.h

main.c


一、时钟使能的含义

1.为什么要时钟使能?

每一个stm32单片机里都有着各种硬件设备,每一个设备对于频率的要求是不同的,有些设备要求频率低,有些设备要求频率高。如果为所有硬件设备设置同一频率,这就会出现性能不足或者资源浪费的情况,所以引入“时钟”这一概念,实现频率分配,即“分频”,“倍频”。需要低频和高频的设备使用相应的时钟使能函数(已经固定,需要查表或者查图获得),可以使用自己所需要的频率,实现资源的合理分配。

2.什么是时钟使能?

时钟是分频,使能是信号,是动作。所有时钟默认是disable,需要用哪个频率,调用相应的信号,设为enable。

时钟使能是用分频得到的信号作为模块的使能信号,模块原有的时钟不变。即用分频信号去控制模块的使能端口。

3.GPIO的使能信号?

GPIO模块的使能信号是AHB1

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);

通过一系列的分频和倍频使得每一个模块有比较适配的频率,利用率高。分倍频原理如下:

 二、代码封装

在前面的开关控制灯的亮灭代码实现时, 有开关的五大参数设置和灯的五大参数设置等数十行代码在函数实现的前面,影响程序的可读性,所以要进行代码的封装,增强简洁性。

1.封装前完整代码

#include "stm32f4xx.h"                  // Device header
 
int main()
{
	//时钟使能--LED
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
	
	//GPIO时钟控制  //参数配置
	//让程序决定第几组第几根引脚,如何工作
	GPIO_InitTypeDef led_gpio;
	led_gpio.GPIO_Mode = GPIO_Mode_OUT;    //引脚以输出方式工作
	led_gpio.GPIO_OType = GPIO_OType_PP;	 //推挽
	led_gpio.GPIO_Pin =  GPIO_Pin_9| GPIO_Pin_10 |GPIO_Pin_8;
	led_gpio.GPIO_Speed=GPIO_High_Speed;      //gpio的反应速率,不太影响
	led_gpio.GPIO_PuPd=GPIO_PuPd_DOWN;          //上拉  GPIO_PuPd_DOWN 下拉//GPIO_PuPd_NOPULL
	
	GPIO_Init(GPIOF,&led_gpio);
	GPIO_SetBits(GPIOF, GPIO_Pin_9);
	GPIO_SetBits(GPIOF, GPIO_Pin_10);
	
	uint16_t key0=0;
	//时钟使能--KEY开关
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
	
	//GPIO时钟控制  //参数配置
	//让程序决定第几组第几根引脚,如何工作
	GPIO_InitTypeDef key_gpio;
	key_gpio.GPIO_Mode = GPIO_Mode_IN;        //引脚以输入方式工作
	key_gpio.GPIO_OType = GPIO_OType_PP;	    //推挽
	key_gpio.GPIO_Pin =  GPIO_Pin_4| GPIO_Pin_3 |GPIO_Pin_2;//第几根引脚
	key_gpio.GPIO_Speed=GPIO_High_Speed;      //gpio的反应速率,不太影响
	key_gpio.GPIO_PuPd=GPIO_PuPd_UP;          //上拉  GPIO_PuPd_DOWN 下拉//GPIO_PuPd_NOPULL
	
	GPIO_Init(GPIOE,&key_gpio);               //初始化
	while(1)
	{
		//uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
		key0= GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4);//默认高电平,按下,接地
		if(key0==1)
		{
      GPIO_WriteBit(GPIOF, GPIO_Pin_10,1);//led高电平,灯灭
		}
		else
		{
			GPIO_WriteBit(GPIOF, GPIO_Pin_10,0);	//led高电平,灯亮
		}	
		
	}
}

2.封装结构

封装后代码

led.c
#include "stm32f4xx.h"                  // Device header

void Led_Init()
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
	
	GPIO_InitTypeDef gpio_init;
	
	gpio_init.GPIO_Mode=GPIO_Mode_OUT;
	gpio_init.GPIO_OType=GPIO_OType_OD;
	gpio_init.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;
	gpio_init.GPIO_PuPd=GPIO_PuPd_NOPULL;
	gpio_init.GPIO_Speed=GPIO_High_Speed;
	
	GPIO_Init(GPIOF,&gpio_init);
}
 led.h
void Led_Init(void);//声明
key.c
#include "stm32f4xx.h"                  // Device header

void Key_Init()
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
	
	GPIO_InitTypeDef gpio_key;
	
	gpio_key.GPIO_Mode=GPIO_Mode_IN;
	gpio_key.GPIO_OType=GPIO_OType_OD;
	gpio_key.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
	gpio_key.GPIO_PuPd=GPIO_PuPd_UP;
	gpio_key.GPIO_Speed=GPIO_High_Speed;
	
	GPIO_Init(GPIOE,&gpio_key);
}
key.h
void Key_Init(void);
main.c
#include "stm32f4xx.h"                  // Device header
#include "led.h"
#include "key.h"

int main()
{
	Led_Init();
	Key_Init();
	uint8_t key=0;
	while(1)
	{
		key= GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4);//默认高电平,按下,接地
		if(key0==1)
		{
            GPIO_WriteBit(GPIOF, GPIO_Pin_10,1);    //led高电平,灯灭
		}  
		else
		{
		    GPIO_WriteBit(GPIOF, GPIO_Pin_10,0);	//led低电平,灯亮
		}	
		
	}
}

至此,main.c代码变简洁了不少,而且代码更加易读,代码层次也更清晰。

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

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

相关文章

关于如何解决问题?代码习惯。

警钟长鸣 从师哥身上学到的东西: 关于如何解决问题? 1、沟通:有效的沟通,将问题描述清楚,让老师和师哥明白你出了什么问题,给出建议,很多时候一句良言胜过自己摸索很久 2、出现问题由浅入深地…

国标GB28181安防监控平台EasyCVR录像时间轴优化步骤

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…

Linux系统上RabbitMQ安装教程

一、安装前环境准备 Linux:CentOS 7.9 RabbitMQ Erlang 1、系统内须有C等基本工具 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c kernel-devel m4 ncurses-devel tk tc xz socat2、下载安装包 1)首先&a…

Harmony Ble蓝牙App(三)特性和属性

Ble蓝牙App(三)特性使用 前言正文一、获取属性列表二、属性提供者三、获取特性名称四、特性提供者五、加载特性六、源码 前言 在上一篇中我们完成了连接和发现服务两个动作,那么再发现服务之后要做什么呢?发现服务只是让你知道设备…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之linux存储管理(5)》(21)

《Linux操作系统原理分析之linux存储管理(5)》(21) 6 Linux存储管理6.6 Linux 物理空间管理6.6.1 Linux 物理内存空间6.6.2 物理页面的管理6.6.3 空闲页面管理——buddy 算法 6.7 内存的分配与释放6.7.1 物理内存分配的数据结构 6…

Design patterns--代理模式

设计模式之代理模式 我们使用Qt开发大型应用程序时,经常遇见大型程序启动时需要加载一些配置信息、用户末次操作信息,以及算法模型等数据时比较费时,笔者在程序启动时设计欢迎页或加载页等窗体来提示用户程序正在加载某些数据,加载…

基于SSM框架的《超市订单管理系统》Web项目开发(第五天)供应商管理,增删改查

基于SSM框架的《超市订单管理系统》Web项目开发(第五天)供应商管理,增删改查 上一次我们实现了多表关联查询,还有分页显示数据的功能。还完善了用户管理这一模块。 因此今天我们需要完成的是供应商管理模块,这一模块…

SQL自学通之表达式条件语句与运算

目录 一、目标 二、表达式条件语句 1、表达式: 2、条件 2.1、WHERE 子句 三、运算 1、数值型运算: 1.1、加法() 1.2、减法 (-) 1.3、除法(/) 1.4、乘法 (*) 1.5、取模 (%) 优先级别…

第24章:Kubernetes Helm Introduction

目录 1. Helm简介2. Helm Charts文件(.tgz)组成3. Helm核心术语:4. Helm常用命令:5. DIY简单Helm Charts参考链接 1. Helm简介 Helm用于管理Kubernetes应用程序,Helm Charts可以用于定义、安装和升级最复杂的Kubernet…

西南科技大学模拟电子技术实验七(集成运算放大器的非线性应用)预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结果,不得分,页数可根据内容调整) 预习计算内容根据运放的非线…

Android加载AnimatedImageDrawable播放gif动态图,Kotlin

Android加载AnimatedImageDrawable播放gif动态图,Kotlin import android.graphics.ImageDecoder import android.graphics.ImageDecoder.OnHeaderDecodedListener import android.graphics.drawable.AnimatedImageDrawable import android.os.Bundle import android…

SVG-椭圆弧-参数转换-计算公式-标准解读

文章目录 1.简介2.基本参数2.1.椭圆的表达2.2.参数变换2.3.注意事项 3.参考资料4.总结 1.简介 为了与其他路径段表示法保持一致, SVG 路径中的圆弧是根据曲线上的起点和终点定义的。椭圆弧的这种端点参数化。优点是它允许与其它路径一致的语法,其中所有…

Spring Security 6.x 系列(9)—— 基于过滤器链的源码分析(二)

一、前言 在本系列文章: Spring Security 6.x 系列(4)—— 基于过滤器链的源码分析(一)中着重分析了Spring Security在Spring Boot 的自动配置、 DefaultSecurityFilterChain 的构造流程、FilterChainProxy 的构造流…

深入学习锁--Synchronized各种使用方法

一、什么是synchronized 在Java当中synchronized通常是用来标记一个方法或者代码块。在Java当中被synchronized标记的代码或者方法在同一个时刻只能够有一个线程执行被synchronized修饰的方法或者代码块。因此被synchronized修饰的方法或者代码块不会出现数据竞争的情况&#x…

Spring Boot中使用Swagger

1. 启用Swagger 1.1 启用注解扫描和文档接口 直接在POM文件引入依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version> </dependency>1.2 启动swagger-u…

ARM与大模型,狭路相逢

编辑&#xff1a;阿冒 设计&#xff1a;沐由 从去年底至今&#xff0c;伴随着OpenAI旗下ChatGPT的火爆&#xff0c;一波AI大模型推动着AI应用全面进入了大模型时代。与此同时&#xff0c;随着边缘算力的提升&#xff0c;AI大模型的部署也逐渐从云端涉入到边缘。 世界对AI算力的…

黑马一站制造数仓实战1

1. 项目目标 一站制造 企业中项目开发的落地&#xff1a;代码开发 代码开发&#xff1a;SQL【DSL SQL】 SparkCore SparkSQL 数仓的一些实际应用&#xff1a;分层体系、建模实现 2. 内容目标 项目业务介绍&#xff1a;背景、需求 项目技术架构&#xff1a;选型、架构 项目环境…

Selenium 自动化高级操作与解决疑难杂症,如无法连接、使用代理等

解决 Selenium 自动化中的常见疑难杂症 这里记录一些关于 Selenium的常用操作和疑难杂症。 有一些细节的知识点就不重复介绍了&#xff0c;因为之前的文章中都有&#xff01; 如果对本文中的知识点有疑问的&#xff0c;可以先阅读我以前分享的文章&#xff01; 知识点&…

1-4、调试汇编程序

语雀原文链接 文章目录 1、执行过程第一步&#xff1a;源程序第二步&#xff1a;编译连接第三步&#xff1a;执行 2、DOSBox运行程序第1步 进入EDIT.EXE第2步 编写源程序第3步 编译第4步 连接第5步 执行完整过程 3、DEBUG跟踪执行过程加载程序到内存执行程序debug和源程序数字…

【导航控制器总结-导航控制器栈 Objective-C语言】

一、导航控制器总结 1.我们接着上一堂课的内容继续 我们上节课说到哪里了,是不是就是对这个导航控制器的一个总结啊 然后,使用的注意事项 2.导航控制器使用注意事项: 1)第一点,使用导航控制器,你在创建的时候,需要给它指定一个根控制器 创建导航控制器的同时,指定…