STM32端口IO方向设置问题的

例程: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;}

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

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 口位配置表如表所示:

STM32 输出模式配置如表 :

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

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

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

GPIOA->CRL&=0XFFFFFFF0//GPIOA->CRL=GPIOA->CRL & 0b1111 1111 1111 1111 1111 1111 1111 0000;

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

GPIOA->CRL|=8<<0;
//GPIOA->CRL=GPIOA->CRL|(0b1000)<<0;

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

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

PA0为输入(上/下拉)

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

PA1为输入(上/下拉)

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

PA2为输入(上/下拉)

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

PA3为输入(上/下拉)

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

PA4为输入(上/下拉)

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

PA5为输入(上/下拉)

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

PA6为输入(上/下拉)

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

PA7为输入(上/下拉)

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

同理设置为输出就是

PA0为输出(通用推挽输出50MHZ)

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

PA1为输出(通用推挽输出50MHZ)

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

PA2为输出(通用推挽输出50MHZ)

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

PA3为输出(通用推挽输出50MHZ)

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

PA4为输出(通用推挽输出50MHZ)

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

PA5为输出(通用推挽输出50MHZ)

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

PA6为输出(通用推挽输出50MHZ)

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

PA7为输出(通用推挽输出50MHZ)

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

PA8为输入(上/下拉)

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

PA9为输入(上/下拉)

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

PA10为输入(上/下拉)

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

PA11为输入(上/下拉)

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

PA12为输入(上/下拉)

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

PA13为输入(上/下拉)

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

PA14为输入(上/下拉)

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

PA15为输入(上/下拉)

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

同理设置为输出就是

PA8为输出(通用推挽输出50MHZ)

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

PA9为输出(通用推挽输出50MHZ)

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

PA10为输出(通用推挽输出50MHZ)

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

PA11为输出(通用推挽输出50MHZ)

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

PA12为输出(通用推挽输出50MHZ)

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

PA13为输出(通用推挽输出50MHZ)

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

PA14为输出(通用推挽输出50MHZ)

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

PA15为输出(通用推挽输出50MHZ)

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

GPIOC->CRL&=0XFFFFFFF0;

GPIOx->CRL,这句话表示要操作GPIOx的低8位,就是Px0 ~ Px7
GPIOx->CRH,这句话表示要操作GPIOx的高8位,就是Px8 ~ Px15

所以GPIOC->CRL,这句话表示要操作GPIOC,

后面的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],对应的就是设置为上拉/输入模式。

  • 103
    点赞
  • 467
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
引用: #define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;} 。 引用: 使用蒙特卡洛算法解算炼油厂的选址MATLAB程序,提供试题照片,以及MATLAB代码 ... while x(1)>82 | x(1)| x(2)>81 | x(2)| x %再次生成随机数 x(1)=82*rand; % x(2)=(1-0.9397)*rand 0.9397; end;。 引用: 顺便说一下,以前有说把python降到3.5版本的,我长时间用3.7和3.8,都没有问题,今天突然报错,反而很奇怪。又搜索了一下,网上有详细介绍兼容性安装的,内容如下,有时间大家可以自己去搜索对比一下,以避免冲突。 对于你的问题,| - > 和 | = > 分别是两种不同的符号表示方法。 - | - > 是C语言中的位移运算符,表示将一个数的二进制位向左或向右移动指定的位数。 - | = > 是MATLAB中的逻辑运算符,表示逻辑或的含义,用于判断条件是否成立。 所以,| - > 在C语言中用于位移运算,而 | = > 在MATLAB中用于逻辑判断。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=(u32)8;(学习笔记)](https://blog.csdn.net/m0_71548440/article/details/125894236)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [使用蒙特卡洛算法解算炼油厂的选址MATLAB程序,提供试题照片,以及MATLAB代码](https://download.csdn.net/download/li171049/88270068)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [anaconda安装opencv -> python[version=‘>=2.7,|>=3.5,|>=3.6,|>=3.7,‘]](https://blog.csdn.net/tanmx219/article/details/123398451)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

果果小师弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值