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, transmisja kodowana w Manchester

maniex 03 Lis 2010 23:29 3015 0
REKLAMA
  • #1 8699866
    maniex
    Poziom 10  
    Witam wszystkich,
    chciałbym zasięgnąć rady w sprawie transmisji sygnału w kodzie Manchester.
    Usiłuję napisać program dla układu z RFID i kartami typu UNIQUE. Do nawiązania transmisji używam układu EM4095, którego wyjście taktujące (RDY/CLK) podłączyłem do pinu PD5(T1), jako zewnętrzne źródło sygnału taktującego dla timera/countera1.
    Wyjście DMOD_OUT układu EM4095 podłączyłem do pinu PD2(int0).
    Do tego mam jeszcze podłączony wyświetlacz lcd i kilka diod sygnalizujących wejścia do poszczególnych partii programu.

    W teorii RFID UNIQUE działa tak, że generowana fala nośna o f=125kHz jest modulowana, przez transponder znajdujący się w polu, z częstotliwością f~2kHz.
    Jeden bit danych z karty trwa 64 okresy fali nośnej i jest kodowany w Manchesterze.

    Algorytm, który zastosowałem w programie jest analogiczny do programu J.Bogusza "dekoder kodu RC5", czyli:
    1) oczekuje na zbocze narastające na INT0-> wywołuje przerwanie,
    2) w obsłudze przerwania od INT0 wyłącza zezwolenie na przerwanie od tego zdarzenia i ustawia t1 w trybie ctc na wartość 3/4 okresu trwania całego bitu oraz włącza pozwolenie na przerwanie od t1,
    3)w obsłudze przerwania od t1 sprawdza stan wejścia INT0 i w zależności od tego zapisuje go jako 1 lub 0,
    4) po odebraniu założonej ilości 'półbitów' dekoduje transmisję z Manchester'a. Tego punktu już w moim programie nie umieściłem,ponieważ najpierw chciałem podejrzeć co jest odbierane,dlatego wyświetlam wszystkie 'półbity' na lcd. Tu jest problem...zgodnie z kodem Manchester nie ma możliwości ,aby 3 i wiecej kolejnych próbek było takich samych, podczas gdy u mnie jest to częsty przypadek.
    Czy ktoś ma pomysł w czym tkwi problem? W niepoprawnie napisanym programie?W sprzęcie?

    kod programu (obsługa lcd jest ściągnięta ze strony http://radzio.dxp.pl/hd44780/hd44780_avr_4-bit_norw_c.htm):


    
    /****************************************
    *program wykorzystuje wyjscie taktujace
    * RDY/CLK ukladu EM4095,ktore jest podlaczone do pinu PD5,
    *jako zewnetrzne zrodlo sygnalu zegarowego dla T1.
    *wyjscie DMOD_OUT jest podlaczone do INT0,czyli PD2.
    *jezeli zostanie wykryte zbocze narastajace
    *na int0, to pobiera
    *64 polbity-do jednej zmiennej.pozniej wyswietla to na lcd
    ************************************************/
    
    #include <avr/io.h>
    #include <avr/interrupt.h> //biblioteka obsługi przerwan
    #include <util/delay.h>	   //obsluga opoznien
    #include "HD44780.h"	   //obsluga wyswietlacza lcd
    
    /*zmienne globalne*/
    
    volatile unsigned long long int trans=0; //polbity transmisji
    volatile unsigned char rfid=0;// odebrano transmisje
    volatile unsigned char lprob=0; //liczba probek
    
    /**************
    program glowny
    ***************/
    
    int main(void)
    {
    unsigned char j=0,d;//licznik petli
    				//konfiguracja portow
    DDRD|=0x80;		//PD7 pracuje jako wyjscie
    DDRD|=0x40;		//PD6 pracuje jako wyjscie
    DDRD&=~(0x04);		//PD2 pracuje jako wejscie
    PORTD|=(0x04);		// podciagniete do vcc
    DDRD&=~(0x01);		//PD0 pracuje jako wejscie
    PORTD|=(0x01);		// podciagniete do vcc
    DDRB|0x01;		//PB0 pracuje jako wyjscie
    
    LCD_Initalize();    // inicjalizacja LCD
    trans=0;
    rfid=0;
    
    
    TCCR1B|=(1<<WGM12); //ustawia bit odpowiedzialny
                         //za tryb CTC timera1 z porownywaniem z wartoscia
                         //przechowywana w OCR1A
    				   
    MCUCR|=((1<<ISC01)|(1<<ISC00));	 //zbocze narastajace bedzie wyw.przerwanie
    GICR|=(1<<INT0);    //zezwolenie na przerwanie od zbocza na int0
    TIMSK|=(1<<OCIE1A); //zezwolenie na przerwania od CTC timera1
    TCCR1B&=~((1<<CS12)|(1<<CS11)|(1<<CS10)); //zatrzymanie timera1 przez wpisanie 0 
    sei();				 //globalne zezwolenie na przerwania	
    
    LCD_WriteData('d');
    
    /*nieskonczona petla*/
    while(1)
    {
    
    if(rfid)			//jezeli cos odebrano
    {
    //nalezy wylaczyc obsluge przerwan,aby w czasie dekodowania transmisji
    //nie byly pobierane nowe dane:
    
    GICR&=~(1<<INT0);   //wylaczenie zezwolenia na przerwanie od 
                         //zbocza na int0,przez skasowanie bitu INT0
    TCCR1B&=~((1<<CS12)|(1<<CS11)|(1<<CS10)); //zatrzymanie timera1 przez wpisanie 0
    cli();				 //wylaczenie globalnego zezwolenia na przerwania
    
    for(;j<55;j++)
    {
    d=trans&0x01;		 //ostatni bit zmiennej 'trans'
    LCD_WriteData(d+48);   //wyswietl na lcd ten bit
    trans=trans>>1;		//przesun o 1 bit w prawo,zeby moc go wyswietlic w nastepnej petli
    }
    }
    }
    return 0;		   
    }
    
    
    /**********************************
    *obsługa przerwania od narastającego*
    *zbocza na wejsciu INT0           * 
    **********************************/
    
    ISR(INT0_vect)
    {
    
    PORTD|=0x40;//sygnalizacja dioda wejscia do isr
    
    GICR&=~(1<<INT0);   //wylaczenie zezwolenia na przerwanie od narastajacego
                         //zbocza na int0,przez skasowanie bitu INT0
    
    OCR1A=48; 			 // 3/4 okresu dla Timera1 przy taktowaniu RDY/CLk
    
    TCCR1B|=(CS12<<1)|(CS11<<1); //ustawia taktowanie z zewnetrznego zrodla
    							   //podlaczonego do PD5(T1).bez filtru zaklocen,
    							   //na zbocze opadajace.
    							   //uruchamia timer1 <-START TIMERA!!
    TIMSK|=(1<<OCIE1A); //zezwolenie na przerwania od CTC timera1
    lprob=64;           
    }
    
    
    /**************************************
    *obsługa przerwania od odliczenia     *
    *czasu 3/4 lub 1/2 okresu przez TIMER1*
    ***************************************/
    
    ISR(TIMER1_COMPA_vect)
    {
    //deklaracje zmiennych
    volatile unsigned char pbit;  //stan wejscia DEMOD_OUT podlaczonego do PD2(int0),
    					 //polowa bitu danych
    
    pbit=(PIND&0x04);            //sprawdz stan DMOD_OUT
    pbit=pbit>>2;
    
    
    while(lprob--)
    {
    TCCR1B&=~((1<<CS12)|(1<<CS11)|(1<<CS10)); //zatrzymanie timera1 przez wpisanie 0 
    											//do odpowiednich bitów TCCR1B
    OCR1A=32;			 						//1/2 okresy dla prescalera 64 i f=8MHz=32
    TCCR1B|=(CS12<<1)|(CS11<<1); //uruchamia timer1 z prescalerem 1<-START TIMERA!!
    
    if(pbit==1)
    {
    trans=trans|1;
    }
    trans=trans<<1;
    return;
    }
    TCCR1B&=~((1<<CS12)|(1<<CS11)|(1<<CS10)); //zatrzymanie timera1 przez wpisanie 0 
    											//do odpowiednich bitów TCCR1B
    TIMSK&=~(1<<OCIE1A); 						//wylaczenie zezwolenia na przerwania od CTC timera1
    PORTB|=1; //sygnalizacja
    rfid=1;
    }
    


    Z góry dziękuję za pomoc.
  • REKLAMA
REKLAMA