如果你想改变某个位的状态而不影响其他的,那用BSRR或BRR就很容易了。直接操作ODR需要“读-操作-写”的过程,速度反而变慢了。
比如说让PA1、PA3、PA7清零而不影响其他位的状态,那就是:
GPIOA->BRR=PA1|PA3|PA7;
你要用ODR来操作的话,那就变成这样了:
GPIOA->ODR&=~(PA1|PA3|PA7);
虽然C的语句都只有一个,但你看汇编代码,就发现使用BRR比ODR快的多。
您好,STM32的GPIO口的功能是非常之强大的。关于GPIO输出的赋值可使用两种方法,方法A:逐一配置法,优点是不会影响到其它的GPIO口,缺点是操作比较繁琐。方法B:ODR设置法,优点是操作轻松,缺点是需要硬件电路作配合。下面我们详细描写这两种方法:方法A:所谓逐一配置法, 就是对需要输出数据的IO口线逐一配置,需要输出为1的IO口使用GPIOx-BSS = 1 N; (N表示第N根线,如PA9, N值为9)需要输出为0的IO口使用GPIOx-BRSS = 1 N;使用以下语句可以完成//to do 先将输出口配置为输出功能for( i = start; i end; i++ ){ if( value BSS = 1 i; } else { GPIOx-BRSS = 1 i; }}方法B: ODR配置法,可以直接使用 GPIO-ODR = value N;给对应的IO口进行输出操作。但是此时在硬件上要保证:1 该功能口(如GPIOA)上的其余的IO口不作为普通的IO输出口使用(由于是键盘扫描,当列输出的时候,行应当是输入;同理,当列输入时,行应当是输出)2 行列以外的GPIO口,要末是普通的IO输入口,要末是功能口。功能口就是UART、USB、PWM、ADC等,对GPIO的ODR进行操作时,不会对功能口产生影响。以上第2条是对第1条的详细解释。总结:如果在硬件上可以满足方法B的利用条件,建议优先采取方法B。在其它1些需要使用并行输出,如并口液晶、NandFlash等应当的时候,也能够斟酌使用方法B。 查看更多答案>>
记得采纳啊
GPIOA是一个结构体指针,他指向一个地址为GPIOA_BASE的结构体GPIO_TypeDef。其中GPIOA_BASE就是控制这组IO口的寄存器组的基地址,GPIO_TypeDef是一个结构体,里面的成员变量对应着A组IO的相关控制寄存器,如:
GPIOA->ODR;GPIOA->IDR;GPIOA->CRL;GPIOA->CRH等等就是控制A组IO口的寄存器,操作GPIOA->ODR就是操作A组IO口。
认真看下手册,下面是我引用的一段,应该能助你理解了~~
端口低配置寄存器寄存器的复位值为0X4444 4444,,复位值其实就是配置端口为浮空输
入模式。STM32的CRL控制着每个IO端口(A~G)的低8位的模式。每
个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。这里我们可以记住几个
常用的配置,比如0X4表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,
50M速率)、0X8表示上/下拉输入模式(做输入口用)、0XB表示复用输出(使用IO口的第二
功能,50M速率)。
CRH的作用和CRL完全一样,只是CRL控制的是低8位输出口,而CRH控制的是高8
位输出口。这里我们对CRH就不做详细介绍了。
给个实例,比如我们要设置PORTC的11位为上拉输入,12位为推挽输出。代码如下:
GPIOA->CRH&=0XFFFFFFF0;
GPIOA->CRH|=0X00000003;//PA8 推挽输出
GPIOA->ODR|=1<<8;
//PA8 输出高
再如:
GPIOC->CRH&=0XFFF00FFF;//清掉这2个位原来的设置,同时也不影响其他位的设置
GPIOC->CRH|=0X00038000; //PC11输入,PC12输出
GPIOC->ODR=1<<11;//PC11上拉
通过这3句话的配置,我们就设置了PC11为上拉输入,PC12为推挽输出
n 是第几个管脚的意思 ,就是GPIO_A_n!
//位带操作,实现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))
使用BIT_ADDR(addr, bitnum)可以取某一数据的某一位,
例如 I_u8data=5;//0000 0101
//用 I_u8data_bit[8]来取I_u8data的每一位有
for(i=0;i<8;i++)
{
I_u8data_bit[i]=BIT_ADDR((uint32_t)&I_u8data, i);
}
//则有 I_u8data_bit[0]==1; I_u8data_bit[2]==1; 其余为零
GPIOA->IDR这是个只读寄存器,是不能给它赋值的,就算你给它赋值也是无效的,也就是说你的:GPIOA->IDR=GPIOA->IDR>>8;这句话是无效的,你应该这样:
先定义一个变量unsigned short temp;然后
while(1)
{
temp = GPIOA->IDR>>8;
GPIOA->ODR = temp;
}
欢迎分享,转载请注明来源:品搜搜测评网