欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

     找回密碼
     立即注冊

    QQ登錄

    只需一步,快速開始

    搜索
    查看: 2791|回復: 1
    打印 上一主題 下一主題
    收起左側

    拋磚引玉之位段操作

    [復制鏈接]
    跳轉到指定樓層
    樓主
    ID:64689 發表于 2014-8-20 16:24 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
    拋磚引玉之位段操作
    分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
    收藏收藏 分享淘帖 頂 踩
    回復

    使用道具 舉報

    沙發
    ID:51088 發表于 2014-8-20 17:00 | 只看該作者
    Cortex?-M3存儲器映像包括兩個位段(bit-band)區。這兩個位段區將別名存儲器區中的每個字映射到位段存儲器區的一個位,在別名存儲區寫入一個字具有對位段區的目標位執行讀-改-寫操作的相同效果。
    在STM32F10xxx里,外設寄存器和SRAM都被映射到一個位段區里,這允許執行單一的位段的寫和讀操作。
    下面的映射公式給出了別名區中的每個字是如何對應位帶區的相應位的:
    bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)
    其中:
    bit_word_addr是別名存儲器區中字的地址,它映射到某個目標位。
    bit_band_base是別名區的起始地址。
    byte_offset是包含目標位的字節在位段里的序號
    bit_number是目標位所在位置(0-31)

    在 CM3  支持的位段中,有兩個區中實現了位段。

    其中一個是 SRAM 區的最低 1MB 范圍, 0x20000000 ‐ 0x200FFFFF(SRAM 區中的最低 1MB);

    第二個則是片內外設區的最低 1MB范圍, 0x40000000 ‐ 0x400FFFFF(片上外設區中的最低 1MB)。

    在 C 語言中使用位段操作

    在 C編譯器中并沒有直接支持位段操作。比如,C 編譯器并不知道對于同一塊內存,能夠使用不同的地址來訪問,也不知道對位段別名區的訪問只對 LSB 有效。欲在 C中使用位段操作,最簡單的做法就是#define 一個位段別名區的地址。例如:

    #define DEVICE_REG0 ((volatile unsigned long *) (0x40000000))

    #define DEVICE_REG0_BIT0 ((volatile unsigned long *) (0x42000000))

    #define DEVICE_REG0_BIT1 ((volatile unsigned long *) (0x42000004))

    ...

    *DEVICE_REG0 = 0xab;        //使用正常地址訪問寄存器

    *DEVICE_REG0_BIT1 = 0x1;  

    還可以更簡化:

    //把“位帶地址+位序號” 轉換成別名地址的宏

    #define BITBAND(addr, bitnum)((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2))  
      //把該地址轉換成一個指針

    #define MEM_ADDR(addr)  *((volatile unsigned long *) (addr))

    于是:

    MEM_ADDR(DEVICE_REG0) = 0xAB;     //使用正常地址訪問寄存器  

    MEM_ADDR(BITBAND(DEVICE_REG0,1)) = 0x1;  //使用位段別名地址

    注意:當你使用位段功能時,要訪問的變量必須用 volatile 來定義。因為 C 編譯器并不知道同一個比特可以有兩個地址。所以就要通過 volatile,使得編譯器每次都如實地把新數值寫入存儲器,而不再會出于優化的考慮 ,在中途使用寄存器來操作數據的復本,直到最后才把復本寫回。

    實際上,在寫程序是都有這樣的定義:

    #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))

    #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))

    #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

    然后定義:#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C

    最后操作:#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //輸出 ODR保存要輸出的數據;IDR保存讀入的數據
    回復

    使用道具 舉報

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規則

    小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

    Powered by 單片機教程網

    快速回復 返回頂部 返回列表