STM32——IO口方向

MPU 6050 的示例代码

问题:IIC 协议代码中 IO 方向代码相关解析
![[Pasted image 20230725195940.png]]

回归 STM 32 数据手册:

1 . STM 32 的 IO 口可以配置为以下 8 种模式

  • 输入浮空(floating input)
  • 输入上拉(pull-up input)
  • 输入下拉(pull-dowm input)
  • 模拟输入(analog)
  • 开漏输出(open-drain output)
  • 推挽输出(push-pull output)
  • 推挽式复用功能(alternate function open-drain)
  • 开漏复用功能(alternaate function push-pull)

2. STM 32 的每个 IO 端口都有 7 个寄存器进行控制

  • 配置模式的 2 个 32 位端口配置寄存器 CRL (IO 0-7)和 CRH (IO 8-15)

  • 2 个 32 位的数据寄存器 IDR (只读) 和 ODR(只写)

  • 1 个 32 位的置位/复位寄存器 BSRR

  • 1 个 16 位的复位寄存器 BRR

  • 1 个 32 位的锁存寄存器 LCKR
    我们常用的 IO 端口配置寄存器只有 4 个:CRL, CRH, IDR,ODR。CRH 和 CRL 控制每个 IO 口的模式及输出速率。
    官方数据手册配置表如图:
    ![[Pasted image 20230725193825.png|500]]

    STM 32 输出模式配置表如图:
    在这里插入图片描述

    STM 32 的 CRL 寄存器控制着每组 IO 端口的低八位模式。每个 IO 占用 CRL 的四个位,高两位为 CNF ,低两位为 MODE。
    端口配置低寄存器表如图:
    在这里插入图片描述

    端口配置高寄存器如图:
    在这里插入图片描述

3.代码解释

	GPIOA->CRL &= 0XFF0FFFFF; \
        GPIOA->CRL |= 8 << 20;

代码解释如下:
1. 将 GPIOA 的 CRL 寄存器(第 5 个 IO 口)的地址位(CNF[1:0], MODE 5[1:0])清零,其余位保持不变;
2. 将“8 (D)=1000 (B)“左移 20 位后写入寄存器:
![[Pasted image 20230725211258.png]]

即:SDA_IN ():
CNF 5[1:0] = 10; 上/下拉输入模式;(复位后状态)
MODE[1:0]=00; 输入模式
	SDA_OUT ():
CNF 5[1:0] = 00; 通用推挽输出模式;
MODE[1:0]=11; 输出模式,最大速度 50 MHz
### 配置STM32双向IO使用CubeMX和HAL库 #### 使用STM32CubeMX配置GPIO作为双向I/O引脚 在STM32CubeMX中,通过图形化界面简化了复杂的硬件配置过程。为了将某个GPIO配置为双向I/O引脚,需按照如下方法操作: 1. 打开STM32CubeMX并创建新项目,选择对应的MCU型号。 2. 进入Pinout & Configuration页面,找到目标引脚(例如PD0),点击进入其属性编辑窗[^1]。 对于双向I/O引脚而言,通常会选择`Input with External Pull-up/Pull-down Resistor (GPIO_INPUT)` 或者 `Output Push-Pull (GPIO_OUTPUT)`模式来实现输入输出切换的功能需求。然而更推荐的方式是在初始化阶段将其设定为推挽输出模式(`Output Push-Pull`),之后再利用软件控制改变方向。 当完成上述设置后,继续进行时钟树与时基单元TIMx等其他必要组件的选择与调整;最后生成工程文件以便后续编程处理。 #### 利用HAL库编写代码以支持动态更改引脚的方向 一旦完成了初步的硬件配置工作,则可以在应用程序层面借助于HAL库提供的API接进一步增强灵活性。下面给出一段简单的例子展示怎样实现在运行期间灵活地修改指定引脚的工作状态: ```c // 初始化部分省略... void Toggle_GPIO_Direction(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){ static uint8_t direction_flag = 0; if(direction_flag == 0){ // 设置为输入模式 HAL_GPIO_DeInit(GPIOx, GPIO_Pin); GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Configure as input */ GPIO_InitStruct.Pin = GPIO_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); direction_flag++; }else{ // 设置为输出模式 HAL_GPIO_DeInit(GPIOx, GPIO_Pin); GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Configure as output */ GPIO_InitStruct.Pin = GPIO_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); direction_flag--; } } int main(void){ // ... 初始化代码 ... while(1){ Toggle_GPIO_Direction(GPIOD, GPIO_PIN_0); HAL_Delay(1000); // 延迟一秒 // 根据当前方向执行相应读写操作... } } ``` 这段程序展示了如何周期性的反转特定引脚的操作方式——即每隔一段时间就自动在这两个极端之间来回变换一次。当然实际应用当中应当依据具体业务逻辑来进行更加精细的设计[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值