Upload
others
View
6
Download
0
Embed Size (px)
Citation preview
ATmega128 FNDx4 제어 1
제06강
FNDx4 제어
FNDx4 제어
실습 및 과제
ATmega128 FNDx4 제어 2
FNDx4 제어
* 입출력 디바이스 제어 방법
-정적 제어(static control)
-동적 제어(dynamic control)
: 입출력 핀의 요구수를 줄일 수 있음.
: 시간차 제어( 주기적으로 refresh 필요 )
* FND 유형
: Common Anode
: Common Cathod
ATmega128 FNDx4 제어 3
FNDx4 제어(계속)
* FND 제어
: 1개 FND 제어에 8핀 요구함.
: 다수개의 FND의 동적 제어 방법
( p.156 그림 및 설명 참조 )
* 스위칭을 위한 전자적 제어 소자
: 쌍극 TR(bipolar junction transistor, BJT)
: NPN형과 PNP형 BJT( p.157 그림 참조 )
: 두 형에서 스위칭할 부하는 C에 연결
ATmega128 FNDx4 제어 4
FNDx4 제어(계속)
: NPN형 : if (VB>VE) then ON else OFF
: PNP형 : if (VB<VE) then ON else OFF (실습용)
ATmega128 FNDx4 제어 5
FNDx4 제어(계속) -회로구현할 것!!
* PNP형 TR,
PD7=Low,
select(ON)
ATmega128 FNDx4 제어 6
FNDx4 제어(계속)
* FNDx4(WCN4-XX40XX-A12) Pin Layout
ATmega128 FNDx4 제어 7
FNDx4 제어(계속)
* 패턴 코드 정의
7 6 5 4 3 2 1 0
dp g f e d c b a
예) "CPU" 패턴(정논리 경우)
문자 dp g f e d c b a Hexa'C' 0 0 1 1 1 0 0 1 39H'P' 0 1 1 1 0 0 1 1 73H'U' 0 0 1 1 1 1 1 0 3EH
* 16진수를 표시위한 코드표(p.160 표 참조, 정논리)
ATmega128 FNDx4 제어 8
실습과제
[실습1] FNDx4 제어 I (p.161 참조)
: 7 8 3 4 문자 패턴을 출력
//======================================// [실습1] p.161// "7834" Display//======================================#include <avr/io.h>#include <util/delay.h>
static unsigned char SegTable[17] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6F, 0x77, 0x7C, 0x58, 0x5E, 0x79, 0x71, 0x00 };
int main() {unsigned char cnumber[4] = {4, 3, 8, 7};int j=0;
DDRA = 0xFF;DDRD |= 0xF0; // 상위니블만 출력으로 변경while(1) {
for(j=0; j<4; j++) {
ATmega128 FNDx4 제어 9
PORTD = ~(0x10<<j); // 0b00010000PORTA = ~SegTable[cnumber[j]];_delay_ms(5); // 5msec
}}
}
보완1) 시간지연을 0, 5, 10msec 변경하여 그 결과를 관찰
보완2) 시간지연을 20, 30msec로 변경하여
결과를 관찰할 수 있도록 보완
( _delay_ms() 함수는 16msec까지만 가능)
보완3) 위 소스에서 아래와 같이 변경시, 동일 기능토록 보완..
...... cnumber[4] = {7, 8, 3, 4};
ATmega128 FNDx4 제어 10
실습과제(계속)
[실습2] FNDx4 제어 II (p.162 참조)
: 십진수 7834를 표시
: 나머지 연산자(%) 활용int num = 7834;j = 0;while (num) {
cnumber[j++] = num % 10;num /= 10;
}
관찰) 수치 78을 표시해보자!! '0078'로 표시된다.
앞의 0을 보이지 않도록 하자!!cnumber[0] = 0;
for(j=1; j<4; j++)
cnumber[j] = 16; // 패턴 16
보완) 수치값을 다양한 진법체계(8진수, 10진수, 16진수)로
표현토록 일반화하여, 함수로 구현( p.163 참조 )
ATmega128 FNDx4 제어 11
실습과제(계속)
[실습3] FNDx4 제어 III
: FND 제어와 관련한 패턴데이터, 변수, 함수 등을
별도 파일로 작성하여 라이브러리화 하자!!
( seg7.c, seg7.h, p.169~171 소스 참조 )
* file : seg7.h
//================================// seg7.h p.171//================================#ifndef __SEG7_H__#define __SEG7_H__
void Seg7Init(void);void Seg7DispNum(unsigned short num, unsigned short radix);
#endif
ATmega128 FNDx4 제어 12
* file : seg7.c
//================================// seg7.c p.169//================================#include <avr/io.h>#include <util/delay.h>#include "seg7.h"
#define N_BUF 5#define N_SEGMENT 4
#define SSEG_CONT PORTD#define DDR_CONT DDRD#define SSEG_DATA PORTA#define DDR_DATA DDRA
#define CONT_MASK ((1<<PD7) | (1<<PD6) | (1<<PD5) | (1<<PD4))#define OUTPUT_VALUE (1<<PD4)
static unsigned char SegTable[18] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6F, 0x77, 0x7C, 0x58, 0x5E, 0x79, 0x71, 0x00, 0b01000000
};
static unsigned char cnumber[N_BUF] = {16};
void Seg7Init(void) {
ATmega128 FNDx4 제어 13
SSEG_CONT |= CONT_MASK;
DDR_CONT |= CONT_MASK;DDR_DATA = 0xFF;
}
void Seg7DispNum(unsigned short num, unsigned short radix) {int j;
// 값없는 자리 표시없게...cnumber[0] = 0;for(j=1; j<N_BUF; j++)
cnumber[j] = 16;
j = 0;while (num) {
cnumber[j++] = num % radix;num /= radix;
}
for(j=0; j<N_SEGMENT; j++) {SSEG_CONT = (SSEG_CONT & ~CONT_MASK) |
(~(OUTPUT_VALUE<<j) & CONT_MASK);SSEG_DATA = ~SegTable[cnumber[j]];_delay_ms(5); // 5msec
}}
ATmega128 FNDx4 제어 14
* main() file
//======================================// [실습3] p.167// 숫자 205 표시// using user library(seg7.h, seg7.c)//======================================#include <avr/io.h>#include "seg7.h"
int main() {unsigned short data = 205;
Seg7Init();
while(1) {Seg7DispNum(data, 10);
}}
ATmega128 FNDx4 제어 15
ATmega128 FNDx4 제어 16
실습과제(계속)
[실습4] FNDx4 제어 IV
: 1sec 마다 수치값을 증가시켜 FND에 표시(초시계기능)
//======================================// [실습4] p.171// 숫자값을 1sec마다 바꾸어가면서 표시// using user library(seg7.h, seg7.c)//======================================#include <avr/io.h>#include <util/delay.h>#include "seg7.h"
void msec_delay(int n) {for( ; n>0; n--)
_delay_ms(1);}
int main() {unsigned short data = 0;
Seg7Init();
ATmega128 FNDx4 제어 17
while(1) {msec_delay(1000); //시간지연 1secSeg7DispNum(data, 10);data++;
}}
* 결과 관찰! 문제있다!
해결책)
: 타이머/카운터 인터럽트 활용
(FND 동적표시를 ISR에서 수행)
ATmega128 FNDx4 제어 18
실습과제(계속)
[실습5] FNDx4 제어 V ( p.175~178 참조 )
: 1sec 마다 수치값을 증가시켜 FND에 표시(초시계기능)
: 타이머/카운터 인터럽트 활용
(FND 동적표시를 ISR에서 수행)
: [실습3]의 seg7.c, seg7.h을 인터럽트 취급하도록 변경
==> iseg7.c, iseg7.h
: 타이머/카운터 0, CTC모드, 비교일치인터럽트 활용
: 5msec마다 FND 자리이동하여 표시
//======================================// [실습5] p.175// 숫자값을 1sec마다 바꾸어가면서 표시// using user library(iseg7.h, iseg7.c)//======================================
ATmega128 FNDx4 제어 19
#include <avr/io.h>#include <util/delay.h>#include "iseg7.h"
void msec_delay(int n) {for( ; n>0; n--)
_delay_ms(1);}
int main() {unsigned short data = 0;
ISeg7Init();sei();
while(1) {msec_delay(1000); // 시간지연 1secISeg7DispNum(data, 10);data++; // 1씩증가
}}
//================================// iseg7.h p.178//================================#ifndef __ISEG7_H__#define __ISEG7_H__
ATmega128 FNDx4 제어 20
void ISeg7Init(void);void ISeg7DispNum(unsigned short num, unsigned short radix);
#endif
//================================// iseg7.c p.176~//================================#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>#include "iseg7.h"
#define N_BUF 5#define N_SEGMENT 4
#define SSEG_CONT PORTD#define DDR_CONT DDRD#define SSEG_DATA PORTA#define DDR_DATA DDRA
#define CONT_MASK ((1<<PD7) | (1<<PD6) | (1<<PD5) | (1<<PD4))#define OUTPUT_VALUE (1<<PD4)
static unsigned char SegTable[18] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6d, 0x7d, 0x07,
ATmega128 FNDx4 제어 21
0x7f, 0x6F, 0x77, 0x7C, 0x58, 0x5E, 0x79, 0x71, 0x00, 0b01000000 };
static unsigned char cnumber[N_BUF] = {16, 16, 16, 16, 16};
void ISeg7Init(void) {SSEG_CONT |= CONT_MASK;
DDR_CONT |= CONT_MASK;DDR_DATA = 0xFF;
TCCR0 = (1<<WGM01); // 00001000, CTC, OC0비사용, stopOCR0 = 77; // 5msec, 78.125TIMSK |= (1<<OCIE0); // 비교일치허용TCCR0 |= 0x07; // 1024분주비로 run
}
void ISeg7DispNum(unsigned short num, unsigned short radix) {int j;int min, sec;
TIMSK &= ~(1<<OCIE0); // 비교일치인터럽트 금지
// 값없는 자리 표시없게...cnumber[0] = 0;for(j=1; j<N_BUF; j++)
cnumber[j] = 16;
ATmega128 FNDx4 제어 22
j = 0;while (num) {
cnumber[j++] = num % radix;num /= radix;
}
// for(j=0; j<N_SEGMENT; j++) {// SSEG_CONT = (SSEG_CONT & ~CONT_MASK) |// (~(OUTPUT_VALUE<<j) & CONT_MASK);// SSEG_DATA = ~SegTable[cnumber[j]];// _delay_ms(5); // 5msec// }
TIMSK |= (1<<OCIE0); // 비교일치인터럽트 허용}
ISR(TIMER0_COMP_vect) {static int index = 0;
SSEG_CONT = (SSEG_CONT & ~CONT_MASK) |(~(OUTPUT_VALUE<<index) & CONT_MASK);
SSEG_DATA = ~SegTable[cnumber[index]];
index++;if(index==N_SEGMENT)
index = 0;}
ATmega128 FNDx4 제어 23
실습과제(계속)
[과제1] FNDx4 제어 I
: 3자리의 숫자(음수포함)를 표시
: 음수의 경우 최상위 FND에 '-'를 표시
ATmega128 FNDx4 제어 24
실습과제(계속)
[과제2] 분/초 시계
: [실습5] 소스 활용
: 상위 2자리 FND는 분을,
하위 2자리 FND는 초를 표시하도록....
ATmega128 FNDx4 제어 25
실습과제(계속)
[과제2] FNDx4 제어 II
: 문자열 출력
: p.167 과제2 참조