본문 바로가기

정리중인 카테고리/전공 기술

ATmega128 - 리모콘 수신 프로그램 (업그레이드).

#define F_CPU 16000000UL


#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <util/delay.h>


#define CLK   16000000

#define PRESCALE 256

#define TIME_US  100

#define TIMER0_CNT (CLK*TIME_US/(256*1000000))


char _remocon_counter,_save_remocon,_flg_remocon;

char bit_input;

char bounce_check = 0;


unsigned char _remocon_custom,_remocon_custom_2;

unsigned char _remocon_data,_remocon_data_2;


int _counter_remocon;


void port_init() {

 DDRA = 0xff; PORTA = 0x00;

 DDRB = 0xff; PORTB = 0x00;

 DDRC = 0xff; PORTC = 0x00;

 DDRD = 0xfe; PORTD = 0x00;

 DDRE = 0xff; PORTE = 0x00;

 DDRF = 0xff; PORTF = 0x00;

 DDRG = 0xff; PORTG = 0x00;

}


void usart_tx_byte(unsigned char tx_data) {

 while(!(UCSR0A&0x20));

 UDR0=tx_data;

 UCSR0A|=0x20;

}


// 송신할 데이터를 16진 데이터로 변형후 송신

void usart_tx_byte_hex(unsigned char tx_hex_data) {

 unsigned char h_data, l_data;


 l_data=tx_hex_data&0x0f; h_data=tx_hex_data>>4;


 if(h_data<0x0a) h_data=h_data+0x30;

 else h_data=h_data+0x37;

 usart_tx_byte(h_data);


 if(l_data<0x0a) l_data=l_data+0x30;

 else l_data=l_data+0x37;

 usart_tx_byte(l_data);

}


// 일반 패킷 단위 송신 함수

void usart_tx_bytes(unsigned char *tx_data) {

 while(*tx_data != '\0') {

  usart_tx_byte(*tx_data);

  tx_data++;

 }

}


ISR(INT0_vect) {

 if(_flg_remocon) {

  // 0 비트 데이터를 확인

  if((_counter_remocon>=5)&&(_counter_remocon<=11)) bit_input=0;

  // 1 비트 데이터를 확인

  else if((_counter_remocon>=15)&&(_counter_remocon<=25)) bit_input=1;


  switch(_save_remocon) {

   case 1: // 커스텀 코드1 을 저장한다

   _remocon_custom<<=1; _remocon_custom|=bit_input;

   break;

   case 2: // 커스텀 코드2 을 저장한다

   _remocon_custom_2<<=1; _remocon_custom_2|=bit_input;

   break;

   case 3: // 데이터 코드1 을 저장한다

   _remocon_data<<=1; _remocon_data|=bit_input;

   break;

   case 4: // 데이터 코드2 을 저장한다

   _remocon_data_2<<=1; _remocon_data_2|=bit_input;

   break;

  }

  _remocon_counter++;


  if(_remocon_counter>=8) {

   _save_remocon++; _remocon_counter=0;

  }


  // 수신 완료

  if(_save_remocon>=5) {

   bounce_check++;

   if(bounce_check >=3 ) {

    bounce_check = 0;

    usart_tx_bytes("C1: 0x");

    usart_tx_byte_hex(_remocon_custom);

    usart_tx_bytes("  C2: 0x");

    usart_tx_byte_hex(_remocon_custom_2);

    usart_tx_bytes("  D1: 0x");

    usart_tx_byte_hex(_remocon_data);

    usart_tx_bytes("  D2: 0x");

    usart_tx_byte_hex(_remocon_data_2);

    usart_tx_bytes("\r\n");

   }

  }

 }

 // 리모콘 신호가 휴지 상태일 경우 플래그 변수들 초기화

 else if((_counter_remocon>=120)&&(_counter_remocon<=140)) {

  if(!_flg_remocon) {

   _flg_remocon=1;

   _save_remocon=1;

  }

 }

 _counter_remocon=0;

}


ISR(TIMER0_OVF_vect){

 TCNT0=0xff-TIMER0_CNT; _counter_remocon++;


 // 리모콘 신호가 감지되지 않을 경우, 플래그 변수들을 초기화 한다

 if(_counter_remocon>=200){

  _flg_remocon=0; _save_remocon=0; _remocon_counter=0;

 }

}


int main(void) {


 _delay_ms(500);


 port_init();

 

 UBRR0H = 0;

 UBRR0L = 51;

 UCSR0A = 0x00;

 UCSR0B = 0x18;

 UCSR0C = 0x06;

 

 EICRA = 0x02;

 EICRB = 0x00;

 EIMSK = 0x01;

 EIFR  = 0xff;

 

 TCCR0 = 0x06;

 TCNT0 = TIMER0_CNT;

 TIMSK  = 0x01;

 TIFR = 0;


 sei();

 

 usart_tx_bytes("Initialized complete.\r\n");


    while(1) {

    }

}