【stm32】物理内存地址如何与指针对应上

.

.

1 C语言基础----- * 与 & 运算符以及强制类型转换

1 &是取地址符号

我们的变量都是存放在物理内存上的,每一个变量定义的时候就被分配了地址,要想知道变量的地址可以用取地址运算符 & ,如取变量 a 的地址 &a 。

&a 的运算结果是a的地址,即&a执行完之后返回一个地址,这个地址的数据类型是指针,即返回的数值并不是一个简单的整数,而是一个unsigned int*类型的,对于这个类型的理解在下面有讲。

2 *是寻址运算符

当我们知道了一个变量的地址之后,即知道了变量的指针之后,想要找到变量对应存放的内存单元,就需要运用 * 来寻址,如*(变量a的地址)

*(变量a的地址)的结果是直接连通物理内存与软件

即你可以读取变量a的值,b=*(变量a的地址),读取a变量内存单元的数据,即读取a的值,然后赋值给b

你也可以将b的值写入a的内存单元,*(变量a的地址)=b;将b的数据赋值到a的内存单元中,即将b的值赋值给a。

3 强制类型转换

将一个数据的类型强制转换成另一种类型

语法:(需要转换的类型)(被转换的数据)

如,将小数转换成int类型的数:(int)(3.14)

2 内存与指针对应

1 操作寄存器 

我们知道想要用软件控制硬件外设,中间必须通过寄存器,软件控制寄存器,寄存器再控制硬件外设。

在stm32中外设的寄存器是专门放在一个特定的内存块当中的,块的起始地址是0x4000 0000

如果想要控制某个外设,就必须操作对应的寄存器,查看参考手册可以知道寄存器的地址,比如为0x4000 0000,那么如何通过软件去写入数据呢?

我们用到*(unsiged int*)(0x40000000)

2 *(unsiged int*)(0x40000000)解读

1 0x40000000是整形

首先,我们要明确的是,0x4000 0000是一个十六进制的整形数据,并不是一个指针,不可以用*进行寻址。

2 unsiged int* 是一个指向unsiged int数据类型的指针

*代表这是一个指针类型,unsiged int代表该指针指向的物理内存中存放的数据是unsiged int类型的。

为什么要有unsiged int呢

假设有一系列连续的房子,每一间房子都有一个编号,并且编号的连续的

当你们家只有一间房子的时候,房号就是你们家的地址

但是当你们家有好几间房子的时候,如果把所有房号都记下来就很麻烦了,所以我们采用第一间房子房号与房间数的方法记,即只要知道你们家第一间房的房号和你们有多少间房就可以知道哪些房子是你们的了(假设你们的房子的房间号连续)。

指针也一样,指针代表的是变量的首地址,但是变量都占有很多个内存单元,因此在首地址的信息的基础上加上变量占用内存单元的大小的信息就可以准确知道变量的所有内存单元了,而这个占用内存单元大小的信息就用unsiged int等等的数据类型标识符来标记。

3 (unsiged int*)(0x40000000)是强制类型转换

我们知道0x40000000是一个十六进制的整形,整形是不可以寻址的,即虽然你知道寄存器的地址的数值,但是你无法通过寻址操作来找到对应的内存。

因此我们需要将整形强制转换成指针。

4 unsiged int是多长

在不同的单片机中,unsiged int的长度是不同的,他的长度是由单片机的位数来决定的,在stm32中,unsiged int的长度是32位,即4个字节。

5 为什么是转换成 unsiged int

首先我们明确为什么是unsigned(无符号),unsigned是无符号的意思,就是说没有负数。

unsigned int 的类型是指针指向的内存单元存放的数据的类型,我们知道这里寄存器操作指向的内存单元就是寄存器,而寄存器的数据是每一位的数值都是有特定的意义的,实际上这里的数据类型你可以定义成任何数据类型,只要长度是32位进行了,即int也行,但是定义成int的话,假设寄存器是8位的,如果你要往寄存器中写1000 0001的二进制数据,那么由于int是有符号的,内存中最高位代表符号位,写入的是正数,因此最高位是0,最后写入的是0000 0001,因为数据位只有7位,写入8位的数据会溢出,导致丢失最高位。所以为了方便准确控制和写入寄存器数据,将寄存器的数据定义成无符号的,即写入什么就是什么。

为什么长度是int

指针指向的数据类型的长度代表着一个地址代表多长的内存单元,由于这里的内存单元代表这外设的寄存器,因此所定义的数据类型的长度必须等于一个寄存器占用的内存单元的长度。在stm32中,外设的寄存器的长度都是32位的,因此指针的类型也是32位的。

6  *(unsiged int*)(0x40000000)是寻址

*(unsiged int*)(0x40000000)是找到对应的内存单元,用于写入数据或者读出数据。

3 总结

软件与硬件内存之间是通过指针操作来实现的,在单片机中指针具有更清晰的物理意义,了解指针的物理意义(对应内存的什么),掌握指针的运算是操作内存/.寄存器的基本要求。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@枭白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值