책을 읽다보니 후에 GPIO_Init설명이 나왔다... 책을 순서대로 학습한다면 지금부터 쓰는거였다.


void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

{

  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;

  uint32_t tmpreg = 0x00, pinmask = 0x00;

  /* Check the parameters */

  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));

  assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));  

  

/*---------------------------- GPIO Mode Configuration -----------------------*/

  currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);

  if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)

  { 

    /* Check the parameters */

    assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));

    /* Output mode */

    currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;

  }


1줄 : input mode, output mode 판별. 0x0F를 이용하여 하위 4비트의 값만 추출

2줄 : mode가 0x00이 아니면 output모드



typedef enum

{ GPIO_Mode_AIN = 0x0,

  GPIO_Mode_IN_FLOATING = 0x04,

  GPIO_Mode_IPD = 0x28,

  GPIO_Mode_IPU = 0x48,

  GPIO_Mode_Out_OD = 0x14,

  GPIO_Mode_Out_PP = 0x10,

  GPIO_Mode_AF_OD = 0x1C,

  GPIO_Mode_AF_PP = 0x18

}GPIOMode_TypeDef;

/*---------------------------- GPIO CRL Configuration ------------------------*/

  /* Configure the eight low port pins */

  if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)    //CRL인지 확인

  {

    tmpreg = GPIOx->CRL;

    for (pinpos = 0x00; pinpos < 0x08; pinpos++)                                    //어느위치 설정값인지 확인(앞의 학습에서 했음)

    {

      pos = ((uint32_t)0x01) << pinpos;

      /* Get the port pins position */

      currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;                            //맞는 핀 위치 확인

      if (currentpin == pos)

      {

        pos = pinpos << 2;                             //CRL은 4비트 단위로 값 담당. pinpos*4로 위치값 구함(2만큼 왼쪽으로 shift)

        /* Clear the corresponding low control register bits */

        pinmask = ((uint32_t)0x0F) << pos;

        tmpreg &= ~pinmask;                    //원하는 부분만 0으로 만든값을 tmpreg에 and함. 원하는 부분만 0으로 변함

        /* Write the mode configuration in the corresponding bits */

        tmpreg |= (currentmode << pos);        //현재 설정값을 원하는 위치에 shift시켜 or시켜 적용

        /* Reset the corresponding ODR bit */

//CRL,CRH가 아닌 BRR.BSRR레지스터 설정

//input mode에서 pull-down, pull-up으로 설정할 경우, 그 GPIO에 값이 설정되어야한 정상적으로 설정 가능.

//즉, 해당 작업을 밖에서 설정하는것이 아니라, GPIO초기화 과정에서 한번에 처리

//Pull-down : Reset(0), Pull-up : Set(1)

        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)

        {

          GPIOx->BRR = (((uint32_t)0x01) << pinpos);

        }

        else

        {

          /* Set the corresponding ODR bit */

          if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)

          {

            GPIOx->BSRR = (((uint32_t)0x01) << pinpos);

          }

        }

      }

    }

    GPIOx->CRL = tmpreg;

  }

/*---------------------------- GPIO CRH Configuration ------------------------*/

  /* Configure the eight high port pins */

  if (GPIO_InitStruct->GPIO_Pin > 0x00FF)

  {

    tmpreg = GPIOx->CRH;

    for (pinpos = 0x00; pinpos < 0x08; pinpos++)

    {

      pos = (((uint32_t)0x01) << (pinpos + 0x08));

      /* Get the port pins position */

      currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);

      if (currentpin == pos)

      {

        pos = pinpos << 2;

        /* Clear the corresponding high control register bits */

        pinmask = ((uint32_t)0x0F) << pos;

        tmpreg &= ~pinmask;

        /* Write the mode configuration in the corresponding bits */

        tmpreg |= (currentmode << pos);

        /* Reset the corresponding ODR bit */

        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)

        {

          GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));

        }

        /* Set the corresponding ODR bit */

        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)

        {

          GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));

        }

      }

    }

    GPIOx->CRH = tmpreg;

  }

}



'중도연재종료 > CORTEX M3' 카테고리의 다른 글

UART_ Hello_Wolrd 찍기_2  (0) 2013.06.08
UART_ Hello World 찍기_1  (0) 2013.06.08
Key가 눌린것 알아채기  (0) 2013.05.24
고급스러운 코딩1.  (0) 2013.05.24
LED 끄기[GPIO Set Reset 레지스터]  (0) 2013.05.24
Posted by 십자성군