当前位置:文档之家› 第5章 跑马灯实验

第5章 跑马灯实验


硬件设计 本章用到的硬件只有 LED( DS0 和 DS1)。其电路在 STM32 开发 板上默认是已经连接好了的。 DS0 接 PB5, DS1 接 PE5。所以在 硬件上不需要动任何东西。
软件设计 跑马灯实验我们主要用到的固件库文件是: stm32f10x_gpio.c /stm32f10x_gpio.h stm32f10x_rcc.c/stm32f10x_rcc.h misc.c/ misc.h stm32f10x_usart /stm32f10x_usart.h 其中 stm32f10x_rcc.h 头文件在每个实验中都要引入,因为系统时 钟配置函数以及相关的外设时钟使能函数都在这个其源文件 stm32f10x_rcc.c 中。 stm32f10x_usart.h 和 misc.h 头文件在我们 SYSTEM 文件夹中都需要使用到,所以每个实验都会引用。
第三个参数是 IO 口速度设置, 有三个可选值,在 MDK 中同样是 通过枚举类型定义: typedef enum { GPIO_Speed_10MHz = 1, GPIO_Speed_2MHz, GPIO_Speed_50MHz }GPIOSpeed_TypeDef;
IDR 是一个端口输入数据寄存器,只用了低 16 位。该寄存器为只 读寄存器,并且只能以16 位的形式读出。该寄存器各位的描述如 图 所示:
BRR 寄存器是端口位清除寄存器。该寄存器的作用跟 BSRR 的高 16 位雷同,这里就不做详细讲解。
在 STM32 固件库中, 通过 BSRR 和 BRR 寄存器设置 GPIO 端口输 出是通过函数GPIO_SetBits()和函数 GPIO_ResetBits()来完成的。
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 在多数情况下,我们都是采用这两个函数来设置 GPIO 端口的输 入和输出状态。 比如我们要设置 GPIOB.5 输出 1,那么方法为: GPIO_SetBits(GPIOB, GPIO_Pin_5);
② 组 CORE 下面存放的是固件库必须的核心文件和启动文件。这 里面的文件用户不需要修改. ③ 组 SYSTEM 是 ALIENTEK 提供的共用代码. ④ 组 HARDWARE 下面存放的是每个实验的外设驱动代码,他的 实现是通过调用 FWLib下面的固件库文件实现的,比如 led.c 里面 调用 stm32f10x_gpio.c 里面的函数对 led 进行初始化,这里面的函 数是讲解的重点。 后面的实验中可以看到会引入多个源文件。 ⑤ 组 USER 下面存放的主要是用户代码。但是 system_stm32f10x.c 文件用户不需要修改,同时 stm32f10x_it.c 里面存放的是中断服务 函数, Main.c 函数主要存放的是主函数了,这个大家应该很清楚。
ODR 是一个端口输出数据寄存器,也只用了低 16 位。该寄存器为 可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出 状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。 该寄存器的各位描述如图 所示:
Hale Waihona Puke 在固件库中设置 ODR 寄存器的值来控制 IO 口的输出状态是通过 函数 GPIO_Write 实现: void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); 该函数一般用来往一次性一个 GPIO 的多个端口设值。
要想知道某个 IO 口的电平状态,你只要读这个寄存器,再看某个 位的状态就可以了。使用起来是比较简单的。 在固件库中操作 IDR 寄存器读取 IO 端口数据是通过 GPIO_ReadInputDataBit 函数实现的: uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 比如我要读 GPIOA.5 的电平状态,那么方法是: GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5); 返回值是 1(Bit_SET)或者 0(Bit_RESET);
STM32 的 IO 口相比 51 而言要复杂得多,所以使用起来也困难很多。 首先 STM32 的 IO 口可以由软件配置成如下 8 种模式: 1、 输入浮空 2、 输入上拉 3、 输入下拉 4、 模拟输入 5、 开漏输出 6、 推挽输出 7、 推挽式复用功能 8、 开漏复用功能 每个 IO 口可以自由编程, 但 IO 口寄存器必须要按 32 位字被访问。 STM32 的很多 IO 口都是 5V 兼容的,这些 IO 口在与 5V 电平的外设 连接的时候很有优势.
在固件库开发中, 操作寄存器 CRH 和 CRL 来配置 IO 口的模式和 速度是通过 GPIO 初始化函数完成: void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); 这个函数有两个参数, 第一个参数是用来指定 GPIO,取值范围 为 GPIOA~GPIOG。 第二个参数为初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef。下面我们看看这个结构体的定义。 首先我们 打开我们光盘的跑马灯实验,然后找到 FWLib 组下面的 stm32f10x_gpio.c文件,定位到 GPIO_Init 函数体处, 双击入口参 数类型 GPIO_InitTypeDef 后右键选择“Go todefinition of…” 可以 查看结构体的定义: typedef struct { uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; }GPIO_InitTypeDef;
反之如果要设置 GPIOB.5 输出位 0,方法为:
GPIO_ResetBits (GPIOB, GPIO_Pin_5);
GPIO 相关的函数我们先讲解到这里。 虽然 IO 操作步骤很简单, 这里我们还是做个概括性的总结,操作步骤为:
1) 使能 IO 口时钟。调用函数为 RCC_APB2PeriphClockCmd()。 2) 初始化 IO 参数。调用函数 GPIO_Init(); 3) 操作 IO。操作 IO 的方法就是上面我们讲解的方法。
该寄存器的复位值为 0X4444 4444,复位值其实就是配置端口为 浮空输入模式。
STM32 的 CRL 控制着每组 IO 端口( A~G)的低 8 位的模式。 每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。这里我们可以记住几个常用的配置,比如 0X0 表示模拟 输入模式( ADC 用)、 0X3 表示推挽输出模式(做输出口用, 50M 速率)、 0X8 表示上/下拉输入模式(做输入口用)、 0XB 表示复用输出(使用 IO 口的第二功能, 50M 速率)。CRH 的作 用和 CRL 完全一样,只是 CRL 控制的是低 8 位输出口,而 CRH 控 制的是高 8位输出口。
typedef enum { GPIO_Mode_AIN = 0x0, //模拟输入 GPIO_Mode_IN_FLOATING = 0x04, //浮空输入 GPIO_Mode_IPD = 0x28, //下拉输入 GPIO_Mode_IPU = 0x48, //上拉输入 GPIO_Mode_Out_OD = 0x14, //开漏输出 GPIO_Mode_Out_PP = 0x10, //通用推挽输出 GPIO_Mode_AF_OD = 0x1C, //复用开漏输出 GPIO_Mode_AF_PP = 0x18 //复用推挽 } GPIOMode_TypeDef;
stm32f10x_gpio.c 源文件下面 include 了好几个头文件,其中有一 个 stm32f10x_conf.h,这个文件会被每个固件库源文件引用。
从图中可以看出, 在头文件 stm32f10x_conf.h 文件中,我们包含 了四个.h 头文件,那是因为我们的 FWLib 组下面引入了相应的 4 个.c 源文件。 同时大家记住,后面三个源文件 stm32f10x_rcc.c,stm32f10x_usart.c 以及 misc.c 在每个实验基本都 要添加。在这个实验中,因为 LED 是关系到 STM32 的 GPIO,所 以我们增加了 stm32f10x_gpio.c 和头文件 stm32f10x_gpio.h的引入。 添加和删除固件库源文件的步骤是: 1. 在 stm32f10x_conf.h 文件引入需要的 .h 头文件。 这些头文件在 每个实验的目录\STM32F10x_FWLib\inc 下面都有存放。 2. 在 FWLib 下面加入步骤一中引入的.h 头文件对应的源文件。记 住最好一一对应,否则就有可能会报错。 这些源文件在每个实验 的\STM32F10x_FWLib\src 目录下面都有存放.
BSRR 寄存器是端口位设置/清除寄存器。 该寄存器和 ODR 寄存器 具有类似的作用,都可以用来设置 GPIO 端口的输出位是 1 还是 0。 下面我们看看该寄存器的描述如下图:
该寄存器通过举例子可以很清楚了解它的使用方法。 例如你要设 置 GPIOA 的第 1 个端口值为 1,那么你只需要往寄存器 BSRR 的低 16 位对应位写 1 即可: GPIOA->BSRR=1<<1; 如果你要设置 GPIOA 的第 1 个端口值为 0, 你只需要往寄存器高 16 位对应为写 1 即可: GPIOA->BSRR=1<<(16+1) 该寄存器往相应位写 0 是无影响的,所以我们要设置某些位,我 们不用管其他位的值。
跑马灯实验
1, STM32 IO 口简介 2, 硬件设计 3, 软件设计 4, 仿真与下载
库函数实现
相关主题