Study/AVR ATmega128 Easy Processor Kit

12. Easy Processor Kit 7-segment 제어하기

안녕하세요~!!! 진짜 추운 날씨죠?ㅠㅠ 얼마전에는 눈보라까지 치고 난리도 아니었어요..


춥지만 힘을 내서 공부를 해 볼까요?ㅎ


오늘은 지난 시간에 이야기 했던 7-segment에 대해서 공부하도록 할게요!


 - 7-Segment란?


 7-Segment(FND)란 7개의 조명편을 아래 그림과 같이 배치하고그 몇 개를 선택하여 조광함으로써 숫자나 문자를 표시할 수 있도록 한 표시장치치에요, LED를 조합하여 숫자나 문자를 나타내는 것이랍니다~

 이러한 각 LED는 어떻게 연결되어 있을까요?? 공통버스인 COM단자에 물려서 제어가 되는군요! 많이 보던 다이오드도 보이구요~

 그리고 Cathode와 Anode 이것은 이전 시간에 LED를 배웠을때 기억나시나요? 다이오드 방향에 따라서 동작방식이 결정되는 것을 말하는 거죠!

조금 더 자세히 알아 볼까요??


 - Segment Anode형

 회로가 복잡해 보이죠? 하지만 잘 보시게 되면 4개의 Segment로 구성되어 있다는 것을 알 수 있습니다. 혹시 시중에 붙여서 파는 Segment 소자들을 보신적 있으신가요? 다 저렇게 연결되어 있답니다~!

 Anode는 공통버스인 COM 단자에는 VCC를 연결하고 입력으로 GND(그라운드)에 해당하는 논리적인 0이 들어오면 해당 LED에 불이 들어오게 된답니다. 다이오드 방향을 보시고 다들 아시겠죠?

 각 핀의 영어들은 위의 그림에서 LED의 위치를 나타냅니다. 참고하세요!


- Segment Cathode형

 다음은 Cathode형을 살펴보도록 하죠. 여기서는 Anode형과 다른 것은 딱 한 가지 있네요. 바로 다이오드의 방향입니다.

 그럼 공통버스인 COM 단자에는 GND를 연결하고 입력으로 논리적인 1이 들어오면 해당 LED에 불이 들어오게 되는 것인거 아시겠죠?


 - 7-Segment 제어 방법

 이제 Segment가 대충 어느 것인지는 알았고, Kit의 회로도를 한번 살펴보도록 하죠.

 D플립플롭으로 FND_DATA, FND_CS가 신호가 들어오게 되네요. FND_DATA는 이름에서 부터 감이 오는 것과 같이 어느 LED가 켜질 것인지에 대한 데이터가 가겠네요. FND_CS의 경우 Segment의 밑 부분의 버스들 있죠? FND_COM 이라는 버스로 Segment에 들어가게 된답니다.


 그렇다면 FND_CS의 역할은 무엇일까요?? 버스의 갯수를 보고 감이 오시나요? 바로 어느 Segment가 해당 데이터로 켜질 것인가에 대한 데이터를 담고 있습니다. 즉, FND_CS가 정한 Segment에 FND_DATA에 해당하는 LED를 키는 것이죠! 


 그렇긴한데... 약간 의문이 듭니다. 8개를 동시에 켜지도 못하면 무용지물이 될터인데.. 여기서 아주 중요한 개념이 이제 나옵니다!


 - 잔상효과

- 잔상효과

 우리가 일상에서 보던 Segment들은 어떻게 동시에 값을 나타내고 있던 것일까요? 바로 위의 그림처럼 잔상효과를 이용하는 것입니다.

Kit에 보시게 되면 총 8개의 Segment가 있는데, 이를 동시에는 켜지 못하니 하나씩 Segment를 키는 것이죠. 그리고 이를 빠르게 돌린다면?? 마치 다 켜져 보이는 것처럼 나타 날 것입니다.

 바로 이러한 개념을 이용하는 것이에요!! 오늘 강좌의 핵심이니 잘 기억해 두세요!


 - Segment 동작 흐름도

 이제 쉽게 그림으로 흐름도를 보도록 하죠. 이해가 되시죠? CPLD를 통해 FND_DATA, FND_CS의 값들이 결정 되고, 해당 데이터의 값이 Segment로 들어가서 제어가 되는 형태입니다!

 혹시나 해서 다시 한번! CPLD 외부 메모리 맵핑 주소를 올립니다. ㅎㅎ 자주 보이죠?


 - 실습


 자 이제 개념 공부는 다했으니 직접 실습해보도록 합시다!! AVR Studio를 켜시고 코드를 입력해 보도록 하죠.


#include <avr/io.h>

#define DIG_SELECT (*(volatile unsigned char *)0x7000) // FND 선택을 위한 주소 지정

#define FND_DATA (*(volatile unsigned char *)0x6C00) // FND data 값 저장 위한 주소 지정

 

void ExtFndSet(int sel)

{

    switch(sel) // 0부터 차례대로 Segment에 표시

    {

        case 0 :

            FND_DATA = ~0x3F; // Anode 방식이므로 0일 때 켜지기 때문에 앞에 not을 붙임, 0011 1111 으로 해당하는 Segment0이라는 표시가 나오게 됩니다.

            break;

        case 1 :

            FND_DATA = ~0x06; // 1 표시

            break;

        case 2 :

            FND_DATA = ~0x5B; // 2 표시

            break;

        case 3 :

            FND_DATA = ~0x4F; // 3 표시

            break;

        case 4 :

            FND_DATA = ~0x66; // 4 표시

            break;

        case 5 :

            FND_DATA = ~0x6D; // 5 표시

            break;

        case 6 :

            FND_DATA = ~0x7C; // 6 표시

            break;

        case 7 :

            FND_DATA = ~0x07; // 7 표시

            break;

        case 8 :

            FND_DATA = ~0x7F; // 8 표시

            break;

        case 9 :

            FND_DATA = ~0x6F; // 9 표시

            break;

        case 10 :

            FND_DATA = ~0x77; // A 표시

            break;

        case 11 :

            FND_DATA = ~0x7C; // b 표시

            break;

        case 12 :

            FND_DATA = ~0x39; // C 표시

            break;

        case 13 :

            FND_DATA = ~0x5E; // D 표시

            break;

        case 14 :

            FND_DATA = ~0x79; // E 표시

            break;

        case 15 :

            FND_DATA = ~0x71; // F 표시

            break;

        case 16 :

            FND_DATA = ~0x76; // H 표시

            break;

        case 17 :

            FND_DATA = ~0x40; // - 표시

            break;

        case 18 :

            FND_DATA = ~0x80; // . 표시

            break;

        case 19 :

            FND_DATA = ~0x00; // 공백 표시

            break;

      }

}

 

void delay_us(unsigned char time_us) // us단위 delay를 위한 함수

{

    register unsigned char i;

    for(i=0;i<time_us;i++)

    {

        asm volatile("PUSH R0"); // 스택 푸쉬

        asm volatile("POP R0"); // 스택 팝

    }

}

 

void delay_ms(unsigned int time_ms) // ms단위 dealy를 위한 함수

{

    register unsigned int i;

    for(i=0;i<time_ms;i++)

    {

        delay_us(250); // 250us 딜레이(2^8=256까지 표현가능)

        delay_us(250);

        delay_us(250);

        delay_us(250); // 1ms 딜레이 표현

    }

}

 

int main(void)

{

    int i;

    MCUCR = 0x80 ; // 외부 메모리 사용

     

    while(1)

    {

        for(i=0;i<20;i++) // 0부터 .까지 표현하기 위한 for 구문

        {

            DIG_SELECT = 0xFF; // 모든 FND 선택

            ExtFndSet(i);

            delay_ms(200); // 200ms 지연

        }

    }

}


주석을 보면서 하나하나 분석해 나가도록 하세요!ㅎㅎ 설명하자면 8개의 FND에서 "0"부터 "."까지 표시를 하게 되는 것입니다.


 잘 나와죠??ㅎㅎ


그리고, 팁을 주자면 DIG_SELECT 즉, FND_CS와 FND_DATA를 잘 조절하여서 각 segment마다 다른 값들을 표시할 수도 있습니다!!


오늘도 공부하느라 수고하셨구요~!! 다음시간에는 키패드와 Segment를 활용한 실험들을 해볼 계획입니다!!


다음시간에 뵈요~



,

최근 댓글

최근 트랙백

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

링크

Yuria

카운터

Today :
Yesterday :
Total :