一、与以前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 ; }