BASIC4MCU | 질문게시판 | 답변 : ATmega 128 스위치를 이용한 경보음, 버저, led 작동 및 시간측정 소스코드 질문입니다.
페이지 정보
작성자 master 작성일2022-12-12 12:50 조회1,397회 댓글0건본문
#include <avr/io.h>
#include "test.h"
#include "lcd.h"
//
#define sbi(PORT,BIT) PORT|=(1<<BIT) // 1로 나타냄
#define cbi(PORT,BIT) PORT&=~(1<<BIT) // 0로 나타냄
#define tog(PORT,BIT) PORT^=(1<<BIT) // 1,0반복
//
unsigned char x[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xA7,0xA1,0x86,0x8E,0xFF} ;
unsigned char s[5]={0x08,0x04,0x02,0x01};
volatile unsigned char b[5];
volatile char dis[17]={0,};
//
volatile int led_cnt=0,led_con=0;
volatile int sw_cnt=0,sw_mode=1,sw_end=0,sw_time=0,sw_stop=0;
volatile int time_cnt=0,time_con=0,sec_cnt=0,min_cnt=0;
volatile int seg_data=0,seg_cnt=0;
volatile int cnt=0.flag=0,ii=0,mode=0;
//
void cvtD2S(int a){
int kk;
b[0]=x[a/1000]; a=a%1000; b[1]=x[a/100]; a=a%100; b[2]=x[a/10]; b[3]=x[a%10];
ii++; kk=ii%4;
PORTE=s[kk]; PORTB=b[kk];
}
//
SIGNAL(SIG_INTERRUPT0){
if(mode==0){
switch(sw_mode){
case 1: EICRA=0x03; sw_mode=0; sbi(TIMSK,TOIE0); break; //falling edge(스위치 누를때 ) // 0번overflow 인터럽트 활성화
case 0: cbi(TIMSK,TOIE0); EICRA=0x02; sw_mode=1; sw_end=0; break; //rising edge(스위치 땠을때) //overflow 인터럽트 비활성화
}
}
if(mode==1){ sw_stop=1; }
if(mode==4){ sw_stop=1; }
}
//
SIGNAL(SIG_OVERFLOW0){ //1ms //FND 시간 재는 용도
if(++cnt>1000)sw_cnt++; //1초
}
//
SIGNAL(SIG_OVERFLOW2){ //1ms //항상 실행
if(led_con==1){
if(++led_cnt>100){ //0.1s
if(mode==1){ tog(PORTD,2); } //RED
if(mode==4){ tog(PORTD,1); tog(PORTD,2); } //GREEN //RED
led_cnt=0; // 깜빡깜빡
}
}
else{ led_cnt=0; cbi(PORTD,1); cbi(PORTD,2); }
//
if(time_con==1){
if(++time_cnt>999){ time_cnt=0; //1초
if(++sec_cnt>59){ sec_cnt=0; if(++min_cnt > 59)min_cnt=0; }
}
}
//
if(++seg_cnt>5){ seg_cnt=0;
seg_data=min_cnt*100+sec_cnt;
cvtD2S(seg_data);
if(mode==2){
led_con=0; cbi(PORTD,3); dis[1]='t'; dis[2]='i'; dis[3]='m'; dis[4]='e'; dis[5]=':';
dis[6]=seg_data/1000+48; dis[7]=(seg_data%1000)/100+48; dis[8]='m';
dis[9]=(seg_data%100)/10+48; dis[10]=(seg_data%10)+48; dis[11]='s';
lcd_putstring(0,0,dis);
mode=3;
}
if(mode==5){
led_con=0; cbi(PORTD,3); dis[1]='t'; dis[2]='i'; dis[3]='m'; dis[4]='e'; dis[5]=':';
dis[6]=seg_data/1000+48; dis[7]=(seg_data%1000)/100+48; dis[8]='m';
dis[9]=(seg_data%100)/10+48; dis[10]=(seg_data%10)+48; dis[11]='s';
lcd_putstring(0,0,dis);
mode=3;
}
}
}
//
void main(){
MCU_initialize();
DDRB=0xff; DDRE=0x0f;
DDRD=0x0E; PORTD=0x01; // 내부풀업
//
Delay_ms(50); lcd_init();
lcd_putstring(0,0," Sensor ");
for(int i=0;i<16;i++)dis[i]=' ';
//
TCCR0=0x05; TCNT0=256-125; // 1/16000000*128*125=1ms
TCCR2=0x03; TCNT2=256-250; // 1/16000000*64*250=1ms
TIMSK=0x41; //타이머 카운트 0/2 둘다 쓰겠다.
//
EICRA=0x03; EIMSK=0x01; //인터럽트 0번 rising edge 로 설정
sei();
while(1){
if(mode==0){ //스위치 입력받는 모드
cnt=0; sw_end=1; sw_cnt=0; sw_time=0; sw_mode=1; EICRA=0x02; //스위치 falling edge 로 설정
while(sw_end); sw_time=sw_cnt; //누루면 스위치 0 while문 빠져나감.
if(sw_time<0.5)mode=1; else mode=4;
}
//
if(mode==1){ //연습
lcd_putstring(0,0," Practice ");
led_con=1; sbi(PORTD,3);
if(sw_stop==1){ time_con=0; mode=2; } else time_con=1;
}
//
if(mode==3){
Delay_ms(2000);
time_cnt=0; sec_cnt=0; min_cnt=0; sw_stop=0; mode=0;
lcd_putstring(0,0," Sensor ");
}
//
if(mode==4){ //긴급
lcd_putstring(0,0," Emergency ");
led_con=1; sbi(PORTD,3);
if(sw_stop==1){ time_con=0; mode=5; } else time_con=1;
}
}
}
뭐가 안되는지 모르겠지만복잡한 코드는 타인이 도와드리지 못합니다.보드를 가지고 있는 본인이 스스로 디버깅 해야합니다.
댓글 0
조회수 1,397등록된 댓글이 없습니다.