日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32位带区和位带别名区的浅谈

發布時間:2025/3/8 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32位带区和位带别名区的浅谈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.首先談下為什么要使用位帶?

在學習51單片機時就已經使用過位操作,比如使用sbit對單片機IO口的定義,但是STM32中并沒有這類關鍵字,而是通過訪問位帶別名區來實現,即通過將每個比特位膨脹成一個32位字,當訪問這些字的時候就達到了訪問比特的目的。比方說BSRR寄存器有32個位,那么可以映射到32個地址上,當我們去訪問這32個地址就達到訪問32個比特的目的,也就是說我們可以通過位帶輕松的去控制某一位。

2.存儲單元和存儲地址的相關概念

在計算機中最小的信息單位是bit,也就是一個二進制位,8個bit組成一個Byte,也就是字節。一個存儲單元可以存儲一個字節,也就是8個二進制位。計算機的存儲器容量是以字節為最小單位來計算的,對于一個有128個存儲單元的存儲器,可以說它的容量為128字節。如果有一個1KB的存儲器則它有1024個存儲單元,它的編號為從0-1023。存儲器被劃分成了若干個存儲單元,每個存儲單元都是從0開始順序編號,如一個存儲器有128個存儲單元,則它的編號就是從0-127。

存儲地址一般用十六進制數表示,而每一個存儲器地址中又存放著一組二進制(或十六進制)表示的數,通常稱為該地址的內容。值得注意的是,內儲單元的地址和地址中的內容兩者是不一樣的。前者是存儲單元的編號,表示存儲器總的一個位置,而后者表示這個位置里存放的數據。正如一個是房間號碼,一個是房間里住的人一樣。

存放一個機器字的存儲單元,通常稱為字存儲單元,相應的單元地址叫字地址。而存放一個字節的單元,稱為字節存儲單元,相應的地址稱為字節地址。如果計算機中可以編址的最小單元是字存儲單元,則該計算機稱為按字尋址的計算機。如果計算機中可編址的最小單位是字節,則該計算機稱為按字節尋址的計算機。如果機器字長等于存儲器單元的位數,一個機器字可以包含數個字節,所以一個存儲單元也可以包含數個能夠單獨編址的字節地址。例如一個16位二進制的字存儲單元可存放兩個字節,可以按字地址尋址,也可以按字節地址尋址。當用字節地址尋址時,16位的存儲單元占兩個字節地址。(摘自百度百科)

以STM32來說,STM32是一個32位的微控制器,它是按字存儲單元;每一個寄存器都是占用4個字節即32位,這點將在下面位帶和位帶別名地址換算的時候用到

3.Cortex-M3位帶區和位帶映射區對應關系

STM32位帶及位帶別名區域支持位帶操作的區域是SRAM 區的最低1MB 范圍(APB1/2,AHB1外設)和片內外設區的最低1MB范圍。

對于SRAM/GPIO位帶區的某個比特(bit),記它所在的字節地址為A,位序號為n(0<=n<=7)(如果是GPIO則n<=16),則該比特在位帶別名區中的地址為:

AliasAddr=0x22000000+((A-0x20000000)*8+n)*4

上式中‘8’表示每個字節中有8個比特,‘4’表示4個字節(因為CM3是32位機,機器字為4個字節)。

(A-0x20000000)表示一共用這么多個字節,(A-0x20000000)*8+n表示一共有這么多位,在別名區中,每個位占4個字節地址,故((A-0x20000000)*8+n)*4表示該位在別名區中的偏移字節地址。偏移地址加上基地址就是該比特在位帶別名區中的地址

4.最后附上STM32F103的實現代碼

#ifndef _BIT_BIND_H_ #define _BIT_BIND_H_#include "stm32f10x.h"//位帶操作,實現51類似的GPIO控制功能 //具體實現思想,參考<<CM3權威指南>>第五章(87頁~92頁). //IO口操作宏定義 #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)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO口操作,只對單一的IO口! //確保n的值小于16! #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //輸出 #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //輸入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //輸出 #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //輸入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //輸出 #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //輸入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //輸出 #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //輸入 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //輸出 #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //輸入#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //輸出 #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //輸入#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //輸出 #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //輸入#endif

總結

以上是生活随笔為你收集整理的STM32位带区和位带别名区的浅谈的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。