单片机课程实验指导书(6)

2019-04-14 17:42

31 3029 2827 2625 2423 2221 2019 1817 16保留15 1413 1211 10 9 8IDR9IDR8 7 6IDR7IDR65 4IDR5IDR4 3 2IDR3IDR21 0IDR1IDR0IDR15IDR14IDR13IDR12IDR11IDR10r rr r位31:16位15:0r rr rr rr rr rr r保留,始终读为0IDRy[15:0]:端口输入数据(y=0...15)(Port Input Data)这些位为只读并能以字(16位)的形式读出,读出的值为对应I/O口的状态

17 16图3.2 GPIO_IDR寄存器

31 3029 2827 2625 2423 2221 2019 18保留15 14ODR15ODR1413 12ODR13ODR1211 10ODR11ODR10 9 8 7 65 4 3 21 0ODR9ODR8ODR7ODR6ODR5ODR4ODR3ODR2ODR1ODR0r rr rr rr rr rr rr r位31:16位15:0r r保留,始终读为0ODRy[15:0]:端口输入数据(y=0...15)(Port Input Data)这些位为可读并只能以字(16位)的形式操作。

图3.3 GPIO_ODR寄存器

GPIOx_IDR是端口的输入数据寄存器,GPIOx_ODR是端口的输出寄存器。当配置引脚的输入输出模式是通过GPIOx_CRL和GPIOx_CRH两个寄存器来配置的,但是每个端口的16个引脚它们有的可能是输出模式,有的是输入模式,甚至一会输出一会输入,而GPIOx_IDR和GPIOx_ODR两个寄存器是以word模式访问而不能以bit模式访问,GPIOx_IDR只能读,而GPIOx_ODR可以读写。因此,如果输入输出公用一个寄存器,将不知道读出的数据到底应该是输入还是输出。

如果是模拟输入或者浮空输入模式,那么与GPIOx_ODR无关,如果配置成下拉输入模式,则应将GPIOx_ODR各位都设置0,如果是上拉输入模式,则GPIOx_ODR各位设置成1。在开漏输出模式下,通过读GPIOx_IDR来获取IO状态。

3)置位/复位寄存器

31 30BR15BR1429 28BR13BR1227 26BR11BR1025 24BR9BR823 22BR7BR621 20BR5BR419 18BR3BR217 16BR1BR0w w15 14BS15BS14w w13 12BS13BS12w w11 10BS11BS10w w 9 8BS9BS8w w 7 6BS7BS6w w5 4BS5BS4w w 3 2BS3BS2w w1 0BS1BS0w ww ww ww ww ww ww ww w位31:16Bry:清除端口x的 位y(y=0...15)(Port x Reset bit y) 这些位只能写入并只能以字(16位)的形式操作0:对对应的ODRy位不产生影响1:清除对应的ODRy为为0Bry:清除端口x的 位y(y=0...15)(Port x Set bit y) 这些位只能写入并只能以字(16位)的形式操作0:对对应的ODRy位不产生影响1:清除对应的ODRy为为1位15:0

图3.4 GPIO_ODR寄存器

GPIOx_BSRR和GPIOx_BRR寄存器,通过这两个寄存器可以直接对对应的GPIOx端口置'1'或置'0'。GPIOx_BSRR的高16位中每一位对应端口x的每个位,对高16位中的某位置'1'则端口x的对应位被清'0';寄存器中的位置'0',则对它对应的位不起作用。GPIOx_BSRR的低16位中每一位也对应端口x的每个位,对低16位中的某位置'1'则它对应的端口位被置'1';寄存器中的位置'0',则对它对应的端口不起作用。

简单地说GPIOx_BSRR的高16位称作清除寄存器,而GPIOx_BSRR的低16位称作设置寄存器。另一个寄存器GPIOx_BRR只有低16位有效,与GPIOx_BSRR的高16位具有相同功能。

使用BRR和BSRR寄存器可以方便地快速地实现对端口某些特定位的操作,而不影响其它位的状态。

比如希望快速地对GPIOE的位7进行翻转,则可以: GPIOE->BSRR = 0x80; GPIOE->BRR = 0x80;

// 置'1' // 置'0'

如果使用常规'读-改-写'的方法: GPIOE->ODR = GPIOE->ODR | 0x80;

// 置'1' // 置'0'

GPIOE->ODR = GPIOE->ODR & 0xFF7F;

BSRR的高16位并不是多余,假如在一个操作中对GPIOE的位7置'1',位6置'0',则使用BSRR非常方便:

GPIOE->BSRR = 0x400080;

如果没有BSRR的高16位,则要分2次操作,结果造成位7和位6的变化不同步! GPIOE->BSRR = 0x80; GPIOE->BRR = 0x40;

三、固件库函数

1)初始化函数

在固件库开发中,操作寄存器CRH和CRL来配置I/O口的模式和速度是通过GPIO初始化函数完成:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

这个函数有两个参数,第一个参数用来指定GPIO,取值范围GPIOA~GPIOG。第二个参数为初始化参数结构体指针,结构体类型为GPIO_InitTypeDef,在此可以详细了解该结构体定义,该定义在stm32f10x_gpio.h中。

typedef struct {

uint16_t GPIO_Pin;

GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; } GPIO_InitTypeDef; 配置GPIO的代码如下:

GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

// 配置端口中引脚5

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz GPIO_Init(GPIOB, &GPIO_InitStrucure);

上述代码设置GPIOB的第5个端口为推挽输出模式,同时速度为50Mbit/s。 首

GPIOB是端口GPIOB的配置寄存器编址,该编址可以在 中查到。结构体GPIO_InitStructure的第一个成员变量GPIO_Pin实际指出了需要配置的引脚在GPIOB配置寄存器中的偏移量。成员变量GPIO_Mode用来设置引脚的输入输出模式,这是通过一个枚举类型定义:

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;

2)数据输入/输出函数

A.. uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 返回输入端口某个引脚的状态.GPIOx: x (A~G). GPIO_Pin: 端口的哪个bit位需要读取 (0~15).

如GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0); 读A0的状态,返回值可能0 或 1 B.

uint16_t

GPIO_ReadInputData(GPIO_TypeDef*

GPIOx);

如GPIO_ReadInputData(GPIOA); 返回A0~A15的状态 其中 typedef struct {

__IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef;

C. uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 读GPIO某一位的输出

D. uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); //读GPIO的输出

3)位设置函数

将GPIO的某个位置位

A. void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 将GPIO的某个位复位

B. void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

四、实验设计

本实验是STM32开发最基础的实验,如图3.4所示,3个LED灯分别接GPIOD的引脚PD5、PD6、PD7,实现LED灯的闪烁功能。

图3.4 LED灯硬件连接图

完成上述功能的步骤为:

(1)使能I/O口时钟,调用函数为RCC_APB2PeriphClockCmd( ); (2)初始化I/O参数,调用函数GPIO_Init( );

(3)操作I/O,调用函数GPIO_SetBits( )和GPIO_ResetBits。

五、例程

/*

********************************************************************** * 文件:main.c

* 编辑:武汉理工大学计算机学院 * 日期:2013/12/04 * 修改: * 版本:V1.0

* 描述:UE-STM32F103开发板板载了3个LED,分别为LED1、LED和LED3 本实验将通过教你如何控制STM32的IO口配置实现这三个灯的交替闪烁 ********************************************************************** */

#include \

/*宏定义*/

#define LED_PORT GPIOD #define LED1 GPIO_Pin_5 #define LED2 GPIO_Pin_6 #define LED3 GPIO_Pin_7 /*函数声明*/

void LED_Init(void);

void delayms(int loop_times); /*

****************************************************************** * 函 数:main * 入口参数:无


单片机课程实验指导书(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:货币时间价值在财务管理实践中的应用

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: