ATTINY13A и китайский приемник XY-MK-5V 433МГц

Обсуждаем контроллеры компании Atmel.
Ответить
uvaxut
Родился
Сообщения: 14
Зарегистрирован: Вт дек 15, 2015 17:12:09

ATTINY13A и китайский приемник XY-MK-5V 433МГц

Сообщение uvaxut »

Адаптировал код библиотеки RemoteSwith ардуино для attiny13.
К входу PB1 (INT0) тиньки подключается выход с приемника. При получении кода одной из кнопок брелока появляется "+" на указанном выводе тиньки, другого кода, соответственно "-". Подключив к выходу тиньки реле, можно получить радиоуправляемое реле. Из-за маленького размера флеш у тиньки передаваемые значения могут быть только двухбайтовыми. Протокол троичный. Может кому пригодится.

Код: Выделить всё

// Фьюзы по дефолту, кроме CLKDIV8
// Он в 1 (не запрограммирован)
// Коды кнопок до FFFF

#include <tiny13a.h>
#include <stdint.h>

#define KEY1          50223 // Код кнопки 1
#define KEY2          50229 // Код кнопки 2
#define POWER_OUT_BIT 0     // pin 5

#define HIGH PORTB |=  (1<<(POWER_OUT_BIT))
#define LOW  PORTB &= ~(1<<(POWER_OUT_BIT))

uint16_t micros = 0;

uint16_t receivedCode;
uint8_t  receivedBit;
uint16_t previousCode;
uint16_t edgeTimeStamp[3] = {0, };
uint16_t min1Period, max1Period, min3Period, max3Period;
uint8_t skip;
int8_t state = -1;    
uint16_t duration;

void InterruptHandler()
{
    uint16_t period;
    
    edgeTimeStamp[1] = edgeTimeStamp[2];
    edgeTimeStamp[2] = micros;
    
    if(skip){
        skip = 0;
        return;
    }
    
    if(state >= 0 && edgeTimeStamp[2]-edgeTimeStamp[1] < min1Period){
        skip = 1;
        return;
    }
    
    duration = edgeTimeStamp[1] - edgeTimeStamp[0];
    edgeTimeStamp[0] = edgeTimeStamp[1];     

    if(state == -1){
        if(duration > 3270){
            period = duration/31;
            receivedCode = previousCode = 0;
            
            min1Period = period*4/10;
            max1Period = period*16/10;
            min3Period = period*23/10;
            max3Period = period*37/10;
        }
        else return;
    }
    else if(state < 48){
        receivedBit <<= 1;
        if(duration <= max1Period) receivedBit &= 0b1110;
        else if(duration >= min3Period && duration <= max3Period) receivedBit |= 0b1;
        else {
            state = -1;
            return;
        }
        
        if((state%4) == 3){ 
            receivedCode *= 3;
            switch(receivedBit & 0b1111){
                case 0b0101:
                    receivedCode += 0;
                    break;
                case 0b1010:
                    receivedCode += 1;
                    break;
                case 0b0110:
                    receivedCode += 2;
                    break;
                default:
                    state = -1;
                    return;
            }
        }
    }
    else if(state == 48){
        if(duration > max1Period){
            state = -1;
            return;
        }
    }
    else
    {   
       //--- ЗДЕСЬ КОД ИСПОЛНЕНИЯ ПРИ ПОЛУЧЕНИИ 
       if(receivedCode      == KEY1) HIGH;
       else if(receivedCode == KEY2) LOW;
       state = -1;
       return;
    }
    state++;
    return;
}    
interrupt [EXT_INT0] void ext_int0_isr(void)
{
    InterruptHandler();   
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
    TCNT0=0xD0;
    micros += 5;
    if(micros == 65535 ){
        micros = 0;
    }
}

void main(void)
{
	DDRB=(1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (0<<DDB1) | (1<<DDB0);

	TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
	TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
	TCNT0=0xD0;
	OCR0A=0x00;
	OCR0B=0x00;

	TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);

	// External Interrupt(s) initialization
	// INT0: On
	GIMSK=(1<<INT0) | (0<<PCIE);
	MCUCR=(0<<ISC01) | (1<<ISC00);
	GIFR=(1<<INTF0) | (0<<PCIF);

	#asm("sei")

	while (1)
      {

      }
}
Реклама
Ответить

Вернуться в «AVR»