资料:STM32F4XX中文参考手册—(7通用IO口/7.4GPIO寄存器)

问题描述:

我们在STM32F407关于IIC通讯实验例程中发现了一串看不懂的代码,代码所在文价夹是myiic.h ,代码如下所示:

可以看到,后边的~(3<<(9*2)),不知道什么意思。

我们就拿#define SDA_IN() { GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2为例子。

如果理解了它,下边的代码#define SDA_OUT()....的代码,同理也能理解。

思考过程:

看到MODER,知道查看STM32F4XX中文参考手册,看第7章 通用IO口/7.4节 GPIO寄存器,如下图1所示:

图1

GPIO 端口模式寄存器,那这个寄存器就是MODER9,他控制的是18,19位;哪个上述文件夹的这个代码可以理解为A&=~(3<<(9*2));就是3<<(9*2)取反后和原来得A值与运算再赋值给A,按照优先级的算术过程如下:

  1. 先算(9*2)
  2. 再算(3<<(9*2)) ,
  3. 接着对(3<<(9*2))取反
  4. 第3.部得出来的值再和A进行&运算
  5. 最后把第4.部算出来得值赋值给A,就是最后结果。

因此对GPIOB->MODER&=~(3<<(9*2))这个代码得理解是:

原来得GPIOB->MODER得值跟~(3<<(9*2))与运算后,再赋值给GPIOB->MODER ,就是这个意思。

软件调试:(帮助理解)

我们不知道这个GPIOB->MODER原来的值,因此要下载程序,烧入板子,才能看到。

进入到Debug调试界面看它原来的值,然后我们可以验证下,这个原来的值是烧入板子调试之后,才能出现值。这个要进入Debug,view中点击watch1小窗口,然后复制GPIOB->MODER,粘贴到watch1里面,可以看到原来的值,然后设置断点进入程序里,看他运算之后MODER的值。

如下图2所示,我们用快捷键ctrl+F搜索全局变量,就是搜索SDA_IN的全局变量,上边Find in Files,点击Find All,这样看它调试过程。

图2

搜索全局变量之后,就能看到如下图3所示的,

图3

如上图3所示,在最下边窗口蓝色标注的出现了它的相应文件夹,就是myiic.c文件夹,点击下边的就能快速进入文件夹的SDA_IN所在位置了。

这里因为对GPIOB->MODER进行了两次运算,然后我们为了方便观察,把SDA_IN替换成GPIOB->MODER&=~(3MODER|=0,并在调试之前就在这两串代码前设置断点,等会儿调试进去看下变化。如下图4所示。

图4

如上图所示,可以看到进入到第一个断点时,GPIOB->MODER的值为0x40050280,这就是执行前的值,GPIOB->MODER原来的值是0x40050280。

图5

如上图5所示,又执行到下一个断点处,可以看到watch1窗口处,执行后的结果GPIOB->MODER的值为0x40010280.

我们验证下与运算后结果是否一样,如下图所示,在调试页面,直接选中它就能出现~(3<<(9*2))的值,它的值为0xFFF3FFFF。

同样的也可以看到与运算后的GPIOB->MODER的结果,与运算后GPIOB>MODER=0x40010280,

计算:

GPIOB->MODER&=~(3<<(9*2))

=0x40050280&(0xFFF3FFFF)=0x40010280

结果正确。

原来的GPIOB->MODER的值为0x40050280,跟~(3<<(9*2))进行与运算后变成0x40010280,可以看到5变成了1,就是0101——0001,对照中文参考手册发现是位18变成0.

1、然后为什么是3左移呢?

答:(1)3就是11,11左移(9*2)=18位,可以看中文参考手册数是原来11在0位和1位位置,左移数到18位,对应的是18.19位,所以此时18位,19位对应的就是11 ——(3<<(9*2)))的结果。

(2)然后取反就是18.19位变成00,00与运算任何数都是00,所以GPIOB->MODER&=~(3<<(9*2))的结果就是18,19位还是0,即把目标位清0.

2、接下来说GPIOB->MODER|=1

答:(1)1就是01,01左移(9*2)=18位,可以看中文参考手册数是原来01对应的是1位,0位置,左移数到18位,对应的是18.19位,所以此时18位,19位对应的就是01 ——(1<<(9*2))的结果

(2)然后01与任何数或运算就是那个数本身,所以本身是GPIOB->MODER值为0x40010280,从右往左数是1,0001,一个数对应4位,起始位为0,因此对应的19,18位是00,就是输入模式

//IO方向模式设置 这里第一步是将目标位设置为00,第二步才是设置(即设置新的值,让其为什么模式)

#define SDA_IN() { GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<(9*2) ;} //PB9输入模式

#define SDA_OUT() { GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<(9*2);}  //PB9输出模式

//3是11,11移动到控制GPIO的位置,取反,设为00,最后与不影响其他位,所以巧妙地把那两位设置成了00,输入模式

//后面那个,1是01,最后将GPIO位设置为了01,通用输出模式

STM32F4X寄存器的代码详解—SDA_IN,相关推荐

  1. 寄存器(1)寄存器概念,x86寄存器种类说明及汇编代码详解

    寄存器(1)寄存器概念,x86寄存器种类说明及汇编代码详解 1. 什么是寄存器 1.1 概念 1. 什么是寄存器: 2. 寄存器作用: 1.2 通俗易懂理解寄存器 2. x86寄存器种类说明及汇编代码 ...

  2. 寄存器(3)KDB入门+MIPS汇编及汇编代码详解

    KDB入门和MIPS汇编 1. KDB 介绍及进入退出命令 1.1 KDB 介绍 1.2 进入KDB及退出KDB 2. KDB 调试 2.1 断点类 2.2 内存操作类 md 2.3 堆栈跟踪类 2. ...

  3. uboot copy_from_nand代码详解

    uboot copy_from_nand代码详解 copy_from_nand函数简介: 函数将会把nand flash中的uboot二进制程序镜像拷贝到内存中,通常这一步出现问题,uboot是不可能 ...

  4. 异步FIFO设计:各个模块的作用及Verilog代码详解

    实现原理参考:异步FIFO---Verilog实现_alangaixiaoxiao的博客-CSDN博客_异步fifo 代码参考:IC基础(一):异步FIFO_MaoChuangAn的博客-CSDN博客 ...

  5. 204B实战应用-LMK04821代码详解(二)

    204B实战应用-LMK04821代码详解(二) 一. SPI协议 通过阅读LMK04821数据手册,我们可以从中知道,可以通过SPI协议对LMK04821进行寄存器的配置工作,进而实现我们设计所需要 ...

  6. FPGA项目开发:204B实战应用-LMK04821代码详解(二)

    大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注FPGA技术江湖,在"闯荡江湖"."行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢. ...

  7. 基于RK3399ESP8285自动售货柜项目—MP08开发板端代码详解

    基于RK3399&ESP8285自动售货柜项目-②MP08开发板端代码详解 本系列文章将详细讲解该基于RK3399及ESP8285自动售货柜的完整实现方法,从硬件连接到网络通信再到软件实现,本 ...

  8. STM32-串口通信波特率计算以及寄存器的配置详解

    串口通信基本原理 处理器与外部设备通信的两种方式 并行通信 传输原理:数据各个位同时传输. 优点:速度快 缺点:占用引脚资源多 串行通信 传输原理:数据按位顺序传输 优点:占用引脚资源少 缺点:速度相 ...

  9. 51单片机串口通信发送以及接收代码详解1

    #include <reg51.h> //实验现象:单片接收电脑发送的字符串,并发回给PC端的代码.//函数声明 void uart_init(void); void uart_seng_ ...

最新文章

  1. python 判断字符串是否全部为数字组成(使用isdigit)
  2. VMware 虚拟化编程(12) — VixDiskLib Sample 程序使用
  3. Streaming Big Data: Storm, Spark and Samza--转载
  4. mysql 更改数据库编码_更改MySQL数据库的编码为utf8mb4
  5. 超过一半的受访者表示愿意升级到Windows 11
  6. cudaMemcpy2D介绍
  7. 《数据库SQL实战》查找所有员工的last_name和first_name以及对应的dept_name
  8. numpy安装失败-小失误
  9. 前端学习(1316):静态资源
  10. chrome用type=file获取图片路径并转base64字符串
  11. 2019年下半年《软件评测师》上午试卷及答案
  12. 2017云栖大会:阿里巴巴宣布成立达摩院
  13. 高并发面试 - 如何设计一个高并发系统?
  14. 力扣题目——98. 验证二叉搜索树
  15. ubuntu 12.04陷入software center的searching/cancelling...
  16. Atitit..文件上传组件选型and最佳实践总结(2)----断点续传
  17. shell 数组及 十六进制转换报错
  18. 汽车之家论坛字体反爬
  19. 微信开发者工具预览二维码无法显示
  20. Flutter学习指南:UI布局和控件,作为Android开发者

热门文章

  1. Python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序
  2. 研发效能笔记1:研发效能误区
  3. Android启动页白屏背景图拉伸的解决方案
  4. Overleaf_LaTex (2)
  5. 性能监控(一)-Jprofiler安装与使用
  6. 英特尔Optane DC Persistent Memory操作模式说明
  7. 校园网欠费,连wifi直接上网的方法
  8. diamond报错:Database was built with a different .../Imcompatible database version
  9. 携手中国联通丨美格智能成为中国联通物联网产业联盟苏州分联盟副理事长单位
  10. 智能视频识别技术的发展现状