如何使用GPIOB7引脚和GPIOD11引脚控制引脚两盏LED的相关配置的初始化程序? STM32的

相信大部分查找GPIO的人,都是刚剛接触STM32的人而刚接触STM32的人,大部分是从51上来的人所以我会由浅入深,从51和STM32的区别入手通过对比这两个处理器的配置方法,来跟大家慢慢讲解(学知识可不能急于求成)博主以stm32f1为主控芯片,以下均简称为stm32

首先,上一张我的理解图(画不好。但能看),给个形象嘚概念

stm32的时钟是由内部或外部振荡器产生的“频率”而被人们形象的称为“系统时钟”。最大为72MHz换成周期T为:1/72MHz≈13.9ns

因为耗电量stm32功能强大,能做很多事但与之同时带来的消耗也越严重,当stm32不引入时钟时钟的话就像51一样外设全开,如果大家是使用电池的话就会感到电量嘚珍贵(开机几分钟就没电了。。)所以厂家(st公司)为了解决这个问题,引入了“时钟概念”即使用哪个外设就给哪个外设时钟(频率),不使用的就关掉(不震荡)此做法大大降低了功耗,续航持久

1、 什么是片内外设?

我来个比喻吧stm32是一个工厂,内部CPU是老板而外设就是帮助CPU干活的工人。老板(CPU)想做某件事于是就命令(指令)有这个能力的工人(外设)去做这件事,并给予研究经费(時钟频率)工人拿了经费,就按照老板的命令来执行工作这就是CPU和外设的关系(不可逆关系。。)

另外片内外设也可以等同于一塊内部芯片,它有内部寄存器CPU给出指令,片内外设得到指令并配置其内部寄存器,以达到功能的实现

外设的功能都是完全不同的,泹是初始化都是大同小异学会了GPIO这最简单的外设初始化,那么后面就很好办了点灯是所有学单片机的人都应该学会的第一项技能,这樣子才算入门51单片机的点灯是,通过控制引脚寄存器将片外引脚(我们称之为IO口)拉低拉高输出高低电平,以控制引脚LED亮灭

51过程是這样子:单片机给指令->控制引脚寄存器->给IO口电平->控制引脚LED亮灭

而stm32的点灯则是,通过使能外设GPIO时钟发出指令给外设GPIO,外设GPIO收到指令后着掱配置自己的寄存器,然后给IO口模式让其实现各种功能(我说过STM32功能强大吧?IO口的配置也是有很多知识的之后会介绍)。

stm32过程是这样孓(参照上图):CPU给指令->GPIO收到指令->配置内部寄存器->配置IO口模式(注意是模式)->控制引脚LED亮灭

1、首先必须先使能时钟,时钟总线可参考:Φ文参考手册P28页这一页是时钟总线上挂载的片内外设,我就不上图了时钟使能函数在官方库函数的对应头文件里有,比如找RCC函数则应該在“stm32f10x_rcc.h”里(拉到最后面void开头的那些函数)
2、定义初始化结构体结构体是外设的初始化参数
3、初始化结构体中的参数复制并粘贴结構体然后按“.”这个符号,会出来个框框内就是外设的参数。

3、调用外设初始化函数初始化函数也是在官方库函数的对应头文件里。仳如找GPIO函数则应该在“stm32f10x_gpio.h”里符号“&”是取地址符,意思是:初始化的参数地址为。(然后MDK就寻找结构体的位置,以找到结构体的参數)

4、初始化完成后,在主函数中调用初始化函数再调用官方库函数,即可进行相应的操作(调用的官方库函数说明,请在“STM32固件庫使用手册”中查看博主不多作说明)

首先呢,初始化函数都可以在“STM32固件库使用手册”中查到使用说明(我就不提供连接了);其佽,点击函数并右键会出现“go to definition of'函数名'”(或者按F12),接着画面会跳转到官方库的 .c 文件那里有很详细的说明(说明中标明有哪些函数需偠配置),还有可以自定义库函数,具体我后面(可能会写)网上有攻略写得比我好。

flag(今后会更新的,正文是大概框架): 1、GPIO寄存器简单介紹及配置

}
要点亮LED需要完成LED的驱动, 在工程模板上新建一个led.c和led.h文件将其存放在led文件夹内。这两个文件需要我们自己编写
通常xxx.c文件用于存放编写的驱动程序,xxx.h文件用于存放xxx.c内的stm32頭文件、管脚定义、全局变量声明、函数声明等内容
因此在led.c文件内编写如下代码:

GPIO_Pin_0),LED_PORT定义的是LED的端口(如GPIOC)这样定义宏的好处是有效提高了程序的移植性,即使后续需要换其他端口只需简单修改这几个宏就可以完成对LED的控制引脚。


在 led.h 文件内编写如下代码:

LED_Init()函数就是對LED所接端口的初始化是按照GPIO初始化步骤完成,这些内容在“寄存器点亮一个LED”章节中有介绍嵌入式学习加意义气呜呜吧久零就易,下媔我们主要看库函数是如何实现GPIO初始化的


在库函数中实现 GPIO 的初始化函数是:

这个函数具体有什么功能以及函数形参的意义,我们可以通過库函数帮助文档来查阅GPIO_Init函数内有两个形参,第一个形参是GPIO_TypeDef类型的指针变量而GPIO_TypeDef是一个结构体类型,封装了GPIO外设的所有寄存器所以给咜传送GPIO外设基地址即可通过指针操作寄存器内容,第一个参数值可以为GPIOA、GPIOB、...GPIOG等其实这些就是封装好的GPIO外设基地址,在stm32f10x.h文件中可以找到苐二个形参是GPIO_InitTypeDef类型的指针变量,而GPIO_InitTypeDef也是一个结构体类型里面封装了GPIO外设的寄存器配置成员。我们初始化GPIO其实就是对这个结构体配置。


洳果想快速查看代码或参数可以用鼠标点击要查找的函数或者参数然后右键鼠标选择“Go To Definition Of ...”即可进入所要查找的函数或参数内。
查找函数內变量类型也是同样的方法但是如果发现此方法查找不出内容,那可能就是你所查找的东西在 KEIL5 软件认为是不正确的
在 LED 初始化函数中最開始调用的一个函数是:

此函数功能是使能GPIOC外设时钟, 在STM32中要操作外设必须将其外设时钟使能否则即使其他的内容都配置好,也是徒劳無功因为GPIO外设是挂接在APB2总线上,所以是对APB2总线时钟进行使能函数内有两个参数,一个是用来选择外设时钟一个是用来选择使能还是夨能,使能:ENABLE失能:DSIABLE。


在LED初始化函数内最后还调用了GPIO_SetBits(LED_PORT,LED_PIN)函数此函数功能是让GPIOC端口的第0-7个引脚输出高电平,让LED处于熄灭状态如果要对同┅端口的多个引脚输出高电平,可以使用“|”运算符相应的在对结构体初始化配置时管脚设置那里也要使用“|”将管脚添加进去,即在led.h攵件内对LED引脚的定义(前提条件是:要操作的多个引脚必须是配置同一种工作模式)例如:

其实从函数名我们大致就可以知道函数的功能。函数内有两个参数一个是端口的选择,一个是端口管脚的选择如果要输出低电平的话可以使用如下库函数:

这个函数功能和GPIO_SetBits是相反的,一个输出低电平一个输出高电平,里面参数功能是一样的


GPIO输出函数还有好几个,例如:

功能:设置端口管脚输出电平这两个函数很少使用。


从 GPIO 内部结构可知STM32 的 GPIO 还可以读取输入或输出引脚电平状态。其函数如下:

功能:读取端口中的某个管脚输入电平底层是通过读取 IDR 寄存器。

功能:读取某组端口的输入电平底层是通过读取 IDR 寄存器。

功能:读取端口中的某个管脚输出电平底层是通过读取 ODR 寄存器。

功能:读取某组端口的输出电平底层是通过读取 ODR 寄存器。


在 led.h 文件中可以看到使用了一个定义头文件的结构代码如下:

它的功能昰防止头文件被重复包含,避免引起编译错误在头文件的开头,使用“#ifndef”关键字判断标号“ _led_H”是否被定义,若没有被定义则从“#ifndef”臸“ #endif”关键字之间的内容都有效,也就是说这个头文件若被其它文件“ #include”,它就会被包含到其该文件中且头文件中紧接着使用“#define”关鍵字定义上面判断的标号“_led_H”。当这个头文件被同一个文件第二次“#include”包含的时候由于有了第一次包含中的“ #define _led_H”定义,这时再判断“#ifndef _led_H”判断的结果就是假了,从“#ifndef”至“#endif”之间的内容都无效从而防止了同一个头文件被包含多次,编译时就不会出现“redefine(重复定义)”的錯误了


一般来说,我们不会直接在C的源文件写两个“#include”来包含同一个头文件但可能因为头文件内部的包含导致重复,这种代码主要是避免这样的问题如“led.h”文件中调用了#include “stm32f10x.h”头文件,可能我们写主程序的时候会在 main 文件开始处调用#include“stm32f10x.h”和“led.h”这个时候“stm32f10x.h”文件就被包含两次了,如果在头文件中没有这种机制编译器就会报错。
}


我用如上代码将上面的四个引脚設置成下拉输入可是为什么当我调用GPIO_ReadInputDataBit()读取引脚输入值的时候,在没有输入的情况下这四个引脚有的是1,有的是0改成上拉输入和浮空輸入都一样,请问这是怎么回事谢谢!

}

我要回帖

更多关于 控制引脚 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信