1、端口位設置/清除
在STM32F1xx系列芯片中,可對BSRR、BRR寄存器相應的位置1,以實現置位和清零操作,如:
GPIOA->BSRR = (1<<3); // 設置端口A的位3為1 GPIOA->BRR = (1<<3); // 清除端口A的位3為0
在LPC17xx系列芯片中,可對FIOSET、FIOCLR寄存器相應的位置1,以實現置位和清零操作,如:
LPC_GPIO2->FIOSET = (1<<3); // 設置端口2的位3為1 LPC_GPIO2->FIOCLR = (1<<3); // 清除端口2的位3為0
2、端口直接輸出
在STM32F1xx系列芯片中,可對ODR寄存器相應的位置1或0,以實現置位和清零操作,如:
GPIOA->ODR |= (1<<3); // 端口A的位3輸出1 GPIOA->ODR &= ~(1<<3); // 端口A的位3輸出0
在LPC17xx系列芯片中,可對FIOPIN寄存器相應的位置1或0,以實現置位和清零操作,如:
LPC_GPIO2->FIOPIN |= (1<<3); // 端口2的位3輸出1 LPC_GPIO2->FIOPIN &= ~(1<<3); // 端口2的位3輸出0
3、端口位帶輸出
參考《Cortex-M3 權威指南》第五章,第5小節 位帶操作(87頁~92頁)。
為簡化位帶操作,可以定義一些宏。比如,我們可以建立一個把“位帶地址+位序號”轉換成別名地址的宏, 再建立一個把別名地址轉換成指針類型的宏。
//1):把“位帶地址+位序號”轉換成別名地址的宏 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2)) //2):把該地址轉換成一個指針 #define MEM_ADDR(addr) *((volatile unsigned long *) (addr)) //3):使用位帶別名地址訪問 #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
應用如下:
STM32F1xx系列芯片:
#define PAout(n) BIT_ADDR((uint32_t)&GPIOA->ODR, n)
PAout(3) = 1; //端口A的位3輸出1 PAout(3) = 0; //端口A的位3輸出0
LPC17xx系列芯片:
#define P2out(n) BIT_ADDR((uint32_t)&LPC_GPIO2->FIOPIN, n) P2out(3) = 1; //端口2的位3輸出1 P2out(3) = 0; //端口2的位3輸出0
4、端口位域輸出
定義一個端口位域,端口為16位的就定義16位(STM32F1xx),端口為32位的就定義32位(LPC17xx)。
#pragma anon_unions //以便結構體或共用體無需另起名字 typedef union{ uint32_t WORDS; struct{ int bit00 :1; int bit01 :1; int bit02 :1; int bit03 :1; int bit04 :1; int bit05 :1; int bit06 :1; int bit07 :1; int bit08 :1; int bit09 :1; int bit10 :1; int bit11 :1; int bit12 :1; int bit13 :1; int bit14 :1; int bit15 :1; int bit16 :1; int bit17 :1; int bit18 :1; int bit19 :1; int bit20 :1; int bit21 :1; int bit22 :1; int bit23 :1; int bit24 :1; int bit25 :1; int bit26 :1; int bit27 :1; int bit28 :1; int bit29 :1; int bit30 :1; int bit31 :1; }; }PORT;
應用如下:
STM32F1xx系列芯片:
#define PAout03 (((PORT *)(&GPIOA->ODR))->bit03) PAout03 = 1; //端口A的位3輸出1 PAout03 = 0; //端口A的位3輸出0
LPC17xx系列芯片:
#define P2out03 (((PORT *)(&LPC_GPIO2->FIOPIN))->bit03)
P2out03 = 1; //端口2的位3輸出1
P2out03 = 0; //端口2的位3輸出0
5、綜述
以上4種方法,1、2兩種較為多見;方法3為位帶操作,速度最快,但只對具備位帶的U有效;方法4是一種新穎的通用方法,只要找到輸入或輸出寄存器即可,對任意U有效!