GPIOC->ODR |=(0<<2); // 總線操作,即操作整個寄存器.
在51單片機中
P0=0xFE; //總線操作.
sbit LED1=P0^0; //位操作,即操作寄存器中的某一位.
LED1 =0;
在STM32中並沒有sbit這樣的關鍵字.但是我們可以用位帶操作實現位操作.
位帶操作
在 STM32 中,有兩個地方實現了位帶,一個是 SRAM 區(存放代碼)的最低 1MB 空間,令一個是外設區最低 1MB 空間。這兩個 1MB 的空間除了可以像正常的 RAM 一樣操作外,他們還有自己的位帶別名區,位帶別名區把這 1MB 的空間的每一個位膨脹成一個 32 位的字(4個字節),當訪問位帶別名區的這些字時,就可以達到訪問位帶區某個比特位的目的.
位帶操作的公式
外設位帶區與外設位帶別名區的地址轉換: AlisaAddr=0x42000000+(A-0x40000000)*8*4+n*4
SRAM位帶區與SRAM位帶別名區地址轉換: AlisaAddr=0x22000000+(A-0x20000000)*8*4+n*4
其中:A:表示操作的那個位寄存器所在的寄存器地址
n:位號(第幾位)
對上面式子的解釋:
AlisaAddr=位帶別名區基地址+(寄存器地址-寄存器基地址)[偏移多少個字節]*8[一個字節8位]*4[每個位膨脹4個字節] [這是第0位]+n*4[第n個位膨脹的字節說]
理解要點:位帶區的一個位在位帶別名區膨脹位4個字節
位帶操作的總公式
AlisaAddr =((addr&0xF0000000)+0x02000000+((addr&0x00FFFFFF)<<5)+(bitnum<<2))
其中:addr:要操作的寄存器地址.(寄存器映射表中,每個外設地址+偏移地址)
bitnum:位號,即寄存器的第幾位
對上面式子的解釋: addr&0xF0000000:為了取出4和2,用來區分是外設還是SRAM.然后+0x20000000就等於外設/SRAM位帶別名區的起始地址
add&0x00FFFFFF0x00FFFFFF:屏蔽掉高2位,外設位帶區的高地址位0x4010 0000,SRAM的位帶區高地址為0x2010 0000, (0x4010 0000 –0x40000000) 和(0x2010 0000-0x200000)在求偏移地址相減的時候只要第四位有效,所以就把剩下的高兩位屏蔽掉,剩下的6位與F相與即可.
點亮LED的源碼
我們在上次的代碼中繼續添加:
main為:
#include "stm32f10x.h" // 相當於51單片機中的 #include <reg51.h> #include "bsp_led.h" #include "bsp_key.h" #define SOFT_DELAY Delay(0x0FFFFF); //void Delay(__IO u32 nCount); #define GPIOC_ODR_Addr (GPIOC_BASE+0x0C) #define PCout(bitnum) *(unsigned int *)((GPIOC_ODR_Addr&0xF0000000)+0x02000000+((GPIOC_ODR_Addr &0x00FFFFFF)<<5)+(bitnum<<2)) #define GPIOC_IDR_Addr (GPIOC_BASE+0x08) #define PCIn(bitnum) *(unsigned int *)((GPIOC_IDR_Addr&0xF0000000)+0x02000000+((GPIOC_IDR_Addr &0x00FFFFFF)<<5)+(bitnum<<2)) void Delay( uint32_t count){ for( ;count!=0;count--); } int main(void) { // 來到這里的時候,系統的時鍾已經被配置成72M。 LED_GPIO_Config(); LED_OFF; KEY_LED_Config(); while(1){ if(PCIn(13)==KEY_ON){ while(PCIn(13)==KEY_ON) ; LED_TOGGLE; } } }


