BASIC4MCU | 질문게시판 | ATmega 128 스위치를 이용한 경보음, 버저, led 작동 및 시간측정 소스코드 질문입니다.
페이지 정보
작성자 짠짠짠 작성일2022-12-12 11:16 조회696회 댓글0건본문
lcd 헤더파일과 test 헤더파일을 추가하였는데도 오류가 발생하였습니다.
#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반복
void cvtD2S(int a);
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 cnt = 0;
volatile int flag = 0;
volatile int seg_data = 0;
volatile int led_cnt = 0;
volatile int led_con = 0;
volatile int sw_cnt = 0;
volatile int sw_mode = 1;
volatile int sw_end = 0;
volatile int sw_time = 0;
volatile int sw_stop = 0;
volatile int ii = 0;
volatile int seg_cnt = 0;
volatile int mode = 0;
volatile int time_cnt = 0;
volatile int sec_cnt = 0;
volatile int min_cnt = 0;
volatile int time_con = 0;
void main()
{
MCU_initialize();
DDRB = 0xff;
DDRE = 0x0f;
DDRD = 0b00001110;
PORTD = 0b00000001; // 내부풀업
Delay_ms(50);
lcd_init();
//Ext interrupt
EIMSK = 0b00000001; //인터럽트 0번 허용
EICRA = 0b00000011; //rising edge 로 설정
//Timer
TCCR0 = 0b00000101; //128분주
TCNT0 = 256-125; // 1/16000000*128*125 = 1ms
TCCR2 = 0b00000011; //64분주
TCNT2 = 256-250; // 1/16000000*64*250 = 1ms
TIMSK = 0b01000001; //타이머 카운트 0/2 둘다 쓰겠다.
sei(); //SREG = 0x80;
lcd_putstring(0,0, " Sensor ");
for(int i=0; i<16; i++)
dis[i] =' ';
while(1)
{
if(mode == 0) //스위치 입력받는 모드
{
cnt = 0;
sw_end = 1;
sw_cnt = 0;
sw_time = 0;
EICRA = 0b00000010; //스위치 falling edge 로 설정
sw_mode = 1;
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;
lcd_putstring(0,0, " Sensor ");
sw_stop = 0;
mode = 0;
}
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;
}
}
}
SIGNAL(SIG_INTERRUPT0)
{
if(mode == 0)
{
switch( sw_mode )
{
case 1: //falling edge(스위치 누를때 )
EICRA = 0b00000011; //rising edge로 변경
sw_mode = 0;
sbi(TIMSK, TOIE0); // 0번overflow 인터럽트 활성화
break;
case 0: //rising edge(스위치 땠을때)
cbi(TIMSK, TOIE0); //overflow 인터럽트 비활성화
EICRA = 0b00000010; //falling edge로 변경
sw_mode = 1;
sw_end = 0;
break;
}
}
if(mode == 1)
{
sw_stop = 1;
}
if(mode == 4)
{
sw_stop = 1;
}
}
SIGNAL(SIG_OVERFLOW0) //1ms //FND 시간 재는 용도
{
cnt++;
if(cnt > 1000) //1초
{
sw_cnt++;
}
}
SIGNAL(SIG_OVERFLOW2) //1ms //항상 실행
{
if(led_con == 1)
{
led_cnt++;
if(led_cnt > 100) //0.1s
{
if(mode == 1)
tog(PORTD,2); //RED
if(mode == 4)
{
tog(PORTD,1); //GREEN
tog(PORTD,2); //RED
}
led_cnt = 0; // 깜빡깜빡
}
}
else
{
led_cnt = 0;
cbi(PORTD,1);
cbi(PORTD,2);
}
if(time_con == 1)
{
time_cnt++;
if(time_cnt > 1000) //1초 //1000번세면 1초 100번 0.1초
{
sec_cnt ++;
if(sec_cnt > 59)
{
min_cnt++;
sec_cnt = 0;
}
if(min_cnt > 59)
{
min_cnt = 0;
}
time_cnt = 0;
}
}
seg_cnt++;
if(seg_cnt > 5)
{
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;
}
seg_cnt = 0;
}
}
void cvtD2S(int a)
{
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++;
int kk = ii%4;
PORTE = s[kk];
PORTB = b[kk];
}
댓글 0
조회수 696등록된 댓글이 없습니다.