FND 실습 2

Download Report

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