STM32F10x之IO口控制(寄存器方式)

目录

1. 使能GPIO的RCC

2.  定义使用的GPIO组和PIN

3.  配置IO

4. 输出电平

5. 读入IO

 


STM32F10x的IO口分组,GPIOA,GPIOB,GPIOC等,每组IO最多16个 。STM32的库已经定义好了一个GPIO的寄存器组

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;

每组GPIO 直接将GPIO首地址转为这组结构指针。

#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)

下面介绍一个GPIO初始化和使用的过程 

1. 使能GPIO的RCC

RCC->APB2ENR |= RCC_APB2Periph_GPIOn

其中n的范围为A-G,另外如果是复用的IO,则需要使能RCC_APB2Periph_AFIO。例如要使能GPIOA和AFIO,则代码如下:

RCC->APB2ENR |= RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA;

2.  定义使用的GPIO组和PIN

为了更快速的修改GPIO组和PIN,将使用到的GPIO组和PIN用宏定义定义好。例如I2C IO方式,将SDA和SCL的IO定义为:

#define IO_I2CIO_SDA                    GPIOA
#define PIN_I2CIO_SDA                   7

#define IO_I2CIO_SCL                    GPIOA
#define PIN_I2CIO_SCL                   5

即SDA用的是GPIOA7,SCL用的是GPIOA5.

3.  配置IO

GPIO用CRL和CRH配置IO的属性,CRL对应GPIO的低8位IO,CRH对应GPIO的高8位IO。每个IO用4bit数据来设置属性。

以I2C的SDA设置为例

#define SDA_SetOut(n)               {\
        *((uint32_t *)&(IO_I2CIO_SDA->CRL) + ((PIN_I2CIO_SDA / 8)))) &= ~(0x0000000F << ((PIN_I2CIO_SDA % 8) * 4)); \
        *((uint32_t *)&(IO_I2CIO_SDA->CRL) + ((PIN_I2CIO_SDA / 8))) |= (0x00000007 << ((PIN_I2CIO_SDA % 8) * 4)); \
        }

&(IO_I2CIO_SDA->CRL)是获取CRL的地址,如果PIN_I2CIO_SDA为8-15(即GPIOA的高8位IO),则(&(IO_I2CIO_SDA->CRL) + ((PIN_I2CIO_SDA > 7) * 4))对应&(IO_I2CIO_SDA->CRH)。

((PIN_I2CIO_SDA % 8) * 4)表示对应的4位配置,这4位配置含义如下:

配置表:

MODE[1:0]用于设置输入输出模式,0x00表示输入,0x01-0x11表示输出。输入时如果需要设置为上下拉输入,则需要设置ODR为0(下拉)或1(上拉),使用BSRR或BRR输出0或1即可以实现上下拉的设置。例如设置GPIOA10为IPU:

GPIOA->CRH &= ~(0x000000FF << ((9 % 8) * 4));
GPIOA->CRH |= (0x0000008B << ((9 % 8) * 4));
GPIOA->BSRR = ((uint32_t)1 << 10); //Input with pull high

CRL和CRH的复位值为0x4,即IO口默认是浮空输入。

4. 输出电平

输出电平通过寄存器BSRR(输出高电平和低电平)和BRR(输出低电平)实现,写入1表示对应操作,写入0无效。例如:

#define SDA_HIGH(n)                 IO_I2CIO_SDA->BSRR = ((uint32_t)1 << PIN_I2CIO_SDA) 
#define SDA_LOW(n)                  IO_I2CIO_SDA->BRR = ((uint32_t)1 << PIN_I2CIO_SDA) 

 BSRR的低16位分别对应16个PIN的输出高电平操作,高16为对应输出低电平操作。

而BRR只有低16位有效,对应对应输出低电平操作。

8bit总线输出

#define I8080_D8_OUT(dat)           IO_I8080_D8->BSRR = (dat & 0xff) | ((uint32)((~dat) & 0xff) << 16)

5. 读入IO

通过寄存器IDR读出对应I/O口的状态。低16位有效。

#define SDA_READ(n)                 (IO_I2CIO_SDA->IDR & ((uint32_t)1 << PIN_I2CIO_SDA))

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值