在uC-CPU/ARM-Cortex-M3/cpu_c.c中有兩個位帶訪問的函數
//使用位帶訪問技術來對內存或外設地址addr中的第bit_nbr位進行清零操作
void CPU_BitBandClr (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
// CPU_ADDR 爲16位
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
// 地址範圍的判斷
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI))
{
/*
CPU_BIT_BAND_SRAM_BASE + ((addr‐CPU_BIT_BAND_SRAM_REG_LO)*8+bit_nbr)*4 =0x22000000 + (addr‐0x20000000)*32 + bit_nbr*4
*/
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
}
}
//使用位帶訪問技術來對內存或外設地址addr中的第bit_nbr位進行置1操作
void CPU_BitBandSet (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
}
}
什麼是位帶訪問技術:
它的對象可以是SRAM、I/O和外設空間。要實現對這些地方的某一位的操作。
它是這樣做:*在尋址空間(32位對應的地址空間爲 4GB)的另一地方,取個別名區空間,從這個地址開始處,每一個字(32BIT)對應SRAM或I/O的一位。
1MB SRAM 就可以有 32MB 的對應別名區空間,就是1位膨脹到32位(1 BIT 變爲1個字節)。我們對這個別名區空間內的某一字操作(置0或置1),就等於它映射的 SRAM 或 I/O 相應的某地址的某一位的操作。
位帶訪問的好處
1、代碼縮小、速度更快、效率更高、更安全。
2、一般操作是讀-改-寫,而位帶別名區只有寫的操作,防止了中斷對讀改寫方式的影響。
應用
支持了位帶操作(bit_band),位帶別名區把每個比特膨脹成一個 32 位的字。 每個比特膨脹成一個32 位的字,就是把 1M 擴展爲 32M 。位於 RAM 地址 0X200000000 的一個字節擴展爲8個32位的字,擴展後每位相對應的的地址是:0X220000000,0X220000004,0X220000008。
支持位帶操作的兩個內存區的範圍是:
0x2000 0000‐0x200F FFFF(SRAM 區中的最低1MB)
0x4000 0000‐0x400F FFFF(片上外設區中的最低1MB)
對 SRAM 位帶區的某個比特,記該比特所在字節的地址爲A,位序號爲 n (0<=n<=7),則它在別名區的地址爲:
AliasAddr = 0x22000000 + ((A‐0x20000000)*8+n)*4 =0x22000000 + (A‐0x20000000)*32 + n*4
(“*4”表示一個字爲 4 個字節,“*8”表示一個字節中有 8 個比特。)
使用地址宏:
#define BITBAND(addr, bitnum) ((addr &0xF0000000)+0x2000000 + ((addr & 0xFFFFF)<<5) + (bitnum<<2))
使用指針的方式
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
MEM_ADDR(BITBAND((U32)&CRCValue, 1)) = 0x1
函數中的應用
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
映射公式:
bit_word_offset = (byte_offset x 32) + (bit_number × 4)
bit_word_addr = bit_band_base + bit_word_offset
其中:
bit_word_offset是目標位在存取器位段區中的位置
bit_word_addr 是別名存儲器區中字的地址,它映射到某個目標位。
bit_band_base 是別名區的起始地址。
byte_offset 是包含目標位的字節在位段中的序號
bit_number 是目標位所在位置(0-31)
參考博客:
http://blog.sina.com.cn/s/blog_9f27507501011gg1.html
在此感謝。