原创 Easyarm113学习之存储访问

2011-8-1 19:38 2262 6 6 分类: MCU/ 嵌入式

  Zlgeasyarm1138使用了lm3s1138作为主芯片。LM3S1138以cortex-m3为内核,和STM32类似。这里只关注cortex-m3的存储器系统。


下面是cortex-m3的存储空间分布图。


Cortex-m3对所有的地址空间使用统一编址的方式,即都可由存储映射访问。而不像8086那样内存空间和IO空间分离。


     9eb2892d-9c35-4208-b5dd-c98038a3a809.gif


其中最有特点的是所谓的位带访问。这跟8051中的SFR存储空间的访问有些类似。也即可以使用某个地址对字/半字/字进行整体的访问,也可以使用其它地址对仅仅对特定字的某一位进行读写。


 



比方说51中的P1寄存器。即可以 i = P1来读取P1的整个值,也可以用j = P1_1来读取P1寄存器的第1位。



这样的好处是,当需要寄存器的某一位时不需要进行读-改-写的操作。比如要设置P1的0号端口为1,可以这样写P1 |= 0x1。实际执行的操作肯定是先读P1的值,再将第0位写1,再将改后的值写回P1。而如果用P1=0x1的话,则肯定会影响P1寄存器的其它位。但如果用P1_1 = 0x1,则相当于直接给该位为1,只需要写就可以了。


 



据说,还可在多任务下实现互斥访问。访问共享资源时不会发生冲突。这一点我还有待学习。


 



Cortex-m3存储系统有两块位带区。一块是0x20000000开始的1M空间,另一块是0x40000000开始的1M空间。这两块地址空间的存储访问,是以字节/半字/字的访问访问的。用汇编指令来说就是LDR R0, =0x20000000; LDR R0, [R0]。而0x2200000开始的32M0x4200000开始的32M,称位带别名区,即分别是前两块存储空间的别名。也就是说0x20000000和0x2200000实际上是映射到相同的存储空间内。不同的是,0x20000000开始的1M地址,每个地址对就于这块存储空间的1个字节。而0x2200000开始的32M每个地址对应于这块存储空间的每位。1M的字,正好是8M的位,每个位用字地址表示,也就是8*4 = 32M的位带别名地址大小了。



当然其二者之间的地址存在一定关系,可以由公式表示


 



LM3S1138的存储映射如图:


其存储空间为FLASH 64K, RAM 16K.


对比cortex-m3与下表可以看出.1138的片内RAM和片上外设地址空间均在位带区。也就是说,无论是RAM还是片上外设的寄存器都可以进行单个位的位操作。


点击看大图      0bfb46d7-a7df-49fd-b9e6-3ba4bf7c6cd2.jpg



存储访问的C函数接口:


官方提供的库中提供了相应的C函数来进行直接的存储访问。在hw_types.h文件中包含了相应的宏。另外还定义了布尔类型。我估计布尔类型用于支持位带操作用的。



 


点击看大图


HWREG(X)用于访问存储空间的一个字。不限于访问片上RAM,也可用于FLASH,内部的寄存器。


HWREGH(X)用于访问存储空间的一个半节


HWREGB(X)用于访问存储空间的一个字节



HWREGBITW(x,b)则仅适用于对位带区中的地址为X的字的第b位进行访问。


HWREGBITH(x,b)则仅适用于对位带区中的地址为X的半的第b位进行访问。


HWREGBITB(x,b)则仅适用于对位带区中的地址为X的字节的第b位进行访问。


 



以访问地址为0x20000000一个字为例:


读字:variable = HWREG( 0x20000000 ), 写字 HWREG( 0x20000000 ) = 数值.


读写0x20000000字单元中的第1位:


    读Variable = HWREGBITW( 0x20000000, 1 ); 读得值为0或1


    写:HWREGBITW(0x20000000, 1) = 0x1;



至于那个计算公式,我觉得就不必深究了。可以自己推导的。


在KEIL下自己写的一个简单的示例为下图:

  


点击看大图


 

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条