A :
#include<avr/io.h>
void main() {
DDRE=0xFB;
TCCR3A = 0x32;
TCCR3B = 0x19;
ICR3 = 60000;
OCR3B = ICR3 / 2;
}
A :
#include<avr/io.h>
#include<avr/signal.h>
마. 부저 제어하기
부저 (Buzzer)란 전기 신호를 소리로 변환시켜 주는 장치이다. 부저에는 내부에 전자석과 진동을 일으키는 판으로 이루어져 있으며, 전자석이 진동판을 아주 빠르 게 흔들어 소리를 발생 시키는 원리를 가지고 있다. 그래서 부저에 음을 출력하면 PWM 파형의 길이에 따라 음의 높이가 다르게 출력이 되는 것이다. 또한, 일반 스 피커와는 달리 출력 주파수의 범위가 한정되어 있어 주로 단순한 용도로 사용된다.
간단한 타이머/카운터를 이용하여 PWM 주파수를 생성한 뒤 부저에 입력하여 음 을 출력해보자.
1) 활용 실습
Q : 6.4_ 음계 ‘도’음을 출력하기
Q : 6.5_ 도트매트릭스의 전체가 1초에 한 번씩 깜박이고, 부저의 ‘도’음이 동시에 출력하게 하기
unsigned char count, data;
void main(void) {
DDRA=0xFF;
DDRC=0xFF;
DDRE=0xFB;
TCCR0=0x07;
TCNT0=0xFF-157;
TIMSK=0x01;
TIFR|=0x01;
TCCR3A = 0x32;
TCCR3B = 0x19;
ICR3 = 60000;
OCR3B = ICR3 / 2;
sei();
while(1) {
PORTA=0xFF;
PORTC=data;
}
}
SIGNAL(TIMER0_OVF_vect) {
cli();
TCNT0=0xFF-157;
count++;
if(count==100)
{
data=0xFF;
count=0;
}else {
data=0x00;
} sei();
}
A :
#include<avr/io.h>
#include<avr/signal.h>
unsigned char count;
unsigned int data=0;
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2000; i++) for(j=0; j<k; j++);
}
void buzzer(unsigned int s) {
if(s==1) {
ICR3 = 50000;
OCR3B = ICR3 / 2;
}else if(s==2) {
Q : 6.6_ 부저의 8옥타브를 1초에 한 번씩 올려가며 출력하기
ICR3 = 45000;
OCR3B = ICR3 / 2;
}else if(s==3) {
ICR3 = 40000;
OCR3B = ICR3 / 2;
}else if(s==4) {
ICR3 = 35000;
OCR3B = ICR3 / 2;
}else if(s==5) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==6) {
ICR3 = 31000;
OCR3B = ICR3 / 2;
}else if(s==7) {
ICR3 = 29000;
OCR3B = ICR3 / 2;
}else if(s==8) {
ICR3 = 27000;
OCR3B = ICR3 / 2;
} }
void main(void) {
DDRA=0xFF;
DDRC=0xFF;
DDRE=0xFB;
TCCR0=0x07;
TCNT0=0xFF-145;
TIMSK=0x01;
TCCR3A = 0x32;
TCCR3B = 0x19;
TIFR|=0x01;
sei();
while(1){}
}
SIGNAL(TIMER0_OVF_vect) {
cli();
TCNT0=0xFF-145;
count++;
if(count==100) {
data++;
buzzer(data);
count=0;
if(data==8) {
data=0;
} }
sei();
}
Q : 6.7_ ‘학교 종’노래를 부저로 출력하며, 도트매트릭스 가로 열을 한 줄씩 올리기(단, 가로 열 LED는 출력 후 꺼져야 함)
A :
#include<avr/io.h>
#include<avr/signal.h>
unsigned char count;
unsigned int data=0;
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2000; i++) for(j=0; j<k; j++);
}
void buzzer(unsigned int s) {
if(s==1) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==2) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==3) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==4) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==5) {
ICR3 = 31000;
OCR3B = ICR3 / 2;
}else if(s==6)
{
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==7) {
ICR3 = 31000;
OCR3B = ICR3 / 2;
}else if(s==8) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==9) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==10) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==11) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==12) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==13) {
ICR3 = 40000;
OCR3B = ICR3 / 2;
}else if(s==14) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==15) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==16) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==17) {
ICR3 = 40000;
OCR3B = ICR3 / 2;
}else if(s==18) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==19) {
ICR3 = 45000;
OCR3B = ICR3 / 2;
}else if(s==20) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==21) {
ICR3 = 40000;
OCR3B = ICR3 / 2;
}else if(s==22) {
ICR3 = 0;
OCR3B = ICR3 / 2;
}else if(s==23) {
ICR3 = 50000;
OCR3B = ICR3 / 2;
}else if(s==24) {
ICR3 = 0;
OCR3B = ICR3 / 2;
} }
void main(void) {
unsigned int cnt;
DDRA=0xFF;
DDRC=0xFF;
DDRE=0xFB;
TCCR0=0x07;
TCNT0=0xFF-145;
TIMSK=0x01;
TCCR3A = 0x32;
TCCR3B = 0x19;
TIFR|=0x01;
sei();
while(1) {
for(cnt=0; cnt<8; cnt++) {
PORTA=0xFF;
PORTC=0x80>>cnt;
m_delay(50);
} }
}
SIGNAL(TIMER0_OVF_vect) {
cli();
TCNT0=0xFF-145;
count++;
if(count==30) {
data++;
buzzer(data);
count=0;
if(data==24) {
data=0;
} }
sei();
}
2) 응용문제
① 슈퍼마리오 또는 알람 음 등 재미있는 멜로디 만들기
바. 모터 제어하기
모터는 크게 회전자(armature or rotor), 고정자(frame, case or housing), 전원 공 급부로 구성되어 있고 그림 6.25와 같이 모터는 플레밍의 왼손법칙에 따라 전기적 에너지를 운동(기계)에너지로 변환해 주는 장치이다.
[그림 6.25] 플레밍의 왼손 법칙
그림 6.26과 같이 근본적으로 자기장 속에서 도체가 놓여있을 때, 이 도체가 어떤 방향으로든지 운동을 하면 도체내부에는 전류가 유기되어 흐른다. 반대로 도체 내 에 전류를 흘리면 특정한 방향으로 힘을 받아 운동하려고 한다. 이러한 전자기적 원리를 이용하여 인위적으로 자기장을 형성하고 도체를 구성한 후 전류를 공급하면 이 도체가 운동을 하는데 이것을 바로 모터라고 한다.
[그림 6.26] 직류전동기의 구동원리
간단한 타이머/카운터를 이용하여 PWM 주파수를 생성한 뒤 이동로봇의 DC기어 드 모터에 입력하여 모터를 제어해보자.
1) 활용 실습
Q : 6.1_ 로봇의 오른쪽 모터를 정 방향으로 회전시키기
A :
#include<avr/io.h>
void main() {
DDRE=0xFB;
DDRB=0xf7;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
while(1) {
OCR1A = 160;
} }
Q : 6.2_ 로봇의 왼쪽 모터를 정 방향으로 회전시키기
A :
#include<avr/io.h>
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
while(1) {
OCR1B = 160;
} }
A :
#include<avr/io.h>
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
while(1) {
OCR1A = 160;
Q : 6.3_ 양쪽 모터를 동시에 정 방향으로 회전시키기
OCR1B = 160;
} }
A :
#include<avr/io.h>
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2560; i++) for(j=0; j<k; j++);
}
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
Q : 6.4_ 로봇의 정 방향으로 1m이동시키기
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
m_delay(350);
OCR1A = 0;
OCR1B = 0;
}
A :
#include<avr/io.h>
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2560; i++) for(j=0; j<k; j++);
}
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
Q : 6.5_ 로봇의 역방향으로 1m이동시키기
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x10;
OCR1A = 160;
OCR1B = 160;
m_delay(350);
OCR1A = 0;
OCR1B = 0;
}
A :
#include<avr/io.h>
Q : 6.6_ 로봇을 오른쪽으로 90도 회전시키기
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2560; i++) for(j=0; j<k; j++);
}
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
m_delay(80);
OCR1A = 0;
OCR1B = 0;
}
A :
#include<avr/io.h>
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2560; i++) for(j=0; j<k; j++);
}
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
Q : 6.7_ 로봇을 왼쪽으로 90도 회전시키기
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x10;
OCR1A = 160;
OCR1B = 160;
m_delay(80);
OCR1A = 0;
OCR1B = 0;
}
A :
#include<avr/io.h>
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2560; i++) for(j=0; j<k; j++);
}
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
Q : 6.8_ 1m 전진후 오른쪽으로 90도 회전 50cm전진, 90도 회전 1m전진
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
m_delay(350);
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
m_delay(90);
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
m_delay(280);
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
m_delay(90);
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
m_delay(350);
OCR1A = 0;
OCR1B = 0;
}
A :
#include<avr/io.h>
void main()
Q : 6.9_ “△” 모양의 버튼은 전진, “□” 모양의 버튼은 정지하기
{
unsigned char key;
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
DDRD=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
while(1) {
key=PIND&0xF0;
if(key==0xE0) {
OCR1A = 160;
OCR1B = 160;
}else if(key==0xB0) {
OCR1A = 0;
OCR1B = 0;
} }
}
A :
#include<avr/io.h>
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<2560; i++) for(j=0; j<k; j++);
}
void main() {
unsigned char key;
unsigned int ucnt=0, dcnt=0;
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
DDRD=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
Q : 6.10_ “△”모양의 버튼은 속도의 증가, “▽”모양의 버튼은 속도의 감속 하기
OCR3C = 0;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
while(1) {
key=PIND&0xF0;
if(key==0xE0) {
OCR1A = 100+ucnt;
OCR1B = 100+ucnt;
m_delay(5);
dcnt=0;
ucnt++;
}else if(key==0xD0) {
OCR1A = 160-dcnt;
OCR1B = 160-dcnt;
m_delay(5);
ucnt=0;
dcnt++;
} }
}
A :
#include<avr/io.h>
#include<avr/signal.h>
Q : 6.11_ 3초간 전진후 멈추기
unsigned char count;
unsigned int data=0;
void main() {
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
TCCR0=0x07;
TCNT0=0xFF-145;
TIMSK=0x01;
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
TIFR|=0x01;
sei();
while(1)
{
if(data>=0 && data<=2) {
OCR1A = 160;
OCR1B = 160;
}else if(data==3) {
OCR1A = 0;
OCR1B = 0;
} }
}
SIGNAL(TIMER0_OVF_vect) {
cli();
TCNT0=0xFF-145;
count++;
if(count==100) {
data++;
count=0;
}
sei();
}
A :
#include<avr/io.h>
Q : 6.12_ 학습 유저에 따라 4개의 버튼에 로봇이동의 경로 저장하기 ※“△”: 전진,“▽”: 후진, “□”: 정지,“○”: 회전
void main() {
unsigned char key;
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
DDRD=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
while(1) {
key=PIND&0xF0;
if(key==0xE0) {
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
}else if(key==0xD0)
{
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x10;
OCR1A = 160;
OCR1B = 160;
}else if(key==0xB0) {
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 0;
OCR1B = 0;
}else if(key==0x70) {
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
} }
}
A :
#include<avr/io.h>
#include<avr/signal.h>
Q : 6.13_ 로봇을“△”모양의 버튼을 눌러 전진시키며, 1초에 한번씩 8음계를 출력하기
unsigned char count;
unsigned int data=0;
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<200; i++) for(j=0; j<k; j++);
}
void buzzer(unsigned int s) {
if(s==1) {
ICR3 = 50000;
OCR3B = ICR3 / 2;
}else if(s==2) {
ICR3 = 45000;
OCR3B = ICR3 / 2;
}else if(s==3) {
ICR3 = 40000;
OCR3B = ICR3 / 2;
}else if(s==4) {
ICR3 = 35000;
OCR3B = ICR3 / 2;
}else if(s==5) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==6) {
ICR3 = 31000;
OCR3B = ICR3 / 2;
}else if(s==7)
{
ICR3 = 29000;
OCR3B = ICR3 / 2;
}else if(s==8) {
ICR3 = 27000;
OCR3B = ICR3 / 2;
} }
void main() {
unsigned char key;
DDRA=0xFF;
DDRC=0xFF;
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
DDRD=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
TCCR0=0x07;
TCNT0=0xFF-145;
TIMSK=0x01;
TCCR3A = 0x32;
TCCR3B = 0x19;
TIFR|=0x01;
while(1) {
key=PIND&0xF0;
if(key==0xE0) {
sei();
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
} }
}
SIGNAL(TIMER0_OVF_vect) {
cli();
TCNT0=0xFF-145;
count++;
if(count==100) {
data++;
buzzer(data);
count=0;
if(data==8) {
data=0;
} }
sei();
}
참고 :
그동안 학습 한 내용을 기반으로 프로그램을 작성하시오.
A :
#include<avr/io.h>
#include<avr/signal.h>
unsigned char count;
unsigned int data=0;
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<200; i++) for(j=0; j<k; j++);
}
void buzzer(unsigned int s) {
if(s==1) {
ICR3 = 50000;
OCR3B = ICR3 / 2;
}else if(s==2) {
Q : 6.14_ 로봇을“△”모양의 버튼을 눌러 전진시키며, 1초에 한번씩 8음계를 출력하고, 도트메트릭스 전체를 1초에 한번씩 깜박이게 하기
ICR3 = 45000;
OCR3B = ICR3 / 2;
}else if(s==3) {
ICR3 = 40000;
OCR3B = ICR3 / 2;
}else if(s==4) {
ICR3 = 35000;
OCR3B = ICR3 / 2;
}else if(s==5) {
ICR3 = 33000;
OCR3B = ICR3 / 2;
}else if(s==6) {
ICR3 = 31000;
OCR3B = ICR3 / 2;
}else if(s==7) {
ICR3 = 29000;
OCR3B = ICR3 / 2;
}else if(s==8) {
ICR3 = 27000;
OCR3B = ICR3 / 2;
} }
void main() {
unsigned char key;
DDRA=0xFF;
DDRC=0xFF;
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
DDRD=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
TCCR0=0x07;
TCNT0=0xFF-145;
TIMSK=0x01;
TCCR3A = 0x32;
TCCR3B = 0x19;
TIFR|=0x01;
while(1) {
key=PIND&0xF0;
if(key==0xE0) {
sei();
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
} }
}
SIGNAL(TIMER0_OVF_vect) {
cli();
TCNT0=0xFF-145;
count++;
if(count==100) {
data++;
buzzer(data);
PORTA=0xFF;
PORTC=0xFF;
count=0;
if(data==8) {
data=0;
} }else {
PORTA=0x00;
PORTC=0x00;
}
sei();
}
A :
#include<avr/io.h>
void m_delay(unsigned int k) {
unsigned int i, j;
for(i=0; i<200; i++) for(j=0; j<k; j++);
}
void main() {
unsigned char key;
DDRA=0xFF;
DDRC=0xFF;
DDRE=0xFB;
DDRB=0xf7;
DDRG=0x00;
DDRD=0x00;
TCCR1A = 0xa2;
TCCR1B = 0x19;
TCCR1C = 0x00;
ICR1 = 200;
OCR1A = 0;
OCR1B = 0;
OCR1C = 0;
TCCR3A = 0xc2;
TCCR3B = 0x1a;
TCCR3C = 0x00;
Q :
6.15_ 로봇의 버튼을 아래와 같이 세팅하고 전진시 도트매트릭스에 전진 화살표 후진은 후진 화살표 정지는 전체 점등, 좌회전시 좌측화살표, 우회 전시 우측화살표를 표시하며 이동하기
ICR3 = 1000;
OCR3A = 500;
OCR3B = 100;
OCR3C = 0;
while(1) {
key=PIND&0xF0;
if(key==0xE0) {
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
PORTA=0x18;
PORTC=0x80;
m_delay(1);
PORTA=0x3C;
PORTC=0x40;
m_delay(1);
PORTA=0x7E;
PORTC=0x20;
m_delay(1);
PORTA=0xFF;
PORTC=0x10;
m_delay(1);
PORTA=0x18;
PORTC=0x08;
m_delay(1);
PORTA=0x18;
PORTC=0x04;
m_delay(1);
PORTA=0x18;
PORTC=0x02;
m_delay(1);
PORTA=0x18;
PORTC=0x01;
m_delay(1);
PORTA=0xFF;
PORTC=0x00;
m_delay(1);
}else if(key==0xD0) {
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x10;
OCR1A = 160;
OCR1B = 160;
}else if(key==0xB0) {
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x80;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 0;
OCR1B = 0;
}else if(key==0x70) {
PORTE = PORTE & 0x3f;
PORTE = PORTE | 0x40;
PORTG = PORTG & 0xe7;
PORTG = PORTG | 0x08;
OCR1A = 160;
OCR1B = 160;
} }
}
2) 응용문제
① 로봇을 오른쪽으로 90도 회전시키기
② 로봇을 왼쪽으로 90도 회전시키기
③ 1m 전진 후 오른쪽으로 90도 회전 50cm전진, 90도 회전 1m전진
④ “△” 모양의 버튼은 전진, “□” 모양의 버튼은 정지하기
⑤ “△”모양의 버튼은 속도의 증가, “▽”모양의 버튼은 속도의 감속하기
⑥ 학습 유저에 따라 4개의 버튼에 로봇이동의 경로 저장하기 ※“△”: 전진,“▽”: 후진, “□”: 정지,“○”: 회전