1 实验目的
1
)熟悉
KEIL
开发软件的应用;
2
)掌握
STM32F429ZG
对
IO
的输出控制方法。
2 实验准备
实验硬件: | 实验箱、PC 机 |
实验软件: | PC 机操作系统 Windows 11 +KEIL -MDK 开发环境 |
3 实验原理
3.1 LED 介绍
LED
是一种能发光的半导体电子元件。它是半导体二极管的一种,可以把电能转化成光能。发光二极管与普通二极管一样是由一个 PN
结组成,也具有单向导电性。
当给发光二极管加上正向电压后,从
P
区注入到
N
区的空穴和由
N
区注入到
P
区的电子,在
PN
结附近数微米内复合,产生自发辐射的荧光。不同的半导体材料中电子和空穴所处的能量状态
不同。电子和空穴复合时释放出的能量越多,则发出的光的波长越短。常用的是发红光、绿光或黄
光的二极管。光线的波长、颜色跟其所采用的半导体材料种类与掺入的元素杂质有关。磷砷化镓二
极管发红光,磷化镓二极管发绿光,碳化硅二极管发黄光。具有效率高、寿命长、不易破损、开关
速度高、高可靠性等传统光源不及的优点。
3.2 LED 硬件接口电路
模块上的灯使用的是
STM32
的
PB0.1.2.3
口,当对应的端口输出高电平时灯关闭,当对应的端
口输出低电平时,灯被点亮。
图3.1 GPIO LED
3.3 STM32 的 IO 口介绍
实验的关键在于如何控制
STM32
的
IO
口输出。通过本实验的学习,将初步掌握
STM32
基本
IO
口的使用。
STM32
的
IO
口相比
51
而言要复杂得多,所以使用起来也困难很多。首先
STM32
的
IO
口可以由软件配置成如下 8
种模式:
1
、输入浮空
2
、输入上拉
3
、输入下拉
4
、模拟输入
5
、开漏输出
6
、推挽输出
7
、推挽式复用功能
8
、开漏复用功能
每个
IO
口可以自由编程,但
IO
口寄存器必须要按
32
位字被访问。
STM32
的很多
IO
口都是
5V
兼容的,这些
IO
口在与
5V
电平的外设连接的时候很有优势,具体哪些
IO
口是
5V
兼容的,可以从该芯片的数据手册管脚描述章节查到(I/O Level
标
FT
的就是
5V
电平兼容的)。
STM32
的每个
IO
端口都有
7
个寄存器来控制。他们分别是:配置模式的
2
个
32
位的端口配置
寄存器
CRL
和
CRH
;
2
个
32
位的数据寄存器
IDR
和
ODR
;
1
个
32
位的置位
/
复位寄存器
BSRR
;一个 16
位的复位寄存器
BRR
;
1
个
32
位的锁存寄存器
LCKR。
3.4 GPIO 相关的函数和定义
GPIO
相关的函数和定义分布在
HAL
库文件
stm32l4xx_hal_gpio.c
和头文件
stm32l4xx_hal_gpio.h
文件中。 在
HAL
库开发中,操作寄存器
CRH
和
CRL
来配置
IO
口的模式和速度是通过
GPIO
初始化函数完成:
void HAL_GPIO_Init (GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
这个函数有两个参数,第一个参数是用来指定 GPIO,取值范围为 GPIOA~GPIOG。第二个参数为初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef。这个结构体的定义:
typedef struct
{
uint32_t Pin;
uint32_t Mode;
uint32_t Pull;
uint32_t Speed;
uint32_t Alternate;
}GPIO_InitTypeDef;
下面我们通过一个
GPIO
初始化实例来讲解这个结构体的成员变量的含义。
通过初始化结构体初始化
GPIO
的常用格式是:
/*Configure GPIO pin : PB5 */
GPIO_InitStruct.Pin = GPIO_PIN_5; // 引脚号
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL; //无上拉/下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; //低速
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); //设置 PB 端口
上面代码的意思是设置 GPIOB 的第 5 个端口为推挽输出模式,同时速度为低速 5M。从上面初始化代码可以看出,结构体 GPIO_InitStructure 的第一个成员变量 Pin 用来设置是要初始化哪个或者 哪些 IO 口;第二个成员变量 Mode 是用来设置对应 IO 端口的输出输入模式,这些模式是上面我们讲解的 8 个模式,在 MDK 中是通过一个枚举类型定义的
#define GPIO_MODE_INPUT (0x00000000u) /*!< Input Floating Mode */
#define GPIO_MODE_OUTPUT_PP (0x00000001u) /*!< Output Push Pull Mode */
#define GPIO_MODE_OUTPUT_OD (0x00000011u) /*!< Output Open Drain Mode */
#define GPIO_MODE_AF_PP (0x00000002u) /*!< Alternate Function Push Pull Mode */
#define GPIO_MODE_AF_OD (0x00000012u) /*!< Alternate Function Open Drain Mode */
#define GPIO_MODE_ANALOG (0x00000003u) /*!< Analog Mode */
#define GPIO_MODE_ANALOG_ADC_CONTROL (0x0000000Bu) /*!< Analog Mode for ADC
conversion */
……
第三个参数是 IO 口速度设置,有三个可选值,在 MDK 中同样是通过枚举类型定义
#define GPIO_SPEED_FREQ_LOW (0x00000000u) /*!< range up to 5 MHz, please refer to the
product
datasheet */- 45 -
#define GPIO_SPEED_FREQ_MEDIUM (0x00000001u) /*!< range 5 MHz to 25 MHz, please refer to
the product datasheet */
#define GPIO_SPEED_FREQ_HIGH (0x00000002u) /*!< range 25 MHz to 50 MHz, please refer to
the product datasheet */
#define GPIO_SPEED_FREQ_VERY_HIGH (0x00000003u) /*!< range 50 MHz to 80 MHz, please refer
to the product datasheet */
要想知道某个 IO 口的电平状态,你只要读这个寄存器,再看某个位的状态就可以了。使用起 来是比较简单的。 在固件库中操作 IDR 寄存器读取 IO 端口数据是通过 HAL_GPIO_ReadPin 函数实现的:
GPIO_PinState HAL_GPIO_ReadPin (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
比如要读 GPIOB.5 的电平状态,那么方法是:
GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5);
返回值是
1(GPIO_PIN_SET)
或者
0(GPIO_PIN_RESET);
在固件库中设置
ODR
寄存器的值来控制
IO
口的输出状态是通过函数
GPIO_Write 来实现的:
GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5);
比如通过 GPIOB.5 的输出高低电平状态,那么方法是:
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
IO
操作步骤很简单,这里我们做个概括性的总结,操作步骤为:
1
) 使能
IO
口时钟。调用函数为
__HAL_RCC_GPIOB_CLK_ENABLE();
。
2
) 初始化
IO
参数。调用函数
HAL_GPIO_Init();
3
) 操作
IO
4 代码分析
主函数中通过
HAL_GPIO_WritePin
函数实现对
LED
灯的点亮和熄灭控制操作,并且在间隔加入时间延时
。
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// 熄灭 LED
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0|
GPIO_PIN_1
|GPIO_PIN_2
|GPIO_PIN_3,GPIO_PIN_SET);
HAL_Delay(1000);
//点亮 LED
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0| GPIO_PIN_1 |GPIO_PIN_2
|GPIO_PIN_3,GPIO_PIN_RESET);
HAL_Delay(1000);
}
5 实验步骤
1)
复制建立的
test
工程文件夹,将文件夹名称修改为
LED
。
(注:该步骤请查看之前内容:Stm32 应用开发基本流程(RVMDK 工程新建))
2)
通过
STM32CubeMX
软件打开工程目录下的
test.ioc
文件。
3)
在
“Pinout View”
界面下,找到
PB0.1.2.3
依次点击设置其为
GPIO_Output
功能;
4)
修改
GPIO-PB0.1.2.3
口默认初始设置,这里默认
IO
高电平、输出、上拉使
LED
熄灭;
5)
修改完后再点击
“Generate Code”
重新获取工程文件,并打开工程;
6)
我们在工程
User->main.c
的
main
函数中添加对
LED
等的控制代码;
7)
右击工程名称弹出菜单栏,使用
“Build Target”
编译工程。
8)
使用
ST-Link
仿真器连接实验模块
Jtag
接口和实验电脑。注意,
Jtag
调试接口旁的切换开
关拨到左侧(下载
STM32
)。
9)
可以通过
Keil
在线调试,或者下载到模块后按下复位按钮重启模块。(注意模块断电前要
先拔掉仿真器)
6 实验结果
下载
HEX
程序后
.
可以看到
Led
灯在不停闪烁。