Transcript FND 실습 2
마이크로프로세서설계 – 8
FND (7-segment) 출력 실습 2
시스템및센서네트워크연구실
1
ATmega128
시스템및센서네트워크연구실
2
LED sink / 스위치 풀업 회로
470
5V
PC0
+5V
PC1
…..
10K
PC7
PD2
104 (0.1uF)
시스템및센서네트워크연구실
3
FND 회로
PB0
1
5
B
C
PA1
6
1K
FND
PA0
10
E
+5V
…..
PA7
시스템및센서네트워크연구실
4
시스템및센서네트워크연구실
5
FND (7-segment) 출력 연습
- FND 회로
- FND 실습
시스템및센서네트워크연구실
6
PORT 입력 관련 레지스터
IO register
PORTx (port x data register) : 포트 x 데이터 출력 레지스터
• 초기값 0
DDRx (port x data direction register) : 포트 x 데이터 방향 설정 레지스터
• 초기값 0
PINx (port x pin input address) : 포트 x 입력 레지스터
• 초기값 N/A
• 읽기만 가능
포트핀의 동작 상태
DDRx – 1, PORTx – 0 : 출력, low 출력 (sink 출력 회로)
DDRx – 1, PORTx – 1 : 출력, high 출력 (source 출력 회로)
DDRx – 0, PINx – 0 : 입력, low 입력 (풀업 저항)
DDRx – 0, PINx – 1 : 입력, high 입력 (풀다운 저항)
시스템및센서네트워크연구실
7
실습 1
// SW1을 누르면, FND1에 랜덤 숫자 출력
#include <stdlib.h>
// rand 함수 정의 헤더 파일
char seg_pat[16]= {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
int key, oldkey, num=0;
DDRA = 0b11111111;
DDRB = 0b00000001;
DDRD = 0b00000000;
oldkey = PIND & 0b00000100;
PORTB = 0b00000000;
// PA 출력 설정
// PB0 출력 설정 (FND1)
// PD2 입력 설정 (SW1)
// SW1 상태 추출
// PB0 = 0 : FND1 활성화
PORTA = seg_pat[num];
while(1){
// while(1) : 무한 루프
key = PIND & 0b00000100; // PD2 값 읽어오기 – 비트 마스킹 기능
if(oldkey != 0 && key == 0) {
num = (char) (rand() % 10); // 랜덤 숫자를 10으로 나머지 연산을 수행. 결과는 0 – 9
}
PORTA = seg_pat[num];
oldkey = key;
delay_ms(20);
}
시스템및센서네트워크연구실
8
실습 2
// SW1을 누르면, FND1, FND2에 각각 랜덤 숫자 출력
#include <stdlib.h>
// rand 함수 정의 헤더 파일
char seg_pat[16]= {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
int key, oldkey, num1=0, num2=0;
DDRA = 0b11111111;
DDRB = 0b00000011;
DDRD = 0b00000000;
oldkey = PIND & 0b00000100;
PORTB = 0b00000000;
// PA 출력 설정
// PB0, PB1 출력 설정 (FND1, 2)
// PD2 입력 설정 (SW1)
// SW1 상태 추출
// PB0, BP1 = 0 : FND1, FND2 활성화
while(1){
// while(1) : 무한 루프
key = PIND & 0b00000100; // PD2 값 읽어오기 – 비트 마스킹 기능
if(oldkey != 0 && key == 0) {
num1 = (char) (rand() % 10); // 랜덤 숫자를 10으로 나머지 연산을 수행. 결과는 0 – 9
num2 = (char) (rand() % 10);
}
PORTB = 0b00000010;
// FND1 활성화 (PB0=0, PB1=1)
PORTA = seg_pat[num1];
delay_ms(10);
PORTB = 0b000000001;
PORTA = seg_pat[num2];
delay_ms(10);
시스템및센서네트워크연구실
// FND2 활성화 (PB1=0, PB0=0)
oldkey = key;
}
9
함수
함수는 문제 해결의 방법
주어진 문제를 작은 문제, 즉 여러 함수로 나누어 생각할 수 있으므로
함수를 만드는 것은 문제 해결의 하나의 방법
함수 이용의 장점
함수로 구성된 프로그램은 함수 단위로 구성되어 있어, 읽기 쉽고, 이
해하기 쉬움
이미 정의된 함수는 여러 번 호출이 가능하므로 소스의 중복을 최소화
하여 프로그램의 양을 줄이는 효과
Structured Program
적절한 함수로 잘 구성된 프로그램을 모듈화 프로그램(Modular
Program), 구조화된 프로그램(Structured Program)
한 번 잘 구현된 함수는 라이브러리 함수와 같이 여러 프로그램에서 손
쉽게 이용이 가능
이러한 함수 중심의 구조화 프로그램 방식을 절차적 프로그래밍
(Procedural Programming) 방식
시스템및센서네트워크연구실
10
함수 이용의 2가지 형태
함수가 존재하는 프로그램의 두 가지 형태
시스템및센서네트워크연구실
11
함수 원형
함수 원형
함수를 사용(호출)하기 이전에 함수의 머리(헤더) 부분을 기술하는 단계
함수 원형의 기술 방법이 다음 두 가지 방법으로 가능
자료유형 목록을 변수 선언 하듯이 변수유형과 변수이름이 함께 나오는 방식
• 함수 반환값 자료유형이 나오고 빈 공간을 띄운 후 적당한 함수이름이 나
타냄
• 괄호 ()안에는 인자 목록이 기술되고, 마지막으로 세미콜론(;)으로 종료
시스템및센서네트워크연구실
12
함수의 정의
함수의 정의(구현)는 함수의 머리(header)와 몸체(body)로 구성
함수의 머리(헤더)는 함수의 반환값 자료유형과 함수의 이름, 그리고 괄호
사이에 인자 목록으로 구성
시스템및센서네트워크연구실
13
함수정의 자료유형
반환 값, 인자 자료 유형
우리가 학습한 모든 기본 자료 유형을 반환 값이나 인자의 자료유형으
로 이용 가능
• 즉 char,int등이 가능
키워드 void
반환 값이 없는 경우에는 void라는 키워드를 이용
인자가 하나도 없는 경우에는 void라는 키워드를 인자 목록에 기술하
여 이용
반환 값을 아예 생략하는 것은 반환 값이 int 형을 의미
반환 값을 생략하는 프로그램 코딩 방법은 적절하지 못한 방법으로, 반
환 값을 반드시 기술하도록
void printKorea(void)
{
PORTA = 0xFF;
}
시스템및센서네트워크연구실
14
함수 호출
주의
인자가 없는 함수를 호출하더라도 반드시 함수이름과 중괄호를 이용하
여 함수를 호출해야 한다.
반환 값이 있는 함수는 반환 값을 적절히 이용
resultMult = mult(8, 10);
resultSum = sum();
시스템및센서네트워크연구실
15
실습 3
// FND1, FND2에 10진수 0-99까지 0.5초 간격으로 출력
// 얼마 간격으로 증가되는가?
// 0-59까지 증가시키려면, 어떻게 해야 하는가?
void seg_out(int num);
char seg_pat[16]= {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
void seg_out(int num)
{
int i, N10, N1;
void main(void)
{
int num=0;
DDRA = 0b11111111;
// PA 출력 설정
DDRB = 0b00000011;
// PB0, PB1 출력 설정
while(1){
// while(1) : 무한 루프
seg_out(num);
N10 = num / 10;
N1 = num % 10;
for(i = 0;i < 24;i++){
PORTB = 0b00000010;
PORTA = seg_pat[N1];
delay_ms(10);
// 두 자리 정수 출력 함수
num++;
// 두 자리 정수 출력
// 10자리 추출
// 1자리 추출
// FND1 활성화 (PB0=0, PB1=1)
if(num > 99) num = 0; // if(num > 59) num = 0;
PORTB = 0b000000001;
PORTA = seg_pat[N10];
delay_ms(10);
}
}
// FND2 활성화 (PB1=0, PB0=0)
}
}
시스템및센서네트워크연구실
16
실습 4
// SW1을 누르면, FND1 - FND2 1씩 증가 (0 -> 59로 증가)
void seg_out_set(int num);
char seg_pat[16]= {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
char key, oldkey;
int num=0;
DDRA = 0b11111111;
DDRB = 0b00000011;
DDRD = 0b00000000;
oldkey = PIND & 0b00000100;
// PA 출력 설정
// PB0 출력 설정 (FND1)
// PD2 입력 설정 (SW1)
// SW1 상태 추출
void seg_out_set(int num)
{
int N10, N1;
while(1){
// while(1) : 무한 루프
key = PIND & 0b00000100; // PD2 값 읽어오기 - 비트 마스킹 기능
if(oldkey != 0 && key == 0) {
num++;
if(num > 60) num = 0;
}
seg_out_set(num);
oldkey = key;
}
N10 = num / 10;
N1 = num % 10;
// 두 자리 정수 출력
// 10자리 추출
// 1자리 추출
PORTB = 0b00000010; // FND1 활성화 (PB0=0, PB1=1)
PORTA = seg_pat[N1];
delay_ms(10);
PORTB = 0b000000001; // FND2 활성화 (PB1=0, PB0=0)
PORTA = seg_pat[N10];
delay_ms(10);
}
시스템및센서네트워크연구실
17
실습 5
// SW1을 누르면, FND1-FND2 1씩 증가, SW2를 누르면, FND1-FND2 1씩 감소 (0에서 59까지 변화)
char key, oldkey;
int num=0;
DDRA = 0b11111111;
// PA 출력 설정
DDRB = 0b00000011;
// PB0, PB1 출력 설정 (FND1, FND2)
DDRD = 0b00000000;
// PD2, PD3 입력 설정 (SW1, SW2)
oldkey = PIND & 0b00001100;
// SW1 상태 추출 -> 누르지 않았으므로, 0b00001100
while(1){
key = PIND & 0b00001100;
if(oldkey != key) {
switch(key) {
case 0b00001000 :
num++;
break;
case 0b00000100 :
num--;
break;
default:
break;
if(num > 59) num = 0;
if(num < 0) num = 59;
}
oldkey = key;
}
seg_out_set(num);
}
시스템및센서네트워크연구실
// while(1) : 무한 루프
// PD2, PD3 값 읽어오기 - 비트 마스킹 기능
// 키 값에 변화가 있는 지를 체크, 변화가 있는 경우 switch문 실행
// SW1이 눌러진 경우, PD2=0, PD3=1
// SW2가 눌러진 경우, PD2=1, PD3=0
// 스위치가 눌러지지 않은 경우
18
실습 6
default:
// SW1을 누르면, FND1 또는 FND2 증가
// SW2를 이용하여 FND1이나 FND2를 선택
// SW2를 누른 후 SW1을 누르면 FND2 증가, 다시 SW2를 누른 후 SW1을 누르면 FND1 증가
break;
}
oldkey = key;
void seg_out_sel(int num1, int num2);
char key, oldkey;
int num1=0, num2=0, loc=0;
DDRA = 0b11111111;
DDRB = 0b00000011;
DDRD = 0b00000000;
oldkey = PIND & 0b00001100;
// 스위치가 눌러지지 않은 경우
}
seg_out_sel(num1, num2);
}
// PA 출력 설정
// PB0, PB1 출력 설정 (FND1, FND2)
// PD2, PD3 입력 설정 (SW1, SW2)
// SW1 상태 추출
while(1){
// while(1) : 무한 루프
key = PIND & 0b00001100; // PD2, PD3 값 읽어오기 - 비트 마스킹 기능
if(oldkey != key) {
// 키 값에 변화가 있는 지를 체크
switch(key) {
case 0b00001000 :
// SW1이 눌러진 경우, PD2=0, PD3=1
if(loc == 0) num1++;
if(loc == 1) num2++;
if(num1 > 9) num1 = 0;
if(num2 > 9) num2 = 0;
break;
case 0b00000100 :
// SW2가 눌러진 경우, PD2=1, PD3=0
loc ^= 1;
break;
시스템및센서네트워크연구실
void seg_out_sel(int num1, int num2) // 두 자리 정수 출력
{
PORTB = 0b00000010; // FND1 활성화 (PB0=0, PB1=1)
PORTA = seg_pat[num1];
delay_ms(10);
PORTB = 0b000000001; // FND2 활성화 (PB1=0, PB0=0)
PORTA = seg_pat[num2];
delay_ms(10);
}
19