AVR, ATmega128, ATmega 128, LED, ATmel Studio, ATmel Studio 7, 7Segment, 아두이노, 전자전기, FND


ATmega128로 FND 만들고 활용하기!



안녕하십니까?


하루 지나고 다시 글을 올리게 되었습니다.


그 전까지는 사실 배선도그렇고, 개념도 그렇고, 프로그래밍도 그렇고 사실 별로 그렇게 많이 어렵지 않아서 그냥 무작정 따라하기 3단계(배선! 프로그래밍! 실행!)이렇게 스파르타하게 달려왔다면 이번 것은 저도 굉장히 애를 먹었던 부분이라 조금 자세하게 설명하겠습니다.


그 전과는 뭔가 포스팅 분위기부터가 많이 달라졌죠? [몰아서 올리지 않아서 그렇습니다.]


오늘 해 볼것은 FND다루기 입니다.

FND는 Finite Numeric Display의 약자로써 7-Segment(이전 포스팅을 참조 해 주세요!)를 4개 붙여 놓은 것과 같은 형상입니다.


사실 FND와 7-Segment는 서로 교차되서 부르기도 하는데, 1자리 7-Segment를 FND로 부르기도 합니다. (사실 Finite Numeric이니까 길이 제한만 있으면 어떤 Display에 다 써도 될 것 같지만요...)


먼저 준비사항에 대하여 알아보겠습니다.


0] 준비

1) AVR

너무 당연. 항상 ATmega128을 사용하고 있습니다.

2) USB허브

깜빡하고 전 포스팅에서 언급하지 않았었는데, 따로 콘센트-플러그가 있는 USB 허브 제품(그냥 USB하나 달랑 컴퓨터에 꽂는 것이 아니라 거기에 추가로 220V 플러그가 추가로 달려있는)이 혹여 제품에 과도한 전류가 흘렀을 때도 컴퓨터에 영향을 주지 않는다고 합니다.

3) FND

이번에 사용할 모델은 HSN-5643AS-H 입니다. 4자리 7-Segment입니다.

핀은 아래와 같습니다.

여기서 D1, D2, D3, D4는 각 자리를 표시해주는 핀이며, A~G까지의 핀은 각 11, 7, 4, 2, 1, 10, 5에 매치됩니다. 3번 핀은 DP(Dot Point)입니다.

특히 이 모델은 공통 캐소드(CC) 방식으로 각 핀에 주어진 source전류가 한번에 Dx핀으로 빠져나갑니다.

즉, 8개 다 켜지면 sink 전류가 ATmega가 최대로 받아들일 수 있는 전류 100mA 보다 커지므로 필수적으로 저항을 설치해 줘야 합니다. 역기서는 A~DP까지 하나하나 저항을 달아주는 방법과, 각 Drain port에 큰 저항을 4개 써주는 방법이 있겠습니다. 저는 드레인 포트에 큰 저항을 4개 써 주었습니다.

보시면 아시겠지만 A~DP에 해당하는 핀이 1개씩밖에 없으므로 이 4개가 연속된 FND는 순차적으로 불을 켜서 표시하게 됩니다. 즉, 눈의 잔상효과로 인해 사실은 네개가 동시에 켜져있는 것이 아니지만, 인간은 한번에 다 켜져있다고 생각하게 되는 것이죠.

4) 10K 저항 *4

10K 저항을 Drain Port에 달아주었습니다. 너무 어두우면 1K 저항까지도 사용이 가능합니다.


항상 이론과 실제의 오차가 존재하듯이, 실수로 저항 없이 바로 연결이 된 적이 생겼었는데, 다행히도 어떤 부품도 상하지는 않았습니다만... 조심하시는 것이 좋을 것 같습니다.


1] 이 부품의 핀을 보고 배선을 해줍니다.

저번 7Segment와 동일하게 A~DP까지는 PORTA0~7에 연결하였습니다. 그리고 D1~4는 각 PORTG0~3에 연결하였습니다.

각 D1~D4까지는 저항을 달아주었습니다. 브레드보드(빵판)에서는 세로줄이 전부 연결이므로 핀 꽂을때 저항을 달면 옆으로 조금씩밀어주시면 되겠습니다. 같은 라인에 연결하면 전류가 저항 없이 다이렉트로 FND핀에 꽂힙니다. (이렇게 해서 저는 실수했었습니다.)


배선은 그다지 어렵지 않습니다. 그저 시간과 노가다가 오래 걸릴뿐...


2] 프로그래밍!!!!!!

대망의 프로그래밍입니다.

D1~D4는 전류가 빠져나가는 (-)입니다. 다시말해, PORTG0가 1이면 D1에서 전류를 못 흐르게 막는 다는 것이고, 이 말은 D1을 끈다는 소리와 같습니다. 그러면 PORTG0가 0이면 sink 포트가 되면서 전류가 흘러 해당하는 자리에 불이 들어오게 됩니다.

소스는 아래와 같습니다.


#include <avr/io.h>

#include <util/delay.h>

#define F_CPU 16000000UL


int d2b[10] = {0b00111111,

0b00000110,

0b01011011,

0b01001111,

0b01100110,

0b01101101,

0b01111101,

0b00100111,

0b01111111,

0b01101111};


int main(void)

{

    DDRA = 0xFF;

    DDRG = 0b00001111;

    int dp = 0b10000000;

    int flag = 0b00000000;

while(1){

for (int c=3 ; c<13 ; c++){

for (int k=0 ; k<50 ; k++){

for (int i=0 ; i<4 ; i++){

PORTA = d2b[(c-i)%10]|(dp&flag);

flag = ~flag;

PORTG = ~(0b1<<i);

_delay_ms(100);

}

}

flag = ~flag;

}

}

return 0;

}


저번 7segment에서는 각 핀이 (-)역할을 하였으므로 위에서 표시된 0b00111111을 비트 반전시켜서 포트에 출력했을 시 0이 나왔지만, 이번에는 각 핀이 (+) 단자이니 이 코드를 그대로 쓰겠습니다. d2b[0]~d2b[9]는 각 0~9를 나타냅니다.


A포트는 모든 핀을 출력핀으로 사용할 것이니 DDRA = 0xFF;로 모두 개방해줍니다.

G포트는 0~3 핀만 출력핀으로 사용할 것이니 DDRA = 0b00001111;로 첫 4개만 개방해줍니다. 여기서 PORT로 5V를 줬다 뺐다 하는 식으로 조작할 건데 이 부분을 DDR반전 시키고 PIN으로 처리해도 될 것은 같습니다만 제가 해보지 않아서 단정지을 수는 없을 것 같습니다.


dp와 flag는 저번 포스팅에서도 말씀드렸다시피 dp의 깜빡거림을 제어하기 위한 장치였기 때문에 dp와 flag를 모두 빼시고 보시면 더 소스가 간결해집니다. 여유가 되시는 분들은 한번 저 두 변수의 역할에 대해 생각해 보시는 것도 좋은 유흥이 될 것이라 생각합니다.


반복문은 가장 안쪽에서 부터 보는 것이 로직 이해해 도움이 됩니다.

가장 안쪽을 보면 4번 돌아가는 for문이 있는데, 이 것은 대충 눈치 채셨다시피 각 자릿수에 해당하는 것입니다. PORTG를 순서대로 개방하면서 각 PORTG에 해당하는 숫자를 PORTA로 지정해주는 것입니다. 저는 왼쪽으로 밀 것이기 때문에 10개 자릿 수 내에서 돌아가도록 10을 나눠주어 빙글빙글 돌렸습니다.

출력은 D4부터 D1순서로 돌아오므로 D4에 3이 나오게 하기 위해서 c변수를 3에서 출발시켰구요, 자릿수가 오름에 따라서 숫자를 하나씩 줄이기 위해서 c-i를 썼습니다.

_delay_ms()함수를 조절해보면 눈에서 이 문자가 덜 깜빡거리면서 동시에 켜져있는 것처럼 보이게 되는 지점이 있습니다. 대략 125면 어느정도 깜빡이는 수준 안에서 동시에 출력되는 것으로 보입니다. 저는 100이 가장 괜찮았습니다.

그 밖에서 50번 도는 for는 글자를 약 1초간 지속적으로 표시해주는 역할입니다. 왼쪽으로 미는 것처럼 보일 것이기 때문에 숫자가 바뀌는 부분과 표시하는 부분은 따로 진행이 되어야 합니다.

대망의 가장 바깥쪽 for문은 숫자를 증가시켜주는 역할입니다. 가장 오른쪽 숫자를 1씩 증가시키는데, 이렇게 디스플레이하면 왠지 숫자가 옆으로 진행하는 것 같죠.


이렇게 준비가 끝났습니다.

AVR에서 실행시켜보죠!


3] 실행!


자 이렇게 어려운 FND도 마무리 해 보았습니다.


다음에 다시 찾아뵙겠습니다.

+ Recent posts