[ATmega128] LED 예제2
해당 예제는 WinAVR 컴파일러 환경에서 동작합니다.
이번 예제는 스위치 여러 개로 LED 여러 개를 컨트롤 하는 예제이다. LED가 켜지면 순차적으로 LED가 켜졌다가 꺼지도록 한다.
가장 위 입력은 LED를 켜고 끄는 ON/OFF 스위치이고 그 다음은 LED가 바뀌는 데 걸리는 시간을 줄이고 다른 스위치는 LED가 바뀌는 데 걸리는 시간을 늘리는 스위치이다.
회로도
소스코드
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
unsigned char led_on = 0; //led_on이 1이면 led를 동작하도록 하기 위한 변수
unsigned char led = 0xfe; //PD0의 LED만 켜지게 하기 위한 초기값
int delay_time = 10;
void delay(int delay_time){ //delay_time 변수 값만큼 50ms씩 delay
while(delay_time--){
_delay_ms(50);
}
}
void main(){
DDRD = 0x00; //PD2~0을 입력으로 설정
DDRB = 0xff; //PB7~0을 출력으로 설정
PORTD = 0x07; //풀업저항을 사용하기 위해 PORTD2~0 = 1
PORTB = 0xff; //PORTB의 초기값 설정
unsigned char key;
while(1){
key = PIND & 0x07; //PIND와 들어온 신호를 비교
switch(key){ //button이 GND와 연결되어 있어서 눌리면 0 열려있으면 1의 값이 입력
case 0b00000110: //PD.0과 연결된 버튼이 눌린 경우
led_on=~led_on; //led_on을 스위칭
break;
case 0b00000101: //PD.1과 연결된 버튼이 눌린 경우
if(led_on){ //LED가 꺼졌다가 다시 켜졌을 때 delay_time이 꺼지기 전의 값을 유지하기 위한 조건문
if(delay_time>1){
delay_time--;
//delay 하는 횟수를 감소
}
}
break;
case 0b00000011: //PD2와 연결된 버튼이 눌린 경우
if(led_on){
if(delay_time<21){
delay_time++; //delay 하는 횟수를 증가
}
}
break;
}
if(led_on){
PORTB=led; //PORTB에 led값을 출력
delay(delay_time); //delay_time * 50ms 만큼 delay
if(led==0x7f) //PB7과 연결된 LED가 켜진 경우
led=0xfe; //led를 초기값으로 설정
else
led=(led<<1)|0x01; //led 변수를 한칸씩 shift하면서 0번 비트를 1로 세트한다.
}
else
PORTB=0xff; //led_on이 0인 경우 led를 모두 끔
_delay_ms(200);
}
}
이전 예제와 마찬가지로 스위치는 GND와 연결되어 있고 LED는 Vcc와 연결되어 있다. 입력 값을 확인하기 위해서 PIND & 0x07
을 해주어서 하위 3비트의 입력값을 비교하고 해당 스위치에 맞는 동작을 한다.
스위치에 따른 동작이 끝나면 led_on
플래그가 1이면 다음 LED를 켜고 다음에 켜질 LED를 led
변수에 입력한다. <<
연산은 이진수를 왼쪽으로 쉬프트하는 연산기호이다.
delay
함수를 따로 선언해 준 이유는 _delay_ms()
함수가 입력값으로 변수를 받지 않아서이다. x = 1
이고 _delay_ms(x)
를 하게 되면 에러가 발생하므로 적당한 ms를 설정하고 반복 횟수로 지연 시간을 조절해야 한다.
주의할 점
이 예제에서는 여러 개의 키가 동시에 눌리는 경우에 동작이 되지 않는다. 이런 경우를 위해서 나중에 인터럽트에 대해서 공부하게 된다. while
문 마지막에 LED가 꺼진 경우 200ms의 delay를 주게 되었는데 이것은 버튼을 눌렀다가 떼기 전에 다시 while문의 처음으로 돌아가서 여러 번 눌린 것으로 인식될 수 있기 때문이다. 이것 또한 인터럽트를 적용하고 입력 방식을 변경하면 해결할 수 있다.
'임베디드 > ATmega128' 카테고리의 다른 글
[ATmega128] GPIO 활용 - 7 세그먼트 (0) | 2021.10.02 |
---|---|
[ATmega128] GPIO 활용 - LED 예제1 (0) | 2021.10.02 |