STM32端口IO方向设置问题的IO方向设置问题

举报
果果小师弟 发表于 2021/05/29 13:28:18 2021/05/29
【摘要】 例程:STM32F103系列 I2C软件模拟实验(mini板) 问题:下面两行关于“IO方向”的代码不太明白。 //IO 方向设置 #define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;} #define SDA_OUT() {GPIOC->CRH&=0XF...

例程:STM32F103系列 I2C软件模拟实验(mini板)

问题:下面两行关于“IO方向”的代码不太明白。

//IO 方向设置
#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

  
 
  • 1
  • 2
  • 3

进过研读开发手册大概解决了这个问题。

STM32 的 IO 口可以由软件配置成如下 8 种模式:
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏复用功能

每个 IO 口可以自由编程,但 IO 口寄存器必须要按 32 位字被访问。STM32 的很多 IO 口都是 5V 兼容的,这些 IO 口在与 5V 电平的外设连接的时候很有优势,具体哪些 IO 口是 5V 兼容的,可以从该芯片的数据手册管脚描述章节查到(I/O Level 标 FT 的就是 5V 电平兼容的)。STM32 的每个 IO 端口都有 7 个寄存器来控制。他们分别是:配置模式的 2 个 32 位的端口配置寄存器 CRL 和 CRH;2 个 32 位的数据寄存器 IDR 和 ODR;1 个 32 位的置位/复位寄存器BSRR;一个 16 位的复位寄存器 BRR;1 个 32 位的锁存寄存器 LCKR;我们常用的 IO 端口寄存器只有 4 个:CRL、CRH、IDR、ODR。CRL 和 CRH 控制着每个 IO 口的模式及输出速率。
STM32 的 IO 口位配置表如表 6.1.1 所示:

STM32 输出模式配置如表 :

接下来我们看看端口低配置寄存器 CRL 的描述

STM32 的 CRL 控制着每组 IO 端口(A~G)的低 8 位的模式。每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。

换句话说我们要控制PA0,就只要这样写:

GPIOA->CRL&=0XFFFFFFF0
 
  • 1

把PA0设置为输入就要这样写:

GPIOC->CRL|=8<<0;

  
 
  • 1

合起来控制PA0为输入就是这样写:

GPIOC->CRL&=0XFFFFFFF0;GPIOC->CRL|=8<<0;

  
 
  • 1

PA0为输出

GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8<<0;

  
 
  • 1

PA1为输出

GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=8<<4;

  
 
  • 1

PA2为输出

GPIOA->CRL&=0XFFFFF0FF;GPIOA->CRL|=8<<8;

  
 
  • 1

PA3为输出

GPIOA->CRL&=0XFFFF0FFF;GPIOA->CRL|=8<<12;

  
 
  • 1

PA4为输出

GPIOA->CRL&=0XFFF0FFFF;GPIOA->CRL|=8<<16;

  
 
  • 1

PA5为输出

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

  
 
  • 1

PA6为输出

GPIOA->CRL&=0XF0FFFFFF;GPIOA->CRL|=8<<24;

  
 
  • 1

PA7为输出

GPIOA->CRL&=0X0FFFFFFF;GPIOA->CRL|=8<<28;

  
 
  • 1

同理设置为输入就是

PA0为输入

GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3<<0;

  
 
  • 1

PA1为输入

GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=3<<4;

  
 
  • 1

PA2为输入

GPIOA->CRL&=0XFFFFF0FF;GPIOA->CRL|=3<<8;

  
 
  • 1

PA3为输入

GPIOA->CRL&=0XFFFF0FFF;GPIOA->CRL|=3<<12;

  
 
  • 1

PA4为输入

GPIOA->CRL&=0XFFF0FFFF;GPIOA->CRL|=3<<16;

  
 
  • 1

PA5为输入

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

  
 
  • 1

PA6为输入

GPIOA->CRL&=0XF0FFFFFF;GPIOA->CRL|=3<<24;

  
 
  • 1

PA7为输入

GPIOA->CRL&=0X0FFFFFFF;GPIOA->CRL|=3<<28;

  
 
  • 1

PA8为输出

GPIOA->CRH&=0XFFFFFFF0;GPIOA->CRH|=8<<0;

  
 
  • 1

PA9为输出

GPIOA->CRH&=0XFFFFFF0F;GPIOA->CRH|=8<<4;

  
 
  • 1

PA10为输出

GPIOA->CRH&=0XFFFFF0FF;GPIOA->CRH|=8<<8;

  
 
  • 1

PA11为输出

GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=8<<12;

  
 
  • 1

PA12为输出

GPIOA->CRH&=0XFFF0FFFF;GPIOA->CRH|=8<<16;

  
 
  • 1

PA13为输出

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

  
 
  • 1

PA14为输出

GPIOA->CRH&=0XF0FFFFFF;GPIOA->CRH|=8<<24;

  
 
  • 1

PA15为输出

GPIOA->CRH&=0X0FFFFFFF;GPIOA->CRH|=8<<28;

  
 
  • 1

同理设置为输入就是

PA8为输入

GPIOA->CRH&=0XFFFFFF0F;GPIOA->CRH|=3<<0;

  
 
  • 1

PA9为输入

GPIOA->CRH&=0XFFFFFF0F;GPIOA->CRH|=3<<4;

  
 
  • 1

PA10为输入

GPIOA->CRH&=0XFFFFF0FF;GPIOA->CRH|=3<<8;

  
 
  • 1

PA11为输入

GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=3<<12;

  
 
  • 1

PA12为输入

GPIOA->CRH&=0XFFF0FFFF;GPIOA->CRH|=3<<16;

  
 
  • 1

PA13为输入

GPIOA->CRL&=0XFF0FFFFF;GPIOA->CRH|=3<<20;

  
 
  • 1

PA14为输入

GPIOA->CRH&=0XF0FFFFFF;GPIOA->CRH|=3<<24;

  
 
  • 1

PA15为输入

GPIOA->CRH&=0X0FFFFFFF;GPIOA->CRH|=3<<28;

  
 
  • 1

GPIOC->CRL&=0XFFFFFFF0;
GPIOx->CRL,这句话表示要操作GPIOx的低8位,就是Px0 ~ Px7,(CRL表示操作高8位,就是Px8~Px15);
所以GPIOC->CRL,这句话表示要操作GPIOC的第0位,就是PC0

后面的0XFFFFFFF0,表示操作PC0;0XFFFFFF0F,表示操作PC1;0XFFFFF0FF,表示操作PC2;0XFFFF0FFF,表示操作PC3;0XFFF0FFFF,表示操作PC4;0XFF0FFFFF,表示操作PC5;0XF0FFFFFF,表示操作PC3;0X0FFFFFFF,表示操作PC7;合起来的意思就是:利用“与”运算,把这个位清0,同时不影响其他的位的设置。

GPIOC->CRL|=8<<0;
意思就是将1000左移0位(不移位),然后再与GPIOC->CRL进行“或”运算。再根据原子的寄存器开发手册可以知道CNF0[10]、MODEO[00],对应的就是设置为上拉/输入模式。

文章来源: blog.csdn.net,作者:果果小师弟,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_39400113/article/details/112070047

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。