标签:
在应用的时候PA2口需要设置成推挽输出,控制一个外部电源开关,端口初始化程序如下:
GPIO_DeInit(GPIOA);
GPIO_Init(GPIOA,GPIO_PIN_2,GPIO_MODE_OUT_PP_HIGH_SLOW);
在设置完后,端口会马上输出高电平,于是又加了一句:
GPIO_WriteLow(GPIOA,GPIO_PIN_2);
完成之后,发现被供电的器件在第一次上电的时候会被触发,而程序并没有在PA2输出高电平。这个被供电器件配有供电电池如果检测到端口有高电平就会启动,
用示波器观察PA2口,发现在上电瞬间会有一个短脉冲,看来就是这个问题。查看了一下库函数的源代码:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
{
      assert_param(IS_GPIO_MODE_OK(GPIO_Mode));
      assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
    
    /* Reset corresponding bit to GPIO_Pin in CR2 register */
    GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));
      /*-----------------------------*/
      /* Input/Output mode selection */
  *-----------------------------*/
      if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x80) != (uint8_t)0x00) /* Output mode */
      {
            if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x10) != (uint8_t)0x00) /* High level */
          {
                GPIOx->ODR |= (uint8_t)GPIO_Pin;
          } 
          else /* Low level */
          {
                GPIOx->ODR &= (uint8_t)(~(GPIO_Pin));
          }
          /* Set Output mode */
            GPIOx->DDR |= (uint8_t)GPIO_Pin;
      } 
      else /* Input mode */
      {
            /* Set Input mode */
            GPIOx->DDR &= (uint8_t)(~(GPIO_Pin));
      }
    /*------------------------------------------------------------------------*/
    /* Pull-Up/Float (Input) or Push-Pull/Open-Drain (Output) modes selection */
    /*------------------------------------------------------------------------*/
      if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x40) != (uint8_t)0x00) /* Pull-Up or Push-Pull */
      {
            GPIOx->CR1 |= (uint8_t)GPIO_Pin;
      } 
      else /* Float or Open-Drain */
      {
            GPIOx->CR1 &= (uint8_t)(~(GPIO_Pin));
      }
      /*-----------------------------------------------------*/
      /* Interrupt (Input) or Slope (Output) modes selection */
      /*-----------------------------------------------------*/
      if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x20) != (uint8_t)0x00) /* Interrupt or Slow slope */
      {
            GPIOx->CR2 |= (uint8_t)GPIO_Pin;
      } 
      else /* No external interrupt or No slope control */
      {
            GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));
      }
}
从源码看来,是先把CR2清零了。然后写DDR方向寄存器1是输出,0是输入,然后是CR1。这个配合DDR可以确定4中方式:DDR为0的时候CR1为0的时候是:悬浮输入,CR1为1的时候是上拉输入,DDR为1的时候CR1为0的时候是:开漏输出,CR1为1的时候是:推挽输出。CR1在DDR为0的时候是外部中断的开关,1是开,0是关,DDR为1的时候是控制摆率的,如果需要比较陡峭的边沿可以设置成1。
不知道为什么会出现这个,硬件仿真发现CR1置位之后就会被拉高,后来我用寄存器方式设置有正常了,代码如下:
  GPIOA->CR2 |= 0x04; 
       GPIOA->DDR |= 0x04;
       GPIOA->CR1 |= 0x04;
标签:
原文地址:http://www.cnblogs.com/ashitaka/p/4271789.html