[Embedded Software] 경희대 임베디드 소프트웨어 과제2 - FND
on Study
개발 환경
- 개발보드 : JKIT-128-1
- MUC : ATmega128
- IDE : AVR Studio 4
- Compiler : WinAVR
실습 3
3.1 FND(Flexible Numeric Display: 7-Segment LED)를 이용하여 특정 숫자를 표시해보기(8888)
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
// FND에서 표시할 수 있는 문자를 배열로 미리 정의
unsigned char FND_DATA[ ]= {0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x27, 0x7f, 0x6f,
0x77, 0x7c, 0x39, 0x5e, 0x79,
0x71, 0x80, 0x40, 0x08};
// FND의 LED는 C포트에 연결되어 있으며,
// FND의 상태를 결정짓는 것은 G포트의 끝의 두 비트이다.
DDRC = 0xFF;
DDRG = 0x0F;
while(1) {
// FND는 output으로 사용되기 때문에 PORT를 사용한다.
PORTC = FND_DATA[8];
PORTG = 0x0f;
}
}
3.2 FND의 1개만 특정 숫자를 표시해 보기(7)
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
unsigned char FND_DATA[ ]= {0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x27, 0x7f, 0x6f,
0x77, 0x7c, 0x39, 0x5e, 0x79,
0x71, 0x80, 0x40, 0x08};
DDRC = 0xFF;
DDRG = 0x0F;
while(1) {
PORTC = FND_DATA[7];
PORTG = 0x01;
}
}
3.3 FND의 4개 숫자를 각각 다르게 표시해 보기 (AbCd)
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
unsigned char FND_DATA[ ]= {0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x27, 0x7f, 0x6f,
0x77, 0x7c, 0x39, 0x5e, 0x79,
0x71, 0x80, 0x40, 0x08};
DDRC = 0xFF;
DDRG = 0x0F;
while(1) {
// 4개의 FND에 서로 다른 값을 넣기 위해
// _delay_ms()를 사용한다.
// 사람의 눈이 인식하지 못할 정도의 딜레이를 주면
// 4개의 FND 동시에 작동하는 것처럼 보이게 할 수 있다.
PORTC = FND_DATA[13];
PORTG = 0x01;
_delay_ms(2);
PORTC = FND_DATA[12];
PORTG = 0x02;
_delay_ms(3);
PORTC = FND_DATA[11];
PORTG = 0x04;
_delay_ms(2);
PORTC = FND_DATA[10];
PORTG = 0x08;
_delay_ms(3);
}
}
3.4 FND를 사용하여 1ms마다 1씩 증가하는 1/100 초시계를 만든다.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
unsigned char FND_DATA[ ]= {0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x27, 0x7f, 0x6f};
unsigned int time = 0, time0, time1, time2, time3;
DDRC = 0xFF;
DDRG = 0x0F;
while(1) {
// time이 계속 증가하면서 자릿수를 바꾸기 위해 다음과 같이 정의한다.
time++;
time3 = (time/1000)%10;
time2 = (time/100)%10;
time1 = (time/10)%10;
time0 = time%10;
// 1/100 초 단위
PORTC = FND_DATA[time0];
PORTG = 0x01;
_delay_ms(2);
// 1/10 초 단위
PORTC = FND_DATA[time1];
PORTG = 0x02;
_delay_ms(3);
// 1초 단위
// FND의 점(0x80)을 찍어 자릿수를 구분하였다.
PORTC = FND_DATA[time2] | 0x80;
PORTG = 0x04;
_delay_ms(2);
// 10초 단위
PORTC = FND_DATA[time3];
PORTG = 0x08;
_delay_ms(3);
}
}
3.5 FND로 문장 표시해 보기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
// '042-486-0761'이라는 숫자가 한 글자씩 나타나다가,
// 끝까지 디스플레이 되면 왼쪽으로 한 칸씩 이동하여 표시하기 위한 배열이다.
// 처음 전압이 공급되었을 때 부터, 숫자가 오른쪽 끝에서 나오게 하기 위해
// 앞에 0x00을 3개 두어 초기화를 하였다.
// 마지막에 하나씩 사라질 때도 마찬가지이다.
unsigned char WORD_DATA[ ]= {0x00, 0x00, 0x00, 0x3f, 0x66,
0x5b, 0x40, 0x66, 0x7f, 0x7d,
0x40, 0x3f, 0x27, 0x7d, 0x06,
0x00, 0x00, 0x00, 0x00};
unsigned char count = 0, word0, word1, word2, word3;
unsigned int i, j;
DDRC = 0xFF;
DDRG = 0x0F;
while(1) {
for(i = 0; i < 16; i++) {
word0 = count % 16;
word1 = (count % 16) + 1;
word2 = (count % 16) + 2;
word3 = (count % 16) + 3;
for(j = 0; j < 100; j++) {
PORTC = WORD_DATA[word0];
PORTG = 0x08;
_delay_ms(2);
PORTC = WORD_DATA[word1];
PORTG = 0x04;
_delay_ms(3);
PORTC = WORD_DATA[word2];
PORTG = 0x02;
_delay_ms(2);
PORTC = WORD_DATA[word3];
PORTG = 0x01;
_delay_ms(3);
}
count++;
}
}
}
실습 응용
문제: FND로 1시간짜리 분/초 시계 만들어 보기
조건 : 왼쪽 2개는 분 표시, 오른쪽 2개는 초 표시. 가운데 점도 표시
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
unsigned char TEN_DATA[ ]= {0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x27, 0x7f, 0x6f};
unsigned char SIX_DATA[ ]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d};
unsigned int time = 0;
unsigned int sec0 = 0;
unsigned int sec1 = 0;
unsigned int min0 = 0;
unsigned int min1 = 0;
DDRC = 0xFF;
DDRG = 0x0F;
while(1) {
time++;
sec0 = (time/100)%10;
sec1 = (time/1000)%10;
if(sec0 > 9) {
sec1++;
}
if(sec1 > 5) {
time = 0;
min0++;
}
if(min0 > 9) {
time = 0;
min0 = 0;
sec1 = 0;
sec0 = 0;
min1++;
}
if(min1 > 5) {
min1 = 0;
}
PORTC = TEN_DATA[sec0];
PORTG = 0x01;
_delay_ms(2);
PORTC = SIX_DATA[sec1];
PORTG = 0x02;
_delay_ms(3);
PORTC = TEN_DATA[min0] | 0x80;
PORTG = 0x04;
_delay_ms(2);
PORTC = SIX_DATA[min1];
PORTG = 0x08;
_delay_ms(3);
}
}