-
-
Save wararyo/9913293 to your computer and use it in GitHub Desktop.
IR library(Send Only/NEC format)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* IR.h | |
* | |
* Created: 2014/03/30 22:35:21 | |
* Author: wararyo | |
*/ | |
#ifndef IR_H_ | |
#define IR_H_ | |
#include <avr/io.h> | |
#include <util/delay.h> | |
#include <avr/interrupt.h> | |
#define cbi(addr,bit) addr &= ~(1<<bit) | |
#define sbi(addr,bit) addr |= (1<<bit) | |
#define tbi(addr,bit) addr ^= (1<<bit) | |
#define wait(ms) _delay_ms(ms) | |
#define TIMER_CONTROL_A TCCR0A | |
#define TIMER_CONTROL_B TCCR0B | |
#define TIMER_COMP OCR0A | |
#define TIMER_INTERRUPT TIMSK0 | |
#define TIMER_INTERRUPT_BIT OCIE0A | |
#define PWM_CONTROL_A TCCR1A | |
#define PWM_CONTROL_B TCCR1B | |
#define PWM_COMP OCR1AL | |
#define PWM_TOP ICR1 | |
#define CAP_CONTROL_A TCCR1A | |
#define CAP_CONTROL_B TCCR1B | |
#define CAP_PERIOD ICR1 | |
#define CAP_DDR DDRB | |
#define CAP_PIN PB0 | |
#define CAP_EDGESELECT ICES1 | |
#define CAP_INTERRUPT TIMSK1 | |
#define CAP_INTERRUPT_BIT ICIE1 | |
#define CAP_OVF_INTERRUPT_BIT TOIE1 | |
#define IR_LED_DDR DDRB | |
#define IR_LED_PORT PORTB | |
#define IR_LED_PIN PB1 //OC1A | |
#define IR_T 70// 562/8 | |
#define IR_CAREER 26 | |
#define IR_DUTY 9 // 26/3 | |
volatile int IR_count = 0; | |
volatile char IR_data[96];//16+8+(4*32)+1 | |
volatile int IR_receive_raw[72]; | |
volatile char IR_isSending = 0; | |
volatile char IR_isReceiving = 0; | |
ISR ( TIMER0_COMPA_vect ){ | |
if(IR_data[IR_count] & 0b00000001){ | |
sbi(PWM_CONTROL_A,7); | |
} | |
else{ | |
cbi(PWM_CONTROL_A,7); | |
} | |
TIMER_COMP = IR_T * (IR_data[IR_count] >> 1); | |
IR_count++; | |
if(IR_data[IR_count] == 0) { | |
cbi(PWM_CONTROL_A,7); | |
cbi(TIMER_INTERRUPT,TIMER_INTERRUPT_BIT); | |
IR_count = 0; | |
cbi(IR_LED_PORT,IR_LED_PIN); | |
IR_isSending = 0; | |
IR_initialize(0); | |
IR_onSendFinished(); | |
} | |
} | |
ISR ( TIMER1_CAPT_vect ){ | |
static char receive_count = 0; | |
IR_isReceiving = 1; | |
tbi(CAP_CONTROL_B,ICES1); | |
//sbi(PORTD,PD7); | |
unsigned int span = CAP_PERIOD; | |
TCNT1 = 0; | |
IR_receive_raw[receive_count++] = span; | |
//sendStringLine(itoa(span,&ch,10)); | |
} | |
//TIMER1のオーバーフローを受信終了とみなす | |
ISR ( TIMER1_OVF_vect ) { | |
tbi(PORTD,PD7); | |
if(!IR_isReceiving) return; | |
char ch; | |
for(int i=1;i<72;i++){ | |
sendStringLine(itoa(IR_receive_raw[i] * 8,&ch,10)); | |
} | |
} | |
void IR_onSendStart(); | |
void IR_onSendFinished(); | |
void IR_onInitialize(); | |
//mode:0=receive 1=send | |
void IR_initialize(char mode){ | |
IR_onInitialize(); | |
TIMER_CONTROL_A = 0b00000010;//OC0A切断 CTC | |
TIMER_CONTROL_B = 0b00000010;//1/8 8us/count | |
TIMER_COMP = IR_T; | |
sbi(IR_LED_DDR,IR_LED_PIN);//output | |
cbi(IR_LED_PORT,IR_LED_PIN); | |
if(mode) IR_PWM_initialize(); | |
else IR_Capture_initialize(); | |
//sei(); | |
} | |
void IR_PWM_initialize(){ | |
if(IR_isReceiving) return; | |
PWM_CONTROL_A = 0b00000010; | |
PWM_CONTROL_B = 0b00011001; | |
PWM_TOP = IR_CAREER; | |
PWM_COMP = IR_DUTY; | |
} | |
void IR_Capture_initialize(){ | |
if(IR_isSending) return; | |
CAP_CONTROL_A = 0b00000000; | |
CAP_CONTROL_B = 0b10000010;//1/8Clock 8us/count | |
sbi(CAP_INTERRUPT,CAP_INTERRUPT_BIT); | |
sbi(CAP_INTERRUPT,CAP_OVF_INTERRUPT_BIT); | |
IR_StartCapture(); | |
} | |
//IR_initialize(0)後に呼び出される | |
void IR_StartCapture(){ | |
cbi(CAP_DDR,CAP_PIN);//input | |
cbi(CAP_CONTROL_B,ICES1);//立ち下がり割り込み | |
} | |
//IR_data一個の構造 | |
//0ビット目でHIGHかLOWか | |
//残り7ビットでその状態の長さを表す | |
//ex) 0b00000100 LOWの状態を2カウント続ける 0b00000011 HIGHの状態を1カウント続ける | |
int add_data_raw(char mvalue,int *count,char length){ | |
char lengthnumber; char rest;//8ビットカウンタ 1MHz 1/8分周より 2048μsまでしか測れない | |
if(length > 3){ lengthnumber = length / 3; rest = length % 3 ;} | |
else if(length == 0) return *count; | |
else {lengthnumber = 0; rest = length;} | |
mvalue &= 0b00000001;//2以上の場合は1に | |
for (char i=0;i < lengthnumber;i++){ | |
IR_data[*count] = (3 << 1) | mvalue; | |
(*count)++; | |
} | |
IR_data[(*count)++] = (rest << 1) | mvalue; | |
return *count; | |
} | |
int add_data(char mvalue,int *count){ | |
if(mvalue){ | |
add_data_raw(1,count,1); | |
add_data_raw(0,count,3); | |
} | |
else{ | |
add_data_raw(1,count,1); | |
add_data_raw(0,count,1); | |
} | |
return *count; | |
} | |
void IR_send(int customer,char data){ | |
/*int count = 0; | |
for(char i=0;i < 16;i++){ | |
IR_data[count] = 1; | |
count++; | |
} | |
for(char i=0;i < 8;i++){ | |
IR_data[count] = 0; | |
count++; | |
} | |
for(char i=0;i < 16;i++){ | |
count = add_data(((customer >> (15 - i)) & 0x0001),count);//カスタマーコード 上位ビットからiビット目が1の時 | |
} | |
for(char i=0;i < 8;i++){ | |
count = add_data(((data >> (7 - i)) & 0x01),count); | |
/*if((data >> (7 - i)) & 0x01){ | |
IR_data[count] = 1;count++; | |
IR_data[count] = 0;count++; | |
} | |
else{ | |
IR_data[count] = 1;count++; | |
for(char ii=0;ii < 3;ii++){IR_data[count] = 0;count++;} | |
}*//* | |
} | |
for(char i=0;i < 8;i++){ | |
count = add_data(((~data >> (7 - i)) & 0x01),count); | |
/*if((~data >> (7 - i)) & 0x01){ | |
IR_data[count] = 1;count++; | |
IR_data[count] = 0;count++; | |
} | |
else{ | |
IR_data[count] = 1;count++; | |
for(char ii=0;ii < 3;ii++){IR_data[count] = 0;count++;} | |
}*//* | |
} | |
IR_data[count] = 1; | |
count++; | |
while(count < 154){ | |
IR_data[count] = 0; | |
count++; | |
}*/ | |
int count = 0; | |
add_data_raw(1,&count,16); | |
add_data_raw(0,&count,8); | |
for(char i=0;i < 16;i++){ | |
add_data(((customer >> (15 - i)) & 0x0001),&count);//カスタマーコード 上位ビットからiビット目が1の時 | |
} | |
for(char i=0;i < 8;i++){ | |
add_data(((data >> (7 - i)) & 0x01),&count); | |
} | |
for(char i=0;i < 8;i++){ | |
add_data(((~data >> (7 - i)) & 0x01),&count); | |
} | |
add_data_raw(1,&count,1); | |
add_data_raw(0,&count,1); | |
while(count < 96){ | |
IR_data[(count)++] = 0; | |
} | |
IR_isSending = 1; | |
IR_initialize(1); | |
IR_onSendStart(); | |
sbi(TIMER_INTERRUPT,TIMER_INTERRUPT_BIT); | |
} | |
#endif /* IR_H_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment