logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMEGA8][C] RC-5 odbiór - dlaczego nie działa?

rodzio 20 Sty 2010 21:05 1272 2
REKLAMA
  • #1 7565964
    rodzio
    Poziom 12  
    Witam,

    Jakiś czas męczę się już z odczytem RC-5 napisałem prosty program na podstawie http://www.ustr.net/infrared/infrared1.shtml, i w sumie nie wiem dlaczego nie działa. Może świeże spojrzenie kogoś innego znajdzie w tym błąd?

    kwarc 1Mhz

    ISR(INT0_vect)
    {
    	GICR&=~_BV(INT0);
    	_delay_ms(4);	//4.752ms
    	_delay_us(752);
    	
    	_delay_ms(8);	//8.640ms bity adresu
    	_delay_us(640);
    	
    	for(int i=5;i>=0;i--)
    		{
    			if (bit_is_set(PORTD,IR)) {IR_CMD[i]=0;}
    			else {IR_CMD[i]=1;}
    			//_delay_ms(1);
    			_delay_us(728);
    		}
    	
    	PORTD^=_BV(D1);
    	_delay_ms(900);
    	GICR=_BV(INT0);
    	PORTC=0x00;
    	
    }


    Chce odczytać jedynie komendę.
  • REKLAMA
  • Pomocny post
    #2 7567611
    elektronik12z
    Poziom 13  
    Witam

    Musisz za każdym razem skalibrować na podstawie 2 pierwszych bitów czas trwania timerem, a dalej już po kalibracji detektować czy to 0 czy 1. Niestety ten czas może się różnić nawet o 20%.
    Proszę o innych o potwierdzenie ww. słów.

    Pozdrawiam
  • #3 7567886
    rodzio
    Poziom 12  
    Na wstępie widzę, że popełniłem straszną gafę. Zczytywałem stan portu przez PORT zamiast PIN:) Napisałem dwie kolejne wersje.

    ISR(TIMER0_OVF_vect)	//
    {
    	TCNT0=39;		//1.728ms
    	if (bit_is_set(PORTD,IR)) {IR_CMD[i]=1;}
    	else {IR_CMD[i]=0;}
    	i--;
    	if (i==0) {TCCR0=0x00; i=13; _delay_ms(1000); GICR=_BV(INT0);}
    	
    }
    
    ISR(INT0_vect)
    {
    	TCCR0=0x03;
    	GICR&=~_BV(INT0);	
    }

    Coś podobnego do tego pierwszego, po pierwszym ext int0 odpalam timer i co 1.728 zczytuje stan portu.

    
    ISR(TIMER0_OVF_vect)	//wykorzystujemy do modulacji
    {
    	TCNT0=HalfBit;		//864us
    	MARKER=!MARKER;		//negacja
    }
    
    ISR(INT0_vect)
    {
    	TCCR0=0x03;
    	if (bit_is_set(PORTD,IR)) {IR_CMD[i]=MARKER;}
    	else {IR_CMD[i]=!MARKER;}
    	i--;
    	if (i==0) {TCCR0=0x00; i=14; TCNT0=201}
    	
    }

    Tutaj trochę inny pomysł, przerwanie ustawione na malejące zbocze. Po przerwaniu czekam czas 432 tak aby znalezc sie w srodku drugiej polowy bitu, a pozniej co 862 zmieniam stan markera.
REKLAMA