К входу 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)
{
}
}