一、与以前51代码的区别
回想以前写51代码
P0=0x10 //将P0端口设置为0x10
P1_0=1 //将P1端口0号引脚设置为高电平
a=P2_2; //获取P2端口2号引脚的电平
根据上述的方法,我们可以发现快速定位修改某个引脚的电平还有获取引脚的状态。
二、什么是位带操作
将APB1、APB2和AHB1这些外设的每一位寄存器都映射到一个32位地址中去,映射过去的目标地址就是外设位带别名区地址。然后对这些别名地址进行操作就可以设置对应的位了。
三、为什么使用位带操作?
GPIO_SetBits、GPIO_ResetBits、GPIO_WriteBit操作IO口的性能没有达到极致,因为这些函数都需要进行现场保护的现场恢复的动作,比较耗时间,没有进行一步到位,使用位带操作则没有上述的烦恼,简单快速。
示例:
GPIO_SetBits(GPIOF,GPIO_Pin_9);
修改为
PFout(9)=1
四、映射表
五、映射公式
寄存器的位带别名=0x42000000+(寄存器的地址-0x40000000)32+引脚编号4
六、代码示例
int main(void )
{
uint32_t *pf9 = (uint32_t *)(0x42000000+((uint32_t)(&GPIOF->ODR)-0x40000000)*32+9*4);
uint32_t *pf10 = (uint32_t *)(0x42000000+((uint32_t)(&GPIOF->ODR)-0x40000000)*32+10*4);
//打开端口F的硬件时钟,等同于对端口F供电
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE );
//初始化对应端口的引脚
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;//指定第9根引脚
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT ;//配置为输出模式
GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz ;//配置引脚的响应时间=1/100MHz .
//从高电平切换到低电平1/100MHz,速度越快,功耗会越高
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP ;//推挽的输出模式,增加输出电流和灌电流的能力
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不使能内部上下拉电阻
GPIO_Init(GPIOF ,&GPIO_InitStruct);
while(1)
{
*pf9=0;
delay();
*pf9=1;
delay();
*pf10=0;
delay();
*pf10=1;
delay();
}
return 0 ;
}