zoukankan      html  css  js  c++  java
  • STM8s在利用库配置端口的小问题

      在应用的时候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;

    这个只不过是自己的流水账,偶尔有一些心得,错误的地方概不负责
  • 相关阅读:
    「读书感悟」三体
    「PLC」PLC基本编程
    利用一个Demo说明Castle+NHibernate的实现
    采用jquery实现简单的计算器
    Html+css+Jquery模拟电影院购票
    Jquery实现简单的导航单并且经常使用
    H5的video元素实现的Demo
    JQuery编写的定时器实现时钟
    Castle.net
    1056. 组合数的和(15)
  • 原文地址:https://www.cnblogs.com/ashitaka/p/4271789.html
Copyright © 2011-2022 走看看