微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Keil创建新的STM32工程以及CortexM3的位带操作

Keil创建新的STM32工程以及CortexM3的位带操作

时间:11-19 来源:互联网 点击:
  上周实验课照例很水,首先是准备工作没做好,J-Link的驱动没装好,而且由于机房电脑本身的问题好多机子无法正确装驱动,或者在进入keil后会弹出莫名错误、闪退等情况,方老师说得好,当我们浪费时间再做这些事情的时候(浪费时间很大程度上是因为机房电脑造成的),好一点的学校早就在写程序了。这么多时间已经浪费了,还有多少能剩下来看代码进而理解它呢?

从新建一个工程开始学习,再加上上周实验课的位带操作相关内容,有需要的同学可以看看,也希望指正相关错误:)

1.新建工程

在keil中新建一个基于51的工程挺简单,不过新建一个STM32工程要复杂一些,多了一些步骤,需要建立更详细的工程目录,导入一些CMSIS(Cortex Microcontroller Software Interface Standard)文件、标准外设驱动文件、启动文件等等,并要进行一些参数设置。下面这篇博客已经说明得挺好了(在SITP中我也是参考的这篇博客),因此不再赘述。

http://www.cnblogs.com/emouse/archive/2012/03/01/2375146.html

至于相关的文件,可以在网上找到,我也在百度网盘里面传了一个上学期总线课用到的无线模块通信的工程,可以在里面找到所需的文件。

2.位带操作

先摘抄一些书上的内容,再结合代码分析



图2.1 Cortex ‐ M3预定义的存储器映射

注:根据我的理解,右边那一大块,对应的地址 从0x0 0 到0xFFFF FFFF 是存储器映射地址,通俗一点说就是序号,每一个地址(序号)对应内存中的一个字节的区域

2.1

在Cortex-M3中,有两个区中实现了位带(Bit Band)操作,其一是内部SRAM区最低的1MB范围,其二是片内外设去的最低1MB范围,这两个区中的地址还有自己的位带别名区(Bit Band Alias Region)。位带别名区把每个比特膨胀成一个32位的字,当通过位带别名区访问这些字时,就可以达到访问原始比特的目的。

图2.2位带区与位带别名区的膨胀映射关系

注1:和图2.1一样,图上显示的是地址,也就是序号,就像是第几号房间,而每个房间里面有8张床 (8个格子) (8bit 可以存东西的空间) 可以放0/1

注2:上半部分位带别名区,从起始地址开始,每4个序号(如0x2200 0~ 0x2200 3)对应下半部分位带区的一个序号中的一个位(如0x2 0. 0),这样就把位带区的1位扩展成了32位(4个序号 ,每个序号对应内存中的1字节=8位,4×8=32,更具体一点,就是0x2200 0.0 ~ 0x2200 3.7的空间),即1字。

/*

在位带区,每个比特都映射到别名地址区的一个字,该字只有最低位有效。当一个别名地址被访问时,会先把该地址变换成位带地址。对于读操作,读取位带地址中的一个字,在把需要的位右移到需要的最低位并把最低位返回。对于写操作,把需要写的位左移至对应的位序号出,然后执行一个原子的“读——改——写”过程。

*/

对于内部SRAM位带区的某个比特,记它所在的字节的地址为Addr,字节中位序号为n(0≤n≤7),则该比特在别名区的地址为:

AliasAddr = 0x2200 0 + ( ( Addr – 0x2 0 ) × 8 + n ) × 4

   = 0x2200 0 + ( Addr - 0x2 0 )×32 + n × 4          (转换公式)

上式中 × 4 是因为 1字 = 4字节, × 8 表示 1字节 = 8比特。

2.2

2.2.1

下面放上代码再具体说明

1 /* Private define */2 #define RAM_BASE       0x203 #define RAM_BB_BASE    0x224  5 /* Private macro -*/6 #define  Var_ResetBit_BB(VarAddr, BitNumber)    \7           (*(__IO uint32_t *) (RAM_BB_BASE  ((VarAddr - RAM_BASE) < 5)  ((BitNumber) < 2)) = 0)8    9 #define Var_SetBit_BB(VarAddr, BitNumber)       \10           (*(__IO uint32_t *) (RAM_BB_BASE  ((VarAddr - RAM_BASE) < 5)  ((BitNumber) < 2)) = 1)11 12 #define Var_GetBit_BB(VarAddr, BitNumber)       \13           (*(__IO uint32_t *) (RAM_BB_BASE  ((VarAddr - RAM_BASE) < 5)  ((BitNumber) < 2)))14    15 /* Private variables */16 17 __IO uint32_t Var, VarAddr = 0, VarBitValue = 0;18 19 Var = 0x05AA5;20 21 VarAddr = (uint32_t)&Var;

首先是定义基址,RAM_BASE是位带区的起始地址,RAM_BB_BASE是位带别名区的起始地址,这也可以从图2.1 看出。

然后是三个宏定义#define,可以看成是三个函数,其中\是续行符,表示下面一行是紧接着当前行的,一般用于将很长的代码语句分几段写,但要注意 \ 后面除了换行回车不能有任何字符,空格也不行。

接下来以Var_ResetBit_BB为例:

#defineVar_ResetBit_BB(VarAddr, BitNumber)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top