《STM32中的位带(bit-band)操作与原理解析.docx》由会员分享,可在线阅读,更多相关《STM32中的位带(bit-band)操作与原理解析.docx(7页珍藏版)》请在优知文库上搜索。
1、STM32中的位带(bit-band)操作支持了位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。在CM3中,有两个区中实现了位带。其中一个是SRAM区的最低IMB范围,第二个则是片内外设区的最低IMB范围。这两个区中的地址除了可以像普通的RAM一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个32位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。位带操作的概念其实30年前就有了,那还是8051单片机开创的先河,如今,CM3将此能力进化,这里的位带操作是8051位寻址区的威力大幅加强版。CM3使用如下术语来表示位带存储的相关地址:位带区
2、:支持位带操作的地址区、位带别名:对别名地址的访问最终作用到位带区的访问上(这中途有一个地址映射过程)在位带区中,每个比特都映射到别名地址区的一个字一一这是只有1.SB有效的字。当一个别名地址被访问时,会先把该地址变换成位带地址。对于读操作,读取位带地址中的一个字,再把需要的位右移到1.SB,并把1.SB返回。对于写操作,把需要写的位左移至对应的位序号处,然后执行一个原子的“读-改-写”过程。图5.3B位带区与位带别名区的膨胀对应关系图B举例:欲设置地址0x20OOJ)OOO中的比特2,划使用位带操令的设置过程如下图所示:不使用位带功能使用位带功能读取0x200(1.OOOO处的值到寄行器中置
3、位寄存SS的bit2阳寄存器的值写回)0x20000000读取0x20000000处的值到内部缓冲区位置bit2后,再犯僵g02000.0000图5.4写数据到位带别名区对应的汇编代码如图5.5所示WithoutBit-Band1.DRR0,020000000;Stupaddr1.DRRl,(R0;ReadORR.WRl,0x4;ModifybitSTRRl,(R0;WritebackresultWithBit-Band1.DRRO,0x22000008SetupaddressMOVRl,1iSetupdataSTRRlt(R0;Write图5.5位带操作与普通操作的对比,在汇编程序的珀度上位
4、带读操作相对简单些:无Bit-BandRead0x200000toregister把bit2右移到1.SB再簿蔽其它的位S*Bit-Band映射成3次Readfrom总线传0x2200CXX)8从0x20000000读出数据后,再阳bit2攫取出来$5.6从位带别名区中读取比特无位带有位带1.DRRO,-0x20000000;建立地址1.DRRO,-0x22000008;建立地址1.DRRlf(RO);Read1.DRRl,RO;ReadUBFX-WR1,R1,#2,#1;提取除2图5.7读取比特时传统方法与位带方法的比较支持位带操作的两个内存区的范围是:0x2000-0000-0x200F_
5、FFFF(SRAM区中的最低1MB)0x4000_0000-0x400F_FFFF(片上外设区中的最低IMB)对SRAM位带区的某个比特,记它所在字节地址为A,位序号为n(0=n=7),则该比特在别名区的地址为:AliasAddr=0x22000000+(A-0x20000000)*8+n)*4=0x22000000+(A-0x20000000)*32+nM对于片上外设位带区的某个比特,记它所在字节的地址为A,位序号为n(0=n=7),则该比特在别名区的地址为:AliasAddr=0x42000000+(A-0x40000000)*8+n)*4=0x42000000+(A-0x40000000
6、)*32+nM上式中,“*4”表示一个字为4个字节,“*8”表示一个字节中有8个比特。这里再不嫌啰嗦地举一个例子:1.在地址0x20000000处写入0x3355AACC2.读取地址0x22000008。本次读访问将读取0x20000000,并提取比特2,值为1。3.往地址0x22000008处写Oo本次操作将被映射成对地址0x20000000的“读-改-写”操作(原子的),把比特2清Oo4.现在再读取0x20000000,将返回0x3355AAC8(bitl2已清零)。位带别名区的字只有1.SB有意义。另外,在访问位带别名区时,不管使用哪一种长度的数据传送指令(字/半字/字节),都把地址对齐
7、到字的边界上,否则会产生不可预料的结果。Icpplviewplaincopy位带操作,实现51类似的GPIO控制功能具体实现思想,参考第五章(87页92页).IO口操作宏定义#defineBlTBAND(addr,bitnum)(addr&0xF0000000)+0x2000000+(addr&0xFFFFF)5)+(bitnum2)#defineMEM_ADDR(addr)*(volatileunsignedlong*)(addr)#defineBIT_ADDR(addr,bitnum)MEM_ADDR(BITBAND(addr,bitnum)/IO口地址映露#defineGP10A_0DR
8、_Addr(GP10A_BASE+12)0x4001080C#defineGP10B_0DR_Addr(GPI0B_BASE+12)0x4001OCOC#defineGP10C_0DR_Addr(GPI0C_BASE+12)0x4001100C#defineGPI0D_0DR_Addr(GP10D_BASE+12)0x4001140C#defineGP10E_0DR_Addr(GP10E_BASE+12)0x4001180C#defineGP10F_0DR_Addr(GP10F_BASE+12)0x40011AOC#defineGPI0G_0DR_Addr(GP10G_BASE+12)0x40
9、011EOC#defineGP!OAJDR_Addr(GPIOA_BASE+8)/0x40010808#defineGP!OBJDR_Addr(GPIOB_BASE+8)/0x40010C08#defineGPIOCJDR_Addr(GPIOC_BASE+8)0x40011008#defineGPIODJDR_Addr(GPIOD_BASE+8)0x40011408#defineGPIOE_IDR_Addr(GPIOE_BASE+8)/0x40011808#defineGP!OFJDR_Addr(GPIOF_BASE+8)/0x40011A08#defineGPIOGJDR_Addr(GPIO
10、G_BASE+8)/0x40011E08IO口操作,只对单一的IO口确保n的值小于16!#definePAout(n)BIT_ADDR(GPIoAjDDR_Addr,n)输出#definePAin(n)BIT_ADDR(GPIOADR_Addr,n)输入#definePBout(n)BIT_ADDR(GPlOBJDDR_Addr,n)输出#definePBin(n)BIT_ADDR(GPlOBDR_Addr,n)输入#definePCout(n)BIT_ADDR(GPIOC1.oDR_Addr,n)输出#definePCin(n)BIT_ADDR(GPIOCDR_Addr,n)输入#defin
11、ePDout(n)BIT_ADDR(GPIOD_ODR_Addr,n)输出#definePDin(n)BIT_ADDR(GPIoDDR_Addr,n)输入#definePEout(n)BIT_ADDR(GPlOE_ODR_Addr,n)输出#definePEin(n)BIT_ADDR(GPIOEDR_Addr,n)输入#definePFout(n)Bn1.ADDR(GPIoFJDDR_Add,n)输出#definePFin(n)Bn1.ADDR(GPIOFDR_Addr,n)输入#definePGout(n)Bn1.ADDR(GPIoG_ODR_Addr,n)输出#definePGin(n)B
12、IT_ADDR(GPIoGDR_Addr,n)输入STM32单片机位带操作原理解析STM32单片机的SRAM有两个区支持位带(bit-band)操作。那么,什么是位带,位带操作的原理是怎样的呢?在介绍位带操作之前,先看一看ARMCroteXt-M3的存储器映射。CM3的地址空间是4GB,程序可以在代码区,内部SRAM区以及外部RAM区中执行。STM32单片机的程序存储器、数据存储器、寄存器和输入输出端口,被组织在同一个4GB的线性地址空间内。数据字节以小端格式存放在存储器中。由芯片供应陶定义外眸有外设总线内部外出总线片外外iflIOGBOx43FFFF”IOGB0*E01000Oveoofff
13、ff0x(0040000OxE003FFFFOMfoOOoOOOOxdfffffffOxAOOOOOOOOx%FFFFFF片外RAM位南剧名区32MB片上外设0140100000C0x4000000002)FFFFFF片上SRAM0142000000041FFFFFFOv201000000x220000000m21FFFFFF512MB512MB5I2MB0x60000000Oxsfffffff0x400000000x3FFFFFFF0x20000000OxifffffffCM3使用如下术语来表示位带存储的相关地址。位带区:支持位带操作的地址区位带别名:对别名地址的访问最终会变换成对位带区的访
14、问(注意:有一个地址映射过程)Cortex-M3存储器映像包括两个位段(bit-band)区。这两个位段区将别名存储器区中的每个字映射到位段存储器区的一个位,在别名存储区写入一个字具有对位段区的目标位执行读-改-写操作的相同效果。两个位带区分别为:第一个是SRAM区的最低IMB范围,地址范围为:0x2000_0000-0x200F_FFFF第二个是片内外设区谣最低IMB范围,地址范围0x4000_0OOo-OX400F_FFFF这两个位带中的地址除了可以像普通的RAM一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个32位的字。当你通过位带别名区访问这些字时,就可以达到
15、访问原始比特的目的。位带区与位带别名区的膨胀对应关系如下图在位带区中,每个比特都映射到别名地址区的一个字,这是个只有1.SB才有效的字。当一个别名地址被访问时,会先把该地址变换成位带地址。在STM32FIOxxx里,外设寄存器和SRAM都被映射到一个位段区里,这允许执行单一的位段的写和读操作。下面的映射公式给出了别名区中的每个字是如何对应位带区的相应位的:bit_word_addr=bit_band_base+(byte_offsetx32)+(bit_numberx4)其相:bit_word_addr是别名存储器区中字的地址,它映射到某个目标位。bit_band_base是别名区的起始地址。byte_offset是包含目标位的字节在位段里的序号bit_number是目标位所在位置(0-31)举个例子,如何映射别名区中