제목: [Intel] 엣지 AI SW 아카데미
부제목: 14일차
일정: 2023.11.14(화)
수업 내용:
- C언어 프로그래밍
- Micro Processor 원리
- Atmel사의 8bit Micro-controller
- KUT0128 Evaluation Board 기능과 특징
- External Interrupt 제어
목표:
External Interrupt 제어
//외부 Interrupt 4 를 이용하여 SW/INT4를 누를 때마다 (falling edge),
//맨 우측 7-Segment의 표시 값이 0 1 2 3… 9 0 1.. 이
//표시되도록 프로그램을 작성하라.
//(예제 4-4) 외부 Interrupt 4에 의한 스위치 입력 실험 (응용)
• EIMSK = 0b00010000; // Interrupt 4 enable
• EICRB = 0b00000010; // Interrupt 4 falling edge
• SREG = 0x80; // Global Interrupt bit set
: MSB=1 SREG = 0x80
#include <mega128.h>
#include <delay.h>
const char seg_pat[10]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
unsigned char N1 = 0;
void main(void)
{
DDRB = 0xF0; // 포트 B 상위 4비트 출력 설정
DDRD = 0xF0; // 포트 D 상위 4비트 출력 설정
DDRG = 0x0F; // 포트 G 하위 4비트 출력 설정
// 인터럽트 초기화
EIMSK = 0b00010000; // 외부 인터럽트4 enable
EICRB = 0b00000010; // 외부 인터럽트4 : falling edge
SREG = 0x80; // 전역 인터럽트 enable-bit set
PORTG = 0b00001000; // 맨 우측 7-Segment DIG4 ON(PG3=1)
while(1) {
PORTD = ((seg_pat[N1] & 0x0F) << 4) | (PORTD & 0x0F); // A, B, C, D 표시
PORTB = (seg_pat[N1] & 0x70 ) | (PORTB & 0x0F); // E, F, G 표시
}
}
//(예제 4-5) 2개의 외부 Interrupt 를 이용한 10진 네 자리 입력 실험
• 두 개의 스위치 SW/INT4와 SW/INT5만을 이용하여 4자리를 입력하는 프로그램을 작성하라.
• 여기서, SW/INT5는 입력될 자리(위치)를 나타내고,
• SW/INT4 눌려지면 현재 선택된 자리의 값을 +1하도록 한다.
• SW/INT5가 눌려지면 입력될 위치를
1자리 10자리 100자리 1000자리 1자리 10자리..로 이동하도록 한다
#include <mega128.h>
#include <delay.h>
typedef unsigned char U8;
const U8 seg_pat[10]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f};
U8 N1 = 0, N10 = 0, N100 = 0, N1000 = 0; // 0 : 1자리, 1 : 10자리 , 2 : 100자리 , 3 : 1000자리
U8 pos = 0;
void Seg4_out(void); // 네 자리수 7-Segment 출력
void main(void)
{
DDRB = 0xF0; // 포트 B 상위 4비트 출력 설정
DDRD = 0xF0; // 포트 D 상위 4비트 출력 설정
DDRG = 0x0F; // 포트 G 하위 4비트 출력 설정
EIMSK = 0b00110000; // 외부 인터럽트 4,5 enable
EICRB = 0b00001010; // 외부 인터럽트 4,5 : falling edge
SREG = 0x80; // 전역 인터럽트 enable-bit set
while(1)
{
Seg4_out();
}
}
void Seg4_out(void)
{
PORTG = 0b00001000; // 7-Seg DIG4 ON(PG3=1), 1자리 표시
PORTD = ((seg_pat[N1] & 0x0F) << 4) | (PORTD & 0x0F); // A, B, C, D 표시
PORTB = (seg_pat[N1] & 0x70 ) | (PORTB & 0x0F); // E, F, G 표시 PORTD 하위 4bits 변경되지 않게 OR
delay_ms(5);
PORTG = 0b00000100; // 7-Seg DIG3 ON(PG2=1), 10자리 표시
PORTD = ((seg_pat[N10] & 0x0F) << 4) | (PORTD & 0x0F); // A, B, C, D 표시
PORTB = (seg_pat[N10] & 0x70 ) | (PORTB & 0x0F); // E, F, G 표시 PORTD 하위 4bits 변경되지 않게 OR
delay_ms(5);
PORTG = 0b00000010; // 7-Seg DIG2 ON(PG1=1), 100자리 표시
PORTD = ((seg_pat[N100] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[N100] & 0x70 ) | (PORTB & 0x0F); //PORTD 하위 4bits 변경되지 않게 OR
delay_ms(5);
PORTG = 0b00000001; // 7-Seg DIG1 ON(PG0=1), 1000자리 표시
PORTD = ((seg_pat[N1000] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[N1000] & 0x70 ) | (PORTB & 0x0F); //PORTD 하위 4bits 변경되지 않게 OR
delay_ms(5);
}
// 외부 인터럽트4 서비스 루틴
interrupt [EXT_INT4] void external_int4(void)
{
if(pos == 0) N1 = (N1 + 1) % 10; // 1자리 +1
else if(pos == 1) N10 = (N10 + 1) % 10; // 10자리 +1
else if(pos == 2) N100 = (N100 + 1) % 10; // 100자리 +1
else N1000 = (N1000 + 1) % 10; // 1000자리 +1
}
// 외부 인터럽트5 서비스 루틴
interrupt [EXT_INT5] void external_int5(void)
{
pos = (pos + 1) % 4; // 입력 자리 이동
}
(예제 4-6) 외부 Interrupt 를 이용한 간이 시계 실험
#include <mega128.h>
#include <delay.h>
typedef unsigned char U8;
const U8 seg_pat[10]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
U8 N1, N10, N100, N1000;
U8 pos = 0;
U8 hour = 12, min = 0, sec = 0;
void Time_out(void); // 시간 표시 함수
void main(void) {
unsigned char i;
DDRB = 0xF0;
DDRD = 0xF0;
DDRG = 0x0F;
EIMSK = 0b00110000; // 외부 인터럽트 4,5 enable
EICRB = 0b00001010; // 외부 인터럽트 4,5 falling edge
SREG = 0x80; // 전역 인터럽트 enable-bit set
while(1) {
for(i = 0;i < 49;i++) {
Time_out(); // 약 1초간 반복 표시
} // end of for
sec = sec + 1; // 초값 +1
if(sec == 60) {
sec = 0;
min = min + 1; // 분값 +1
if(min == 60) {
min = 0;
hour = (hour + 1) % 24; // 시간 +1
} // end of min
} // end of sec
} //end of while
} //end of main
void Time_out(void) // display
{
PORTG = 0b00001000; // 7-Seg DIG4 ON(PG3=1), 분 1자리 표시
PORTD = ((seg_pat[min % 10] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[min % 10] & 0x70 ) | (PORTB & 0x0F);
delay_ms(5);
PORTG = 0b00000100; // 7-Seg DIG3 ON(PG2=1), 분 10자리 표시
PORTD = ((seg_pat[min / 10] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[min / 10] & 0x70 ) | (PORTB & 0x0F);
delay_ms(5);
PORTG = 0b00000010; // 7-Seg DIG2 ON(PG1=1), 시간 1자리 표시
PORTD = ((seg_pat[hour % 10] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[hour % 10] & 0x70 ) | (PORTB & 0x0F);
delay_ms(5);
PORTG = 0b00000001; // 7-Seg DIG1 ON(PG0=1), 시간 10자리 표시
PORTD = ((seg_pat[hour / 10] & 0x0F) << 4) | (PORTD & 0x0F);
PORTB = (seg_pat[hour / 10] & 0x70 ) | (PORTB & 0x0F);
delay_ms(5);
}
interrupt [EXT_INT4] void external_int4(void)
{
N1 = min % 10; // 현재 분 1자리 추출
N10 = min / 10; // 현재 분 10자리 추출
N100 = hour % 10; // 현재 시간 1자리 추출
N1000 = hour / 10; // 현재 시간 10자리 추출
if(pos == 0) N1 = (N1 + 1) % 10; // 현재 분 1단위 표시 +1 값
else if(pos == 1) N10 = (N10 + 1) % 6; // 현재 분 10단위 표시 +1 값 (60분)
else if(pos == 2) { // 시간 1단위 +1
if(N1000 == 2) N100 = (N100 + 1) % 4; // 24시간의 앞자리 2이므로 20,21,22,23,24
else N100 = (N100 + 1) % 10; // 0,1,2,3,-9,10 ,11,12,-,18, 19
}
else { // pos=3 (세 번 눌러짐)
if(N100 < 4) N1000 = (N1000 + 1) % 3; // N100<4은 04 (00,01,02,03), (10,11,12,13),
// else if(N1000 != 1) N1000 = (N1000 + 1) % 3;
else N1000 = (N1000 + 1) % 2;
}
hour = N1000 * 10 + N100; // 시간 계산 (시간 세팅 값을 void Time_out(void) 로,
min = N10 * 10 + N1; // 분 계산
}
interrupt [EXT_INT5] void external_int5(void)
{
pos = (pos + 1) % 4; // 입력 자리 이동
}
'[Intel] 엣지 AI SW 아카데미 > 펌웨어 프로그래밍 75hour' 카테고리의 다른 글
[Intel] 엣지 AI SW 아카데미 17일차 (부산상공회의소 인력개발원) (0) | 2023.11.30 |
---|---|
[Intel] 엣지 AI SW 아카데미 15일차 (부산상공회의소 인력개발원) (0) | 2023.11.30 |
[Intel] 엣지 AI SW 아카데미 13일차 (부산상공회의소 인력개발원) (0) | 2023.11.30 |
[Intel] 엣지 AI SW 아카데미 12일차 (부산상공회의소 인력개발원) (0) | 2023.11.30 |
[Intel] 엣지 AI SW 아카데미 11일차 (부산상공회의소 인력개발원) (1) | 2023.11.30 |