#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) {
}
}