对于STM32F4库函数中GPIO_PinAFConfig()函数的解读

  最近在学STM32F4芯片,想用寄存器操作,在学到IO端口复用AF(Alternative Function)时,发现对于

GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)函数无法理解.而后拿纸算了算,恍然大悟,写下这篇笔记来记录和分享.

     先贴上代码:

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
{
  uint32_t temp = 0x00;
  uint32_t temp_2 = 0x00;
  
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  assert_param(IS_GPIO_AF(GPIO_AF));
  
  temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;   
  GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
  temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
  GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
}

对于代码疑问有二:

1,为何写入PinSource和AF复用就可以对相应寄存器进行操作.

2,对于((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4))无法理解.

针对疑点查询IO复用映射表:

并代入 PA9 (0x09) 和GPIO_AF_USART1(0x07) 的数据发现GPIOA->AFR[1] |=0x0000 0070;

对应AFR高八位寄存器为0x0000 0070,其中PA9对应AFRH9[3:0]为7,即0111,为AF7

恰到好处的是GPIO_AF_USART1 为 0x07,所以恍然大悟:

((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) 

拆解为 先执行(uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07),即GPIO_PinSource与0x07相 "&" 后剔除高位byte,并获取GPIO_PinSource在寄存器中的位置,再 * 4,就是移动在 高位/低位寄存器 中的位置 乘以 一个半字(AFR中的一个位),如此便可以得到想写入寄存器中的 GPIO_AF_USART1 的数据. 即 0x0000 0070;

    而GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4))是对 我们 想写入的   AFR寄存器 对应位的复位 (即是对应位置写入0000).

     至此分析完成,可以得到我们想要进行寄存器操的 函数,即对对应位写入想要的AF.

     对PA9写入GPIO_AF_USART1的代码示例如下:   

    GPIOA->AFR[1] &= ~(0xF<<4*1);        //初始化复用端口     

    GPIOA->AFR[1] |= 0x7<<4*1;          //PA9 复用为USATT1_TX

PA9是高八位,对应寄存器位AFR[1]中的AFRH9,我们想写入的AF是GPIO_AF_USART1,参考图一是AF7,即0x07,那么操作就是先初始化再写入0x7咯.

PS:本人第一次写博客,讲的也许不好,如有错误和异议还请大家指正.谢谢!

猜你喜欢

转载自blog.csdn.net/Beking17113/article/details/82733070