JW's

STM32F746을 이용해 사거리 신호등 만들기 프로젝트 본문

펌웨어/사거리 신호등 만들기 with STM32F746

STM32F746을 이용해 사거리 신호등 만들기 프로젝트

wlsdnr929 2022. 8. 21. 18:33

 

 

<사거리 신호등 만들기 프로젝트>

 

 

 

(STM32F746 이미지)

 

 

 

(간단한 회로도)

 

 

 

 

 

<동작내용>

 

- 4거리 신호등 중 붙어있는 3방향의 신호 각 4개를 제어

- 일정한 시간이 흐르면 다음 step으로 넘어가야 함. 반복됨.

- 한방향 기준으로 파란불->노란불->빨간불/좌회전-> …....  이렇게 1번의 step이 무한반복

- 1 set이 지날때마다 LED 4개의 바이너리 카운트 표시

- 1111이 최대이며, 그 다음은 0000

- 메인보드 내의 리셋 스위치

- , 리셋 스위치는 누른 후 땔 때에만 작동

- 파란불이 꺼질때까지 남은시간을 7segment에 표시

- 각 거리의 신호에 맞는 횡단보도 LED 꺼지기 2초전에는 빠르게 깜빡이게함 (파란불)

- 외부보드에 Skip 스위치 기능

 

 

 

 

<동작영상>

 

 

 

 

 

<소스코드>

#ifndef SRC_MAIN_H_
#define SRC_MAIN_H_
#endif

#ifndef SRC_BSP_BSP_H_
#define SRC_BSP_BSP_H_
#include "def.h"
#include "stm32f7xx_hal.h"
static void SystemClock_Config(void);
#endif

void hwInit(void);
void MyApp();

static void SystemClock_Config(void)
{
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    RCC_OscInitTypeDef RCC_OscInitStruct;

    /* Enable HSE Oscillator and activate PLL with HSE as source */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 25;
    RCC_OscInitStruct.PLL.PLLN = 432;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        //Error_Handler();
    }

    /* activate the OverDrive to reach the 216 Mhz Frequency */
    if (HAL_PWREx_EnableOverDrive() != HAL_OK)
    {
        //Error_Handler();
    }

    /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
       clocks dividers */
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
    {
        //Error_Handler();
    }
}


int main(void)
{
    hwInit();
    MyApp();
}

void hwInit(void)
{
    SCB_EnableICache();
    SCB_EnableDCache();
    HAL_Init();
    SystemClock_Config();
}

int DelayWithBTN(unsigned int n) {
    n = n * 100000;
    int r = 0;
    while (n--) {
        // sw2 눌리면
        if ((*(volatile unsigned int*)0x40020810U & 0x00001000U)) {
            r = 2;
        }
        // sw1 눌리면
        if (*(volatile unsigned int*)0x40021810U & 0x00000008U) {
            r = 1;
        }
    }
    return r;
}

// n =10  --> 1초
void MyDelay(unsigned int n)
{
    volatile unsigned int delay;

    for (delay = 0; delay <= n * 3600000; delay++);
}

void verticalCrossBlueOn()
{
    //   pf10 (세로신호등 파란불)
    //     a1

    *(volatile unsigned int*)(0x40021418U) |= 0x00000400U;
}

void verticalCrossBlueOff()
{
    //   pf10 (세로신호등 파란불)
    //     a1

    // 끄기
    *(volatile unsigned int*)(0x40021418U) |= 0x04000000U;
    MyDelay(2);
}

void verticalCrossRedOn()
{
    //   pf9 (세로신호등 빨간불)
    //   a2

    // 켜기
    *(volatile unsigned int*)(0x40021418U) |= 0x00000200U;
}

void verticalCrossRedOff()
{
    //   pf9 (세로신호등 빨간불)
    //   a2

    // 켜기
    *(volatile unsigned int*)(0x40021418U) |= 0x02000000U;
}

void verticalCrossBlueBlink()
{
    //   pf10 (세로신호등 파란불)
    //     a1

    // 끄기
    *(volatile unsigned int*)(0x40021418U) |= 0x04000000U;
    MyDelay(2);
    // 켜기
    *(volatile unsigned int*)(0x40021418U) |= 0x00000400U;
    MyDelay(2);
}


void horizontalCrossBlueOn()
{
    //   pf8 (가로신호등 파란불)
    //   a3

    *(volatile unsigned int*)(0x40021418U) |= 0x00000100U;
}

void horizontalCrossBlueOff()
{
    //   pf8 (가로신호등 파란불)
    //   a3

    // 끄기
    *(volatile unsigned int*)(0x40021418U) |= 0x01000000U;
    MyDelay(2);
}

void horizontalCrossRedOn()
{
    //   pf7 (가로신호등 빨간불)
    //   a4

    // 켜기
    *(volatile unsigned int*)(0x40021418U) |= 0x00000080U;
}

void horizontalCrossRedOff()
{
    //   pf7 (가로신호등 빨간불)
    //   a4

    // 켜기
    *(volatile unsigned int*)(0x40021418U) |= 0x00800000U;
}

void horizontalCrossBlueBlink()
{
    //   pf8 (가로신호등 파란불)
    //   a3

    // 끄기
    *(volatile unsigned int*)(0x40021418U) |= 0x01000000U;
    MyDelay(2);
    // 켜기
    *(volatile unsigned int*)(0x40021418U) |= 0x00000100U;
    MyDelay(2);
}

void countSet(unsigned char data) {
    // 1번 led
    if ((data >> 3) & 0x01) {
        // 1이면 켜기
        TurnOnOneLED(1);
    }
    else {
        // 0이면 끄기
        TurnOffOneLED(1);
    }

    // 2번 led
    if ((data >> 2) & 0x01) {
        // 1이면 켜기
        TurnOnOneLED(2);
    }
    else {
        // 0이면 끄기
        TurnOffOneLED(2);
    }

    // 3번 led
    if ((data >> 1) & 0x01) {
        // 1이면 켜기
        TurnOnOneLED(3);
    }
    else {
        // 0이면 끄기
        TurnOffOneLED(3);
    }

    // 4번 led
    if ((data) & 0x01) {
        // 1이면 켜기
        TurnOnOneLED(4);
    }
    else {
        // 0이면 끄기
        TurnOffOneLED(4);
    }

}

int MyDelayWithCheckSwitch(unsigned int n)
{
    volatile unsigned int delay;
    int flag = 0; // 내부 sw1 눌리면 1, 때면 2

    //  n = 10   -> 1초

    for (delay = 0; delay <= n * 800000; delay++)
    {
        // 내부 sw1 눌리면
        if (*(volatile unsigned int*)0x40020810U & 0x00001000U) {
            flag = 1;
        }
        // 내부 sw1 눌렸다 때면
        if (flag == 1) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00001000U) == 0) {
                flag = 2;
                countSet(0);
            }
        }
        // 외부 스위치 (pc1) 눌리면 바로 return
        if (*(volatile unsigned int*)0x40020810U & 0x00000002U) {
            flag = 3;
        }
        // 외부 스위치 (pc1) 눌렸다 때면
        if (flag == 3) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00000002U) == 0) {
                flag = 4;
                return flag;
            }
        }
    }
    return flag;
}

int MyDelayWithCheckSwitchSeg(unsigned int n)
{
    volatile unsigned int delay;
    int flag = 0; // 내부 sw1 눌리면 1, 때면 2

    //  n = 10   -> 1초

    for (delay = 0; delay <= n * 800000; delay++)
    {
      if(delay == 7000000)
      {
        segment(112);
      }
      if(delay == 14000000)
      {
        segment(95);
      }
      if(delay == 21000000)
       {
         segment(91);
       }
      if(delay == 28000000)
       {
         segment(51);
        }
      if(delay == 35000000)
       {
          segment(121);
       }
      if(delay == 42000000)
       {
          segment(109);
        }
      if(delay == 49000000)
        {
          segment(48);
        }
      if(delay == 55500000)
         {
           segment(126);
        }

      if(delay)
        // 내부 sw1 눌리면
        if (*(volatile unsigned int*)0x40020810U & 0x00001000U) {
            flag = 1;
        }
        // 내부 sw1 눌렸다 때면
        if (flag == 1) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00001000U) == 0) {
                flag = 2;
                countSet(0);
            }
        }
        // 외부 스위치 (pc1) 눌리면 바로 return
        if (*(volatile unsigned int*)0x40020810U & 0x00000002U) {
            flag = 3;
        }
        // 외부 스위치 (pc1) 눌렸다 때면
        if (flag == 3) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00000002U) == 0) {
                flag = 4;
                return flag;
            }
        }
    }
    return flag;
}

// 세로 횡단보도 파란불 깜빡 포함된 Delay
int MyDelayWithCheckSwitchVerticalBlink(unsigned int n)
{
    volatile unsigned int delay;
    int flag = 0; // 내부 sw1 눌리면 1, 때면 2


    for (delay = 0; delay <= n * 100000; delay++)
    {

        if (delay % 400000 == 0) {
            verticalCrossBlueOn();
        }
        if (delay % 800000 == 0) {
            verticalCrossBlueOff();
        }
        if (delay % 1200000 == 0) {
            verticalCrossBlueOn();
        }
        if (delay % 1600000 == 0) {
            verticalCrossBlueOff();
        }
        if (delay % 1900000 == 0) {
            verticalCrossBlueOn();
        }


        // 내부 sw1 눌리면
        if (*(volatile unsigned int*)0x40020810U & 0x00001000U) {
            flag = 1;
        }
        // 내부 sw1 눌렸다 때면
        if (flag == 1) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00001000U) == 0) {
                flag = 2;
                countSet(0);
            }
        }
        // 외부 스위치 (pc1) 눌리면 바로 return
        if (*(volatile unsigned int*)0x40020810U & 0x00000002U) {
            flag = 3;
        }
        // 외부 스위치 (pc1) 눌렸다 때면
        if (flag == 3) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00000002U) == 0) {
                flag = 4;
                return flag;
            }
        }
    }
    return flag;
}

// 가로 횡단보도 파란불 깜빡 포함된 Delay
int MyDelayWithCheckSwitchHorizontalBlink(unsigned int n)
{
    volatile unsigned int delay;
    int flag = 0; // 내부 sw1 눌리면 1, 때면 2


    for (delay = 0; delay <= n * 100000; delay++)
    {

        if (delay % 400000 == 0) {
            horizontalCrossBlueOn();
        }
        if (delay % 800000 == 0) {
            horizontalCrossBlueOff();
        }
        if (delay % 1200000 == 0) {
            horizontalCrossBlueOn();
        }
        if (delay % 1600000 == 0) {
            horizontalCrossBlueOff();
        }
        if (delay % 1900000 == 0) {
            horizontalCrossBlueOn();
        }

        // 내부 sw1 눌리면
        if (*(volatile unsigned int*)0x40020810U & 0x00001000U) {
            flag = 1;
        }
        // 내부 sw1 눌렸다 때면
        if (flag == 1) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00001000U) == 0) {
                flag = 2;
            }
        }
        // 외부 스위치 (pc1) 눌리면 바로 return
        if (*(volatile unsigned int*)0x40020810U & 0x00000002U) {
            flag = 3;
        }
        // 외부 스위치 (pc1) 눌렸다 때면
        if (flag == 3) {
            if ((*(volatile unsigned int*)0x40020810U & 0x00000002U) == 0) {
                flag = 4;
                return flag;
            }
        }
    }
    return flag;
}

int CheckClockStatus(int GOIOPort)
{
    if (*(volatile unsigned int*)0x40023830U & (1 << (GOIOPort - 1)))
    {
        return 1;
    }
    else
        return 0;
}

void ClockEnable(int GOIOPort)
{
    *(volatile unsigned int*)0x40023830U |= 1 << (GOIOPort - 1);
}

void TurnOnOneLED(unsigned char No)
{
    // 1번켜기
    if (No == 1) {
        if (CheckClockStatus(7) == 0) {
            ClockEnable(7);
        }
        *(volatile unsigned int*)0x40021800U |= 0x01000000U;
        *(volatile unsigned int*)0x40021808U |= 0x03000000U;
        *(volatile unsigned int*)0x4002180CU |= 0x01000000U;
        *(volatile unsigned int*)0x40021818U |= 0x10000000U;
    }
    // 2번켜기
    else if (No == 2) {
        if (CheckClockStatus(5) == 0) {
            ClockEnable(5);
        }
        *(volatile unsigned int*)0x40021000U |= 0x00000400U;
        *(volatile unsigned int*)0x40021008U |= 0x00000C00U;
        *(volatile unsigned int*)0x4002100CU |= 0x04000C00U;
        *(volatile unsigned int*)0x40021018U |= 0x00200000U;
    }
    // 3번켜기
    else if (No == 3) {
        if (CheckClockStatus(5) == 0) {
            ClockEnable(5);
        }
        *(volatile unsigned int*)0x40021000U |= 0x00000100U;
        *(volatile unsigned int*)0x40021008U |= 0x00000300U;
        *(volatile unsigned int*)0x4002100CU |= 0x00000100U;
        *(volatile unsigned int*)0x40021018U |= 0x00100000U;
    }
    // 4번켜기
    else {
        if (CheckClockStatus(7) == 0) {
            ClockEnable(7);
        }
        *(volatile unsigned int*)0x40021800U |= 0x00100000U;
        *(volatile unsigned int*)0x40021808U |= 0x00300000U;
        *(volatile unsigned int*)0x4002180CU |= 0x00100000U;
        *(volatile unsigned int*)0x40021818U |= 0x04000000U;
    }
}

void TurnOffOneLED(unsigned char No)
{
    // 1번끄기
    if (No == 1) {
        *(volatile unsigned int*)0x40021818U &= 0x00000000U;
        *(volatile unsigned int*)0x40021818U |= 0x00001000U;
    }
    else if (No == 2) {
        *(volatile unsigned int*)0x40021018U &= 0x00000000U;
        *(volatile unsigned int*)0x40021018U |= 0x00000020U;
    }
    else if (No == 3) {
        *(volatile unsigned int*)0x40021018U &= 0x00000000U;
        *(volatile unsigned int*)(0x40021018U) |= 0x00000010U;
    }
    // 4번 끄기
    else {
        *(volatile unsigned int*)0x40021818U &= 0x00000000U;
        *(volatile unsigned int*)(0x40021818U) |= 0x00000400U;
    }
}

int btn_check()
{
    // sw1 눌렸을 때
    if (*(volatile unsigned int*)0x40021810U & 0x00000008U)
    {
        return 1;
    }
    // sw2 눌렸을 때
    else if ((*(volatile unsigned int*)0x40020810U & 0x00001000U)) {
        return 2;
    }
    // 아무것도 안 눌렸을 때
    else {
        return 0;
    }
}

void portAsetting()
{

    // 7segment    --> pa2, pa8
    // a,     b,     c,     d,     e,     f,     g,     dp
    // pa2,   pa8,   pa3,   pc2,   pc6,   pc7,   pg6,   pg7


    *(volatile unsigned int*)0x40023830U |= 0x00000001U;
    // mode setting  --> output
    *(volatile unsigned int*)0x40020000U |= 0x00010050U;
    // speed setting --> very high
    *(volatile unsigned int*)0x40020008U |= 0x000300f0U;
    // pupd  --> reserved
    *(volatile unsigned int*)0x4002000cU |= 0x000300f0U;
}

void portBsetting()
{
    // PB setting --> pb 7,8,9

    // 7segment
    // a,     b,     c,     d,     e,     f,     g,     dp
    // pa2,   pa8,   pa3,   pc2,   pc6,   pc7,   pg6,   pg7


    *(volatile unsigned int*)0x40023830U |= 0x00000002U;
    // mode setting  --> output
    *(volatile unsigned int*)0x40020400U |= 0x00054000U;
    // speed setting --> very high
    *(volatile unsigned int*)0x40020408U |= 0x000fc000U;
    // pupd  --> reserved
    *(volatile unsigned int*)0x4002040cU |= 0x000fc000U;
}

void portCsetting()
{
    // 7segment    --> pc2, pc6, pc7
    // a,     b,     c,     d,     e,     f,     g,     dp
    // pa2,   pa8,   pa3,   pc2,   pc6,   pc7,   pg6,   pg7


    *(volatile unsigned int*)0x40023830U |= 0x00000004U;
    // mode setting  --> output
    *(volatile unsigned int*)0x40020800U |= 0x00005010U;
    // speed setting --> very high
    *(volatile unsigned int*)0x40020808U |= 0x0000f030U;
    // pupd  --> reserved
    *(volatile unsigned int*)0x4002080cU |= 0x0000f030U;
}

void portFsetting()
{
    // pf   10,    9,    8,    7  --> 신호등
    //      a1,    a2,   a3,   a4

    // enble
    *(volatile unsigned int*)(0x40023830U) |= 0x00000020U;

    // mode setting  --> output
    *(volatile unsigned int*)(0x40021400U) |= 0x00154000U;
    // speed setting --> very high
    *(volatile unsigned int*)(0x40021408U) |= 0x003FC000U;
    // pupd  --> reserved
    *(volatile unsigned int*)(0x4002140CU) |= 0x003FC000U;

}

void portGsetting()
{
  // 7segment    --> pg6, pg7
  // a,     b,     c,     d,     e,     f,     g,     dp
  // pa2,   pa8,   pa3,   pc2,   pc6,   pc7,   pg6,   pg7


    // enble
    *(volatile unsigned int*)(0x40023830U) |= 0x00000040U;

    // mode setting  --> output
    *(volatile unsigned int*)(0x40021800U) |= 0x00005000U;
    // speed setting --> very high
    *(volatile unsigned int*)(0x40021808U) |= 0x0000f000U;
    // pupd  --> reserved
    *(volatile unsigned int*)(0x4002180CU) |= 0x0000f000U;

}

void sw_setting()
{
    // push_sw2 (pc12)
    // enable
    if (CheckClockStatus(3) == 0) {     //   ---> *(volatile unsigned int*)0x40023830U |= 0x00000004U;
        ClockEnable(3);
    }
    //  input setting
    *(volatile unsigned int*)0x40020800U &= 0xfcffffffU;  // ~(0x03000000)
  // speed setting - low
    *(volatile unsigned int*)0x40020808U &= 0xfcffffffU;  // ~(0x03000000)
  // pupd - no pull
    *(volatile unsigned int*)0x4002080cU &= 0xfcffffffU;  // ~(0x03000000)


    // 외부 스위치 (pc1)
    // enable 이미 됨
    //  input setting
    *(volatile unsigned int*)0x40020800U &= 0xfffffff3U;  // ~(0x0000000c)
   // speed setting - low
    *(volatile unsigned int*)0x40020808U &= 0xfffffff3U;  // ~(0x0000000c)
   // pupd - no pull
    *(volatile unsigned int*)0x4002080cU &= 0xfffffff3U;  // ~(0x0000000c)
}

void controlLED(unsigned char data) {

    // pb  7,         8,        9
    //     d14,       d15,      d10
    //     clock,       latch,    input


    // 초기값 모두 0
    *(volatile unsigned int*)0x40020418U |= 0x01000000U;  // pb7
    *(volatile unsigned int*)0x40020418U |= 0x01000000U;  // pb8
    *(volatile unsigned int*)0x40020418U |= 0x02000000U;  // pb9

    unsigned char i = 7;


    while (i <= 7) {
        // input에 값써주기
        if ((data >> i) & 0x01) {
            // 1이면
            *(volatile unsigned int*)0x40020418U |= 0x00000200U;
        }
        else
        {
            // 0이면
            *(volatile unsigned int*)0x40020418U |= 0x02000000U;
        }

        // clock High  --> 1주면 input의 값이 Q0로 들어감
        *(volatile unsigned int*)0x40020418U |= 0x00000080U;
        // 다시 끄기
        *(volatile unsigned int*)0x40020418U |= 0x00800000U;

        i--;
        // 이렇게 7번 반복하면 원래있던 값들이 한칸씩 쉬프트되면서
        // Q0 부터 Q7 까지 data의 비트별 값이 들어감
    }

    // latch High  --> 1을 주면 저장된 값들을 LED에 출력
    *(volatile unsigned int*)0x40020418U |= 0x00000100U;
    // 다시 끄기
    *(volatile unsigned int*)0x40020418U |= 0x01000000U;
}


int trafficLight(int cnt)
{
    controlLED(24);                       // 1번 상황 (파)    (빨)

    // 횡단보도 세로빨간불 꺼지기
    verticalCrossRedOff();
    // 횡단보도 세로파란불 켜기
    verticalCrossBlueOn();

    // 횡단보도 가로파란불 꺼지기
    // 횡단보도 가로빨간불 켜지기
    horizontalCrossRedOn();


    // 버튼눌렀다가 때면 cnt 초기화
    if (MyDelayWithCheckSwitchSeg(70) == 2) {
        cnt = 0;
        countSet(cnt);
    }


    controlLED(18);                       // 2번 상황 (노)    (빨)

    // 횡단보도 세로 파란불 2초 깜빡
    if (MyDelayWithCheckSwitchVerticalBlink(20) == 2) {
        cnt = 0;
        countSet(cnt);
    }

    // 깜빡임 끄기
    *(volatile unsigned int*)(0x40021418U) |= 0x04000000U;
    MyDelay(2);


    // 횡단보도 세로 빨간불 켜기
    verticalCrossRedOn();

    controlLED(21);                       // 3번 상황 (빨/좌)  (빨)
    if (MyDelayWithCheckSwitch(70) == 2) {
        cnt = 0;
        countSet(cnt);
    }

    controlLED(19);                       // 4번 상황 (빨/노)  (빨)
    if (MyDelayWithCheckSwitch(20) == 2) {
        cnt = 0;
        countSet(cnt);
    }


    // 가로 횡단보도 파란불 켜기
    horizontalCrossBlueOn();
    // 가로 횡단보도 빨간불 끄기
    horizontalCrossRedOff();

    controlLED(129);                      // 5번 상황 (빨)    (파)
    if (MyDelayWithCheckSwitch(70) == 2) {
        cnt = 0;
        countSet(cnt);
    }

    controlLED(33);                       // 6번 상황 (빨)    (노)
    if (MyDelayWithCheckSwitchHorizontalBlink(20) == 2) {
        cnt = 0;
        countSet(cnt);
    }

    // 가로 횡단보도 깜빡임 끄기
    // 끄기
    *(volatile unsigned int*)(0x40021418U) |= 0x01000000U;
    MyDelay(2);


    // 가로 횡단보도 빨간불 켜기
    horizontalCrossRedOn();

    controlLED(81);                       // 7번 상황 (빨)    (빨/좌)
    if (MyDelayWithCheckSwitch(70) == 2) {
        cnt = 0;
        countSet(cnt);
    }

    controlLED(49);                       // 8번 상황 (빨)    (빨/노)
    if (MyDelayWithCheckSwitch(20) == 2) {
        cnt = 0;
        countSet(cnt);
    }

    cnt = (cnt + 1) % 16;

    // set 수 내부 led에 나타내기
    countSet(cnt);

    return cnt;
}

void segment(char n)
{
  // A,    B,    C,    D,    E,    F,    G
  // pa2,  pa8,  pa3,  pc2,  pc6,  pc7,  pg6

  if((n>>6) & 0x01){
    // 켜기 pa2
    *(volatile unsigned int*)0x40020018U |= 0x00000004U;
  }
  else{
    // 끄기
    *(volatile unsigned int*)0x40020018U |= 0x00040000U;
  }

  if((n>>5) & 0x01){
     // 켜기 pa8
    *(volatile unsigned int*)0x40020018U |= 0x00000100U;
  }
  else{
     // 끄기
    *(volatile unsigned int*)0x40020018U |= 0x01000000U;
  }

  if((n>>4) & 0x01){
     // 켜기 pa3
    *(volatile unsigned int*)0x40020018U |= 0x00000008U;
  }
  else{
     // 끄기
    *(volatile unsigned int*)0x40020018U |= 0x00080000U;
  }

  if((n>>3) & 0x01){
     // 켜기 pc2
    *(volatile unsigned int*)0x40020818U |= 0x00000004U;
  }
  else{
     // 끄기
    *(volatile unsigned int*)0x40020818U |= 0x00040000U;
  }

  if((n>>2) & 0x01){
     // 켜기 pc6
    *(volatile unsigned int*)0x40020818U |= 0x00000040U;
  }
  else{
     // 끄기
    *(volatile unsigned int*)0x40020818U |= 0x00400000U;
  }

  if((n>>1) & 0x01){
     // 켜기 pc7
    *(volatile unsigned int*)0x40020818U |= 0x00000080U;
  }
  else{
     // 끄기
    *(volatile unsigned int*)0x40020818U |= 0x00800000U;
  }

  if((n) & 0x01){
     // 켜기 pg6
    *(volatile unsigned int*)0x40021818U |= 0x00000040U;
  }
  else{
     // 끄기
    *(volatile unsigned int*)0x40021818U |= 0x00400000U;
  }
}

void MyApp()
{

    // port 3개
    // pb 7,         8,        9
    //    d14,       d15,      d10
    //    clock,       latch,    input


    // pc 1   --> 외부 스위치
    //    d7


    // pf 10,   9,   8,   7  --> 신호등
    //    a1,   a2,  a3,  a4


    // 7segment
    // a,     b,     c,     d,     e,     f,     g,     dp
    // pa2,   pa8,   pa3,   pc2,   pc6,   pc7,   pg6,   pg7

    portAsetting();
    portBsetting();
    portCsetting();
    portFsetting();
    portGsetting();

    sw_setting();  // 내부 sw2 , 외부 스위치 (pc1)

    int cnt = 0;

    while (1) {
        // 신호등
        cnt = trafficLight(cnt);
    }
}