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):
Z góry dziękuję za pomoc.
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.