文章目录
- 前言
- GPIO的工作模式
- 一、有哪些工作模式?
- 1.1 GPIO的详细介绍
- 1.2 GPIO的内部框图
- 输入模式
- 输出部分
- 二、操作GPIO点亮led
- 2.1 初始化gpio
- 2.2 写gpio
- 三、示例代码
- 总结
前言
本文将介绍如何在MM32F3270火龙果微控制器上使用Keil开发环境点亮LED。MM32F3270火龙果是一款功能强大的微控制器,具有丰富的外设和性能,适用于各种应用场景。LED点亮是嵌入式系统开发中的基础任务之一,通过本文的指导,读者将学习如何在MM32F3270上配置GPIO,并控制其输出状态以点亮LED。
GPIO的工作模式
GPIO是"General Purpose Input/Output"(通用输入/输出)的缩写。它是现代微控制器(MCU)或嵌入式系统中的一种重要接口,用于连接外部设备和传感器。每个GPIO引脚可以被配置为输入或输出,并且可以通过软件控制其电平状态。
GPIO就是我们开发板上的针脚
以下内容引用自我的博客GPIO
一、有哪些工作模式?
1.1 GPIO的详细介绍
GPIO是General-purpose and alternate-function I/Os的缩写
他的含义是:通用和复用的引脚
GPIO是分组的,每一组有很多引脚
比如说PA0、PA1…PA15,一组GPIO有16个引脚
组数是由芯片决定的,具体的组数可以看对应的芯片的原理图
1.2 GPIO的内部框图
我们可以在芯片手册中找到GPIO的对应框图,他说对于某一个引脚的:
他可以分为两部分,上部分就是输入,下部分就是输出
输入模式
输入模式的框图如下:
要理解他,我们可以看下面的图:
我们通过配置pin1让他为输入,然后我们读某个寄存器就可以得到他的状态。
当k1按下,接到电源,那么pin肯定状态是1高电平,如果没有按下,相当于这个引脚是悬空状态
那么你读这个值,你知道他是什么状态吗,可能读出来是1,可以是0
再比如,我们配置pin2让他为输入,和上面一样,我们也去读,按下时为0,那么没有按下是什么状态呢,就和上面的是一样的了
那么我们怎么解决他这个问题呢
对于pin1我们可以加一个下拉电阻
那么他按下时就就会是高电平,没按就是低电平
同样的对于pin2,就需要加上拉电阻了
那么他按下时就就会是低电平,没按就是高电平
所以上下拉电阻是需要看实际的情况来选择的。
这些电阻集成到了芯片,我们可以直接设置他,是上拉还是下拉,我们就不用每一个都搞一个电阻了
回到框图:
其中,里面的VDD为上拉电阻
Vss为下拉电阻,他在芯片中已经设计好的了
还有一种输入就是 Analog Input
,模拟输入,那么模拟输入的话,他需要得到具体的电压值,所以我们不能设置上下拉电阻,完全由外部电路控制,要不然模拟输入和直接输入没两样了
那么输入就是这几部分:上拉输入、下拉输入、浮空输入、模拟输入
在最后我们通过读取输入寄存器:Input data register
,得到1/0
如果说他有毛刺怎么办:他会在某一个范围电压内为1,某一个电压范围为0
输出部分
他这个GPIO可以接到一个灯,或者其他的芯片
如果是点灯,那么电压肯定是越高越好
如果是关灯,电压肯定是越低越好
当输出1时,I/O pin连接到P-MOS的VDD,然后就能点灯了
如果输出0,P-MOS断开,连接地,所以就关灯
推挽输出:当你要高电平,就推到VDD,如果要低电平,就推到VSS这样就是推挽输出,可以输出高低电平
开漏输出:
在开漏输出中,有两种状态:开和关。当开漏输出为开启状态时,它会将电路连接到地(或负极),使得电路的输出变为低电平。而当开漏输出为关闭状态时,它不会连接到任何地方,使得电路的输出由外部设备或其他电路来控制。
开漏输出一般是用来解决两个芯片通信的问题的
不至于把两个芯片搞坏
二、操作GPIO点亮led
2.1 初始化gpio
声明init结构体:GPIO_Init_Type gpio_init;
设置结构体成员:
在结构体中,里面有这些成员:
typedef struct
{uint16_t Pins; /*!< GPIO operating pins. */GPIO_Speed_Type Speed; /*!< GPIO pin speed mode. */GPIO_PinMode_Type PinMode; /*!< GPIO pin input / output functional mode. */
} GPIO_Init_Type;
这是一个结构体GPIO_Init_Type
,用于配置GPIO引脚的初始化参数。让我们逐个介绍其成员的含义:
-
uint16_t Pins
:这是一个16位的参数,用于指定操作的GPIO引脚。通常情况下,会使用GPIO_PIN_x(x为引脚号)的宏来表示具体的引脚。如果需要操作多个引脚,可以使用按位或(|)的方式将多个宏组合在一起。 -
GPIO_Speed_Type Speed
:这是一个枚举类型的参数,用于指定GPIO引脚的速度模式。枚举类型GPIO_Speed_Type
定义了不同的速度模式,比如GPIO_Speed_10MHz
表示10MHz的速度模式、GPIO_Speed_50MHz
表示50MHz的速度模式等。
typedef enum
{GPIO_Speed_50MHz = 1u, /*!< Maximum speed is 50MHz. */GPIO_Speed_20MHz = 2u, /*!< Maximum speed is 20MHz. */GPIO_Speed_10MHz = 3u, /*!< Maximum speed is 10MHz. */
} GPIO_Speed_Type;
GPIO_PinMode_Type PinMode
:这是一个枚举类型的参数,用于指定GPIO引脚的功能模式,即输入模式还是输出模式。枚举类型GPIO_PinMode_Type
定义了不同的功能模式,包括输入模式(GPIO_PinMode_Input)、推挽输出模式(GPIO_PinMode_Out_PushPull)、开漏输出模式(GPIO_PinMode_Out_OD)等。
/*!
* @brief Port input / output mode.
*/
typedef enum
{GPIO_PinMode_In_Analog = 0x00u, /*!< Analog input. */GPIO_PinMode_In_Floating = 0x04u, /*!< Floating input. */GPIO_PinMode_In_PullDown = 0x28u, /*!< Pull down input. */GPIO_PinMode_In_PullUp = 0x48u, /*!< Pull up input. */GPIO_PinMode_Out_OpenDrain = 0x14u, /*!< Universal open drain output. */GPIO_PinMode_Out_PushPull = 0x10u, /*!< Universal push-pull output. */GPIO_PinMode_AF_OpenDrain = 0x1Cu, /*!< Multiplex open drain output. */GPIO_PinMode_AF_PushPull = 0x18u, /*!< Multiplexed push-pull output. */
} GPIO_PinMode_Type;
结构体GPIO_Init_Type
的作用就是用于配置GPIO引脚的初始化参数,其中Pins
成员用于指定操作的GPIO引脚,Speed
成员用于指定引脚的速度模式,PinMode
成员用于指定引脚的功能模式。
使能一组gpio:
void RCC_EnableAHB1Periphs(uint32_t ahb1_periphs, bool enable)
这个函数RCC_EnableAHB1Periphs
是用来控制使能或禁用连接到AHB1总线上的外设时钟的函数。让我们来详细介绍一下它的参数含义:
uint32_t ahb1_periphs
:这是一个32位的参数,用来指定要操作的外设。在函数内部,会根据传入的参数来设置相应的位,从而实现对特定外设时钟的使能或禁用。通常,使用预定义的宏来表示要操作的外设,比如RCC_AHB1_PERIPH_GPIOA
表示GPIOA外设、RCC_AHB1_PERIPH_DMA1
表示DMA1外设等。通过按位或(|)的方式可以同时使能多个外设。
他有这些取值:
#define RCC_AHB1_PERIPH_GPIOA (1u << 0u) /*!< AHB1 peripheral GPIOA clock 0 bit. */
#define RCC_AHB1_PERIPH_GPIOB (1u << 1u) /*!< AHB1 peripheral GPIOB clock 1 bit. */
#define RCC_AHB1_PERIPH_GPIOC (1u << 2u) /*!< AHB1 peripheral GPIOC clock 2 bit. */
#define RCC_AHB1_PERIPH_GPIOD (1u << 3u) /*!< AHB1 peripheral GPIOD clock 3 bit. */
#define RCC_AHB1_PERIPH_GPIOE (1u << 4u) /*!< AHB1 peripheral GPIOE clock 4 bit. */
#define RCC_AHB1_PERIPH_GPIOF (1u << 5u) /*!< AHB1 peripheral GPIOF clock 5 bit. */
#define RCC_AHB1_PERIPH_GPIOG (1u << 6u) /*!< AHB1 peripheral GPIOG clock 6 bit. */
#define RCC_AHB1_PERIPH_GPIOH (1u << 7u) /*!< AHB1 peripheral GPIOH clock 7 bit. */
#define RCC_AHB1_PERIPH_SDIO (1u << 10u) /*!< AHB1 peripheral SDIO clock 10 bit. */
#define RCC_AHB1_PERIPH_CRC (1u << 12u) /*!< AHB1 peripheral CRC clock 12 bit. */
#define RCC_AHB1_PERIPH_FLASH (1u << 13u) /*!< AHB1 peripheral FLASH clock 13 bit. */
#define RCC_AHB1_PERIPH_SRAM (1u << 14u) /*!< AHB1 peripheral SRAM clock 14 bit. */
#define RCC_AHB1_PERIPH_DMA1 (1u << 21u) /*!< AHB1 peripheral DMA1 clock 21 bit. */
#define RCC_AHB1_PERIPH_DMA2 (1u << 22u) /*!< AHB1 peripheral DMA2 clock 22 bit. */
#define RCC_AHB1_PERIPH_ETHMAC (1u << 25u) /*!< AHB1 peripheral ETHMAC clock 25 bit. */
bool enable
:这是一个布尔类型的参数,用来指定是使能(true)还是禁用(false)所选外设的时钟。当enable为true时,函数会将相应外设的时钟使能;当enable为false时,函数会将相应外设的时钟禁用。
初始化gpio:
void GPIO_Init(GPIO_Type * GPIOx, GPIO_Init_Type * init);
-
GPIO_Type *GPIOx
:这是一个指向GPIO_TypeDef类型结构体的指针,用于指定要初始化的GPIO端口。在MM32F3270系列的芯片中,GPIO_TypeDef结构体定义了每个GPIO端口的寄存器映射,用于控制对应端口的操作。比如,如果要初始化GPIOA端口,则将此参数设置为GPIOA
,如果要初始化GPIOB端口,则将此参数设置为GPIOB
,依此类推。 -
GPIO_Init_Type *init
:这是一个指向GPIO_Init_Type结构体的指针,用于指定GPIO引脚的初始化参数。GPIO_Init_Type结构体定义了如何配置GPIO引脚的初始化参数,包括要操作的引脚、引脚的速度模式以及功能模式等。
2.2 写gpio
我们可以使用下面这个函数写gpio的高低电平:
void GPIO_WriteBit(GPIO_Type * GPIOx, uint16_t pins, uint16_t val);
-
GPIO_Type *GPIOx
:这是一个指向GPIO_TypeDef类型结构体的指针,用于指定要操作的GPIO端口。在MM32F3270系列的芯片中,GPIO_TypeDef结构体定义了每个GPIO端口的寄存器映射,用于控制对应端口的操作。例如,如果要操作GPIOA端口,则将此参数设置为GPIOA
,如果要操作GPIOB端口,则将此参数设置为GPIOB
,以此类推。 -
uint16_t pins
:这是一个16位的参数,用于指定要设置状态的GPIO引脚。通常情况下,会使用GPIO_PIN_x(x为引脚号)的宏来表示具体的引脚。如果需要操作多个引脚,可以使用按位或(|)的方式将多个宏组合在一起。 -
uint16_t val
:这是一个16位的参数,用于指定要设置的输出状态值。在MM32F3270系列中,GPIO引脚的输出状态可以是逻辑高电平(1)或逻辑低电平(0)。因此,可以将此参数设置为GPIO_PIN_SET
表示设置为逻辑高电平,或者设置为GPIO_PIN_RESET
表示设置为逻辑低电平。
三、示例代码
#include "mm32f327xx.h" // 包含MM32F3270芯片的头文件// 定义LED引脚所在的GPIO端口和引脚号
#define LED_PIN GPIO_PIN_0
#define LED_PORT GPIOAint main() {// 使能GPIOA端口的时钟RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOA, true);// 配置LED引脚为推挽输出模式GPIO_Init_Type gpio_init;gpio_init.Pins = LED_PIN;gpio_init.Speed = GPIO_Speed_50MHz;gpio_init.PinMode = GPIO_PinMode_Out_PushPull;GPIO_Init(LED_PORT, &gpio_init);while (1) {// 点亮LEDGPIO_WriteBit(LED_PORT, LED_PIN, GPIO_PIN_SET);HAL_Delay(100);// 熄灭LEDGPIO_WriteBit(LED_PORT, LED_PIN, GPIO_PIN_RESET);HAL_Delay(100);}return 0;
}
总结
通过本文的介绍,我们学习了如何在MM32F3270火龙果微控制器上使用Keil开发环境点亮LED。首先,我们详细介绍了MM32F3270微控制器的基本特性和外设。接着,我们讲解了如何在Keil中创建一个新的工程,并配置GPIO以控制LED的引脚。然后,我们编写了简单的代码,通过设置GPIO的输出状态来控制LED的亮灭。最后,我们进行了代码的编译、下载和调试,并验证了LED的点亮效果。通过本文的学习,读者将掌握在MM32F3270火龙果微控制器上点亮LED的基本方法,为后续的应用开发打下基础。