BASIC4MCU | 질문게시판 | 답변 : Atmega128 led 점등
페이지 정보
작성자 master 작성일2022-05-01 07:51 조회15,792회 댓글8건본문
(1) 프로그램이 시작하면 LED는 왕복 점등 반복
interrupt [EXT_INT2] void external_int2(void){ // 인터럽트}//void main(){signed char led=0,dir=1;DDRD=0b00000000; DDRC=0b11111111; PORTC=~(1<<led);EIMSK=0b00000100; EICRA=0b00100000; SREG=0b10000000;while (1){PORTC=~(1<<led);if(dir){ if(++led>7){ led=7; dir=0; } }else { if(--led<0){ led=0; dir=1; } }delay_ms(200);}}(2) SW를 눌렀을 때 현재 점등된 LED 위치에서 방향 전환(3) SW를 누를 때마다 방향이 전환되도록 프로그래밍 (현재 점등된 위치에서)interrupt [EXT_INT2] void external_int2(void){ // 인터럽트dir^=1;}//void main(){signed char led=0,dir=1;DDRD=0b00000000; DDRC=0b11111111; PORTC=~(1<<led);EIMSK=0b00000100; EICRA=0b00100000; SREG=0b10000000;while (1){PORTC=~(1<<led);if(dir){ if(++led>7){ led=7; dir=0; } }else { if(--led<0){ led=0; dir=1; } }delay_ms(200);}}(4) 폴링 / 인터럽트 두 가지 방식으로 구현해볼 것폴링은 위 1,2,3 방식아래는 인터럽트 방식signed char led=0,dir=1;//interrupt [EXT_INT2] void external_int2(void){ // 인터럽트if(dir){ if(++led>7){ led=7; dir=0; } }else { if(--led<0){ led=0; dir=1; } }PORTC=~(1<<led);}//void main(){PORTC=~(1<<led);DDRD=0b00000000; DDRC=0b11111111; PORTC=led;EIMSK=0b00000100; EICRA=0b00100000; SREG=0b10000000;while(1){}}
댓글 8
조회수 15,792Eleccc님의 댓글
Eleccc 작성일
정말감사합니다....
1.2.3 번이 1코드안에 들어가게만들고싶은데
그냥 붙이면 될까요?너무너무감사합니다.
master님의 댓글
master
2,3번에 1번이 포함되어 있습니다.
Eleccc님의 댓글
Eleccc
정말죄송한데 스위치 를 누를떄 방향전환이안되네요.. pd 2 번에 꽂았는데스위치를 누르면 0번으로가네요.. led가 2번불들어왔으면 1번 이나 3번으로 가야하는데.
master님의 댓글
master
10K 풀업저항 사용하고 있을테고요
스위치에 병렬로 104(0.1uF = 100nF) 커패시터 연결하세요(채터링이 심하면 1uF 또는 10uF 정도를 사용해야 합니다.)
delay_ms(1000); // delay_ms(200);
딜레이가 길어야지 구분하기 쉬울겁니다.
Eleccc님의 댓글
Eleccc
풀업저항부분은 문제없는데
2.3번 시작할때 interrupt [EXT_INT2] void external_int2(void){ // 인터럽트
dir^=1;
}
//
이거 치고 void main 들어가니깐 Error: C:.c(16): undefined symbol 'dir'
가뜨네요 ㅠㅠ
Eleccc님의 댓글
Eleccc
커패시터없이 저항으로만 가능할까요??
master님의 댓글
master
char dir=1; // 전역변수로 선언하세요
//
커패시터가 없으면 채터링 막기 어려울텐데요
딜레이로 채터링 방지하는 코드를 추가해보죠
interrupt [EXT_INT2] void external_int2(void){ // 인터럽트
delay_ms(50);
dir^=1;
while(!PIND.2); delay_ms(50); // 스위치를 누르고 있는 동안 대기
EIFR|=0x04; // 인터럽트 플래그 clear
}
텍트 스위치를 사용하는 경우 50ms 정도의 딜레이면 채터링이 잡힐겁니다.
master님의 댓글
master 작성일
#include <mega128.h>
#include <stdlib.h>
#include <math.h>
#include <delay.h>
//
char dir=1;
//
interrupt [EXT_INT2] void external_int2(void){
delay_ms(50);
dir^=1;
while(!PIND.2); delay_ms(50);
EIFR|=0x04;
}
//
void main(void){
char led = 0xFE;
DDRC = 0xFF; PORTC = led;
EICRA = 0x20; EIMSK = 0x04; SREG = 0x80;
while(1){
PORTC = led;
if(dir){
led=(led<<1)|0x01;
if(led==0x7F)dir=0;
}
else{
led=(led>>1)|0x80;
if(led==0xFE)dir=1;
}
delay_ms(200);
}
}