stm32-----IO复用配置

GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9USART1

解析:
GPIO为端口A的基址
GPIO_PinSource9:为端口9
GPIO_AF_USART1:复用映射,宏定义为:
#define GPIO_AF_USART1 ((uint8_t)0x07),见下图,为不同外设的映射情况,UART1对应的是AF7,因此这里是0X07,同理AF6,映射的是SPI3,对应的宏定义是0x06

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;
}

解析:
首先看下复用功能寄存器,复用功能寄存器分两个,复位功能低位寄存器配置端口0-7和复位功能高位寄存器配置端口8-15,该寄存器32位,每4位表示一个端口,因此一个寄存器总共能配置8个端口,如下:

由上面寄存器定义,可发现两个规律:
其一,若是复用AF7,需要把相应的寄存器设置成为0111即0x7,这里需要设置的数字7和复用映射号7一致,同样发现,其他复用也是如此。
其二:每4位代表一个端口,从低到高依次为端口0-7;对于高位端口8-15同样,从低到高依次为8-15,若取低三位(8的二进制1000-低三位0;9的二进制1001-低三位是1),则是0-7。
从上面规律可知道,若想端口9复用USART1功能,端口9大于8,则对应高位寄存器,端口数字9取第三位为001,说明需要用配置高位寄存器的第二个4位的值。要想复用USART功能,则需设置成7即0111。
明白了以上规律,基本就清楚程序中式如何设置的了。接下来对分局对程序进行解析:
temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4))该句的意思就是判断需要配置复用功能寄存器中那个端口,每个端口4位,因此乘以4,即获得需要配置的位置。
GPIO_AF是复用的功能的值,左移的目的就是移动到需要配置的端口上去。
GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
这句话的意思,把需要设置的4位清零,其他地方保持不变。
temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
这句话的意思,是改变需要配置的位置的值,其他位置保持不变

GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;

你可能感兴趣的:(stm32)