请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F0xx之IO口控制(寄存器方式)

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
STM32F0xx的IO口定义方式与STM32F10x类似,一组GPIO包含16个IO。每组GPIO同样用GPIO_TypeDef的结构指向对应的寄存器空间。

  1. <blockquote>#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
复制代码

但是寄存器空间与STM32F10x的不同。
  1. <blockquote>typedef struct
复制代码

1. 使能GPIO的RCC
RCC->AHBENR |= RCC_AHBPeriph_GPIOn

其中n的范围为A-F。

如果涉及到复用,与STM32F10x不同,这里用寄存器AFR[2]来设定复用。每个IO用4bit来选择复用功能,最多有8种复用。

20210603162156418.png

例如GPIOA9,GPIOA10的AFR设定:

  1. *((uint32_t *)GPIOA->AFR + ((9 / 8))) &= ~(0x0000000F << ((9 % 8) * 4));
  2. *((uint32_t *)GPIOA->AFR + ((9 / 8))) |= (0x00000001 << ((9 % 8) * 4));  
  3. *((uint32_t *)GPIOA->AFR + ((10 / 8))) &= ~(0x0000000F << ((10 % 8) * 4));
  4. *((uint32_t *)GPIOA->AFR + ((10 / 8))) |= (0x00000001 << ((10 % 8) * 4));  
复制代码

2. 配置GPIO
2.1 设置输出频率(OSPEEDR)

20210603171958361.png


每2个位配置一个Pin。默认是2MHz。

0b00, 0b10: 2MHz

0b10: 10MHz

0b11: 50MHz

  1. typedef enum
  2. {
  3.   GPIO_Speed_Level_1  = 0x00, /*!< I/O output speed: Low 2 MHz */
  4.   GPIO_Speed_Level_2  = 0x01, /*!< I/O output speed: Medium 10 MHz */
  5.   GPIO_Speed_Level_3  = 0x03  /*!< I/O output speed: High 50 MHz */
  6. }GPIOSpeed_TypeDef;

  7. #define GPIO_Speed_2MHz  GPIO_Speed_Level_1   /*!< I/O output speed: Low 2 MHz  */
  8. #define GPIO_Speed_10MHz GPIO_Speed_Level_2   /*!< I/O output speed: Medium 10 MHz */
  9. #define GPIO_Speed_50MHz GPIO_Speed_Level_3   /*!< I/O output speed: High 50 MHz */
复制代码

例如A9、A10都为50MHz:

  1. GPIOA->OSPEEDR |= (0x0000000F << (9 * 2));
复制代码

2.2 配置输入输出(MODER)



每2个位配置一个Pin。 默认Input(除了SWD的A13,A14)

0b00: Input

0b01: Output

0b10: AF

0b11: Analog In/Out

  1. typedef enum
  2. {
  3.   GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode              */
  4.   GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode             */
  5.   GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
  6.   GPIO_Mode_AN   = 0x03  /*!< GPIO Analog In/Out Mode      */
  7. }GPIOMode_TypeDef;
复制代码

例如GPIOA9,GPIOA10为AF:
  1. GPIOA->MODER |= ((uint32_t)GPIO_Mode_AF << (9 * 2)) | ((uint32_t)GPIO_Mode_AF << (10 * 2));
复制代码

2.3 配置输出模式(OTYPER)

20210604084327134.png


每个bit表示输出模式,

0b0: PP模式;

0b1: OD模式。

  1. typedef enum
  2. {
  3.   GPIO_OType_PP = 0x00,
  4.   GPIO_OType_OD = 0x01
  5. }GPIOOType_TypeDef;
复制代码

例如:
  1. GPIOA->OTYPER |= (((uint32_t)GPIO_OType_PP << (9 * 1))
  2.     | ((uint32_t)GPIO_OType_PP << 10 * 1))
复制代码

2.4 配置上下拉模式(PUPDR)

20210604085305353.png


每2个位表示上下拉模式。
  1. typedef enum
  2. {
  3.   GPIO_PuPd_NOPULL = 0x00,
  4.   GPIO_PuPd_UP     = 0x01,
  5.   GPIO_PuPd_DOWN   = 0x02
  6. }GPIOPuPd_TypeDef;
复制代码

例如:
  1. GPIOA->PUPDR &= ~((0x00000003 << (9 * 2)) | (0x00000003 << (10 * 2)));
复制代码

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

  1. #define SDA_HIGH(n)                 IO_I2CIO_SDA->BSRR = ((uint32_t)1 << PIN_I2CIO_SDA)
  2. #define SDA_LOW(n)                  IO_I2CIO_SDA->BRR = ((uint32_t)1 << PIN_I2CIO_SDA)
复制代码

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

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

8bit总线输出

  1. #define I8080_D8_OUT(dat)           IO_I8080_D8->BSRR = (dat & 0xff) | ((uint32)((~dat) & 0xff) << 16)
复制代码
4. 读入IO
通过寄存器IDR读出对应I/O口的状态。低16位有效。

  1. #define SDA_READ(n)                 (IO_I2CIO_SDA->IDR & ((uint32_t)1 << PIN_I2CIO_SDA))
复制代码



20210603165224704.png
收藏 评论0 发布时间:2021-11-25 15:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版