要使得LED被点亮,根据LED的性质来说,肯定是要通过控制高低电平的输出,进而控制LED的亮灭。而要控制电平就是要控制IO的输出电平,对此我们需要对IO口进行设置。GPIO中有很多中模式,但对于其他模式,我们需要用的时候再去了解,对此我们目前只需要实现点灯这个功能就好了,也就是目前掌握控制GPIO高低电平输出就可以了。
有关GPIO的库函数在‘stm32f10x_gpio.h,stm32f10x_gpio.c’之中。
我们先看一下硬件需要做些什么,在工程中也是如此,我们想好了要什么功能之后我们就要对硬件进行设计,要考虑清楚实现功能的硬件条件
这个开发板上直接将PD2与LED1连接,PA8与LED0进行连接。
根据这个二极管的电平我们可以知道,我们要输出低电平就能够使得LED点亮,对此我们接下来就是对GPIO的软件设置进行讲解。
我们可以打开‘stm32f10x_gpio.h,stm32f10x_gpio.c’中去进行查看。在这个.c文件中是GPIO中的一些对于寄存器编程的封装函数我们并不需要全部掌握。最好的方法就是直接查看.h文件中的关于函数的声明,去阅读其中的函数,在这里如果我们英文水平可以看懂这些函数的意义那么对于我们日后的学习和工作来说会简单许多,其实就像是直接阅读工具的使用说明书一样,我们需要用什么就可以去进行使用。对应的函数如下,
对于stm32来讲,使用任何一个功能都要对其中的内部功能进行初始化,即激活该模块,比如我们现在要使用IO口我们就需要对GPIO进行一个初始化。
这里我们找到其中函数,在351行中有一个函数。
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
我们要对这个函数进行初始化设置,其中这个函数中一些参量我们需要了解其中含义。
GPIO_TypeDef* GPIOx ——其中GPIO_TypeDef* 是一个结构体其中具体内容我们不需要进行掌握,是一些GPIO寄存器的封装,而我们只需要关注GPIOx这个的含义是我们对哪一个GPIO进行配置,其中的X我们进行设置,在这里我们可以设置为“A or B or C or D”具体的使用我们后面用到的时候再进行讲述。
GPIO_InitTypeDef* GPIO_InitStruct——其中GPIO_InitTypeDef*是我们需要重点关注的,它是对于我们想要功能的结构体设置(设置如下代码),而GPIO_InitStruct是我们自己定义的一个结构体。
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define “那个引脚”*/
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef “GPIO的速度是多少” */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef “工作在什么模式”*/
}GPIO_InitTypeDef;
在stm32中的结构体主要是用枚举型的我们在.h文件中都可以进行查找到这里我们可以使用快捷键“ctrl+f”进行搜索,搜索如下
我们根据需要在其中选择我们需要的参数进行设置,不要自己去改变其中的内容,不然会出错
这里就是C语言函数基本逻辑的运用,其实简单的嵌入式就是简单的函数调用设置+一些逻辑功能+一些算法进行实现的。
上面我们讲解了该函数的作用,函数当中的一些参量都是由我们自己自行的设置,所以我们要在一开始进行定义变量,然后我们在初始化前面要先将我们想要的功能进行设置。相关的代码与讲解如下
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PB端口时钟,这个是一个时钟使能函数,就像是一个开关我们需要打开后才能使用
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //这里在初始化的时候设置为高电平是为了先让LED灯处于不亮的状态
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //同理可以知道该函数是设置低电平——让LED亮
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); //这个函数是我们每次都要用到的,同样我们找到这个函数看一下
uint32_t RCC_APB1Periph——我们后期需要用到什么模块,我们就是要打开这个开关对应的模块,上面的@arg 列举了我们后期要使用到的模块,到后面我们遇到了我们再进行使用就好了。
FunctionalState NewState——对应的只有两种状态 “ENABLE or DISABLE”,打开或关闭。
我们将上述配置过程的代码放在了LED.c文件中,这样模块化的编程会使得更加便利
在主函数设置就可以实现我们所要的功能
两个LED交替闪烁