STM32学习笔记(1) GPIO初始化及点亮LED

简介: 在这一段代码中,假设同时有A.h和B.h同时包含了这个头文件,在编译器编译A时,会先判断LED.H有没有被定义(这里肯定是未被定义的),那么就定义(define __LED_H),然后再(endif),在编译器编译B时,同样会判断LED.H有没有被定义(这里经过A的编译,肯定是被定义的),那么就直接(endif)。这样,就可以防止重复编译。

一、led.h头文件分析


#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2
void LED_Init(void);//初始化
#endif


问:ifndef,endif有什么用?


在这一段代码中,假设同时有A.h和B.h同时包含了这个头文件,在编译器编译A时,会先判断LED.H有没有被定义(这里肯定是未被定义的),那么就定义(define __LED_H),然后再(endif),在编译器编译B时,同样会判断LED.H有没有被定义(这里经过A的编译,肯定是被定义的),那么就直接(endif)。这样,就可以防止重复编译。


二、Led_Init()函数分析


APB2 外设时钟使能寄存器(RCC_APB2ENR)


80ed0b4dc3214f2cb5b6bc7adcef9118.png


由图易知,外部时钟寄存器的2~8位是对应相关的GPIO,当我们想要使用该GPIO时,必须打开时钟(clock),这样,各种寄存器,上、下升沿触发器,锁存器才会工作。


void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
/**作用:开启APB2外部时钟使能
  *1st参数:外部时钟的寄存器
  *@arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11
  *2st:ENABLE or DISABLE (是否使能)
  */


然后,我们要定义一个结构体,因为我们需要配置GPIO端口的各种参数。而这个结构体,在库函数中可以找到


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 */
  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;


我们来分析一下这个结构体


typedef:

在C语言中,用户可以用typedef这个关键字,来自定义自己常用的数据类型名称。


我们可以看一下有无typedef时定义结构体有什么不同


(1)没有typedef,传统定义一个结构


struct Student
{
   int no;
   char name[12];
};


1.


声明结构体:struct Student stu1;


(2)用typedef定义一个结构体


typedef struct Student
{
   int no;
   char name[12];
}Stu,student;


声明结构体:Stu stu1; | student stu2;


(3)如果这里用了typedef,也可以不需要Student


typedef struct
{
   int no;
   char name[12];
}Stu;


声明结构体:Stu student1;


在上面中,先定义一个结构体,里面包含(GPIO_Pin,GPIO_Speed,GPIO_Mode)三个参数,然后再把这个结构体typedef为GPIO_InitTypeDef


然后,就可以配置这三个结构体变量


GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;


GPIO_Pin_8是宏定义了一个寄存器


GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置推挽输出


设置电平输出方式


端口模式的配置有上拉,下拉,模拟,浮空输入;推挽,开漏,复用输出


输入


1.上拉输入:把不确定的信号电位强制拉高到VCC


2.下拉输入:把电压拉低到GND


3.浮空输入:逻辑器件,不接任何电压,例:按键,RX


4.模拟输入:输入0/1的数字信号,然后转化为模拟信号,例:ADC,低功耗下省电


输出


1.推挽输出:可以输出0/1


2.开漏输出:可输出0,若需要输出1需要接一个上拉电阻


3.复用输出:当IO口不作为通用IO口时使用,常配合其它输出使用例如:各种通信方式,PWM


4.复用+推挽输出:I2C的SCL,SDA


5.复用+开漏输出:TX


 GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//速度越快,功耗越高


设置输出速度,如果是输入的话可以直接忽略。速度越快,功耗越高


最后,再调用外设初始化函数,把配置好的结构体写到相应的寄存器中


GPIO_Init(GPIOA,&GPIO_InitStruct);
//void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
/**作用:将结构体成员写入寄存器当中
  *1st参数:GPIO端口,即GPIOx (x=A ...G)
  *2st参数:结构体的指针
  */


这样,我们的GPIO配置就完成了


在main函数当中,可以调用Reset来点亮LED


GPIO_ResetBits(GPIOA,GPIO_Pin_8);


可以调用Set灭灯


GPIO_SetBits(GPIOA,GPIO_Pin_8);


三、代码示例


相关程序代码放在这里了,程序移植性较高:


STM32代码句句解析:点亮一个LED

相关文章
|
1月前
stm32学习 3-2 LED流水灯
stm32学习 3-2 LED流水灯
69 4
|
1月前
stm32学习3-1 LED闪烁
stm32学习3-1 LED闪烁
35 4
|
4月前
STM32CubeMX FreeRTOS点亮LED
STM32CubeMX FreeRTOS点亮LED
78 10
|
4月前
STM32CubeMX 按键控制LED
STM32CubeMX 按键控制LED
71 0
|
4月前
STM32CubeMX 点亮LED
STM32CubeMX 点亮LED
62 0
|
5月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
446 2
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
715 0
|
6月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结
|
5月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
509 4