siemian Napisano Listopad 7, 2009 Udostępnij Napisano Listopad 7, 2009 Witam, jestem w trakcie budowy robota, którego jedną z funkcji ma być możliwość uruchamiania programów pilotem RC5. Zbudowałem układ dzięki którem chciałem się nauczyć jak obsłużyć odbieranie RC-5 a przy okazji sprawdzić jakie kody mają odpowiednie przyciski mojego pilota. Napisałem kod i niestety nie działa. Pilot jest na pewno RC5. Czujnik podczerwieni to TSOP1736 podłączony to PD3. Kody obsługi wyświetlacza pochodzą z: http://radzio.dxp.pl/hd44780/ a to kod mojego programu: #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include "HD44780.c" #define F_CPU 1000000 #define IR_PIN PD3 volatile char koniec='1'; volatile int kod=0; volatile int ilosc=0; int main (void) { LCD_Initalize(); LCD_Clear(); LCD_WriteText("czekam"); TCCR1B |= (1 << WGM12); DDRD =0x01;// PORTD=0xff; OCR1A = 1778;//porównanie po 1778 impulsach 1 impuls =1us TCCR1B |= (1 << CS10) ; // Ustawia timer z preskalerem 1 MCUCR |= (1<<ISC10); GICR |= (1<<INT1);//włączenie przerwania od INT1 sei(); while(1) { } } ISR(TIMER1_COMPA_vect) { if(PIND & IR_PIN) { kod++;//dodaj 1 do wartości kodu } kod<<=1;//przesuń wartość o 1 pole w lewo ilosc++; if(ilosc==13) { TIMSK &=~ (1 << OCIE1A);// wylaczenie przerwań wypisz(); _delay_ms(1000); koniec='1'; ilosc=0; GICR |= (1<<INT1);//włączenie przerwań od INT1 } TCNT1 = 0;//wyzeruj wartość licznika w timerze } SIGNAL(INT1_vect) { GICR &=~ (1<<INT1);//wylacz przerwania od INT1 PORTD ^= (1 << 0); if(koniec=='1')//sprawdzenie czy instrukcja została pobrana w całości { koniec='0'; _delay_ms(0.45);//po pojawieniu się impulsu czekaj if(PIND & IR_PIN )//sprawdź czy impuls nadal jest { TCNT1 = 0; TIMSK |= (1 << OCIE1A); //włącz przerwania od timera } else koniec='1'; } } void wypisz() { LCD_Clear(); if(kod & 0x01) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x02) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x03) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x04) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x05) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x06) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x07) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x08) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x09) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x0a) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x0b) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x0c) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x0d) LCD_WriteText("1"); else LCD_WriteText("0"); if(kod & 0x0e) LCD_WriteText("1"); else LCD_WriteText("0"); } Kompilacja przebiega prawidłowo, program się odpala na uC wyświetla "czekam" a po wciśnięciu przycisku na pilocie pojawia się wartość 01111111111111 na wyświetlaczu, dziwnym jest że dioda podłączona do PD0 która ma sygnalizować kiedy następuje wywołanie przerwania od INT1 miga 2-3 razy po jednorazowym wciśnięciu przycisku. Proszę o pomoc w zlokalizowaniu błędu. Link do komentarza Share on other sites More sharing options...
Elvis Listopad 8, 2009 Udostępnij Listopad 8, 2009 Masz błąd w instrukcjach: if(kod & 0x01) LCD_WriteText("1"); else LCD_WriteText("0"); Zamiast 0x01, 0x02, 0x03, 0x04, 0x05... powinno być 0x01, 0x02, 0x04, 0x08, 0x10, 0x20 itd.. Ogólnie sprawdzenie i-tego bitu (i liczone od 0) to test: if (kod & (1< Więc zamiast 16 razy pisać to samo można dać pętlę [ Dodano: 08 Lis 09 08:52 ] Do wyświetlania liczby proponuję kod: unsigned int mask; int i; .... mask = 0x8000; for (i=0;i<16;i++) { if (kod & mask) LCD_WriteText("1"); else LCD_WriteText("0"); mask >>=1; } Link do komentarza Share on other sites More sharing options...
siemian Listopad 17, 2009 Autor tematu Udostępnij Listopad 17, 2009 dziękuję za zainteresowanie, odpisuje dopiero teraz bo nie miałem dostępu do programatora, jednak nie w tym leżał błąd, nadal nie wiem co może być nie tak, skończyły mi się już pomysły. Link do komentarza Share on other sites More sharing options...
Mazicort Luty 15, 2010 Udostępnij Luty 15, 2010 Odkopywanie starego tematu, ale nie wiem czy problem został rozwiązany. Zamieszczam kod do obsługi RC5, nie działający co prawda na timerach, ale w pełni działający. Może komuś się przyda. //RC5 Decoding by Mazi volatile int rc5_getkey; volatile int rc5_toggle; volatile int rc5_addr; volatile int rc5_comm; SIGNAL (INT1_vect){ //OUT: int: rc5_toggle, rc5_addr,rc5_comm,rc5_getkey; //ALL 4 variables should be cleared in main function //after code recieve [ if(rc5_getkey) ] //NEED TO WORK: //interrupt.h with properly set F_OSC //SET INTERRUPT VECTOR in function prototype //ENABLE INTERRUPT FROM INTx on FALLING EDGE //ENABLE INTERRUPT FROM INTx //ENABLE GLOBAL INTERRUPTS //And change PIND & 0x08 for ur INTx //So, search it in ur datasheet, or (for ATtiny2313): // //MCUCR |= (1<<ISCx1); //GIMSK |= (1<<INTx); //SREG |= (1<<7); // //Ah- propably you dont need last line of this function //or change it correspondly to ur uC. It's clear of interrupt flag // //Finnaly, function works, but it's written terrible. //It's based on delays, cuz i needed timers to sth other. //Anyway, it's working and good if u can waste CPU time //and have no free timers. _delay_us(200); // Middle of 1st bit for (int i = 0 ; i< 2; i++){ _delay_us(1778); // Two start bits } rc5_toggle =(PIND & 0x08) ? 0 : 1; //Toggle bit <bit :D> _delay_us(1778); for(int i = 0; i < 5; i++){ // Addres byte rc5_addr = (PIND & 0x08) ? (rc5_addr<<1) : ((rc5_addr<<1) | 0x01); _delay_us(1778); } for(int i = 0; i < 6; i++){ //Command byte rc5_comm = (PIND & 0x08) ? (rc5_comm<<1) : ((rc5_comm<<1) | 0x01); _delay_us(1778); } _delay_ms(10); rc5_getkey=1; EIFR |= (1<<INTF1); } //END RC5 Decoding Przykład użycia w programie: if(rc5_getkey){ if(rc5_comm==0x02) { tbi(LED,RED); _delay_ms(500); } rc5_getkey=0; rc5_comm = 0; rc5_addr = 0; rc5_toggle = 0; } } Edit. Kod był pisany pod attiny, dziś sprawdziłem pod atmegą, wprowadziłem do posta drobne poprawki. Dla atmegi powinno być GIFR zamiast EIFR. Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
pawel Marzec 21, 2010 Udostępnij Marzec 21, 2010 Ostatnio trochę siedzę nad dekodowaniem RC5 i przyuważyłem że w tym programie jest błąd. Chodzi o ostatnią instrukcje programu. Tam jest rejestr EIFR, a taki nie istnieje. Powinno tam być GIFR. Jeszcze nie sprawdziłem czy po poprawce działa, bo mam lekkie problemy z elektroniką. Link do komentarza Share on other sites More sharing options...
siemian Marzec 28, 2010 Autor tematu Udostępnij Marzec 28, 2010 Tak problem został rozwiązany i całość została użyta w moim manipulatorze. Problem polegał na tym że nie wiedzieć czemu pilot wysyłał niekiedy 12 niekiedy 13 albo 14 bitów informacji, czasy też były jakieś dziwne, możliwe że była to jakaś marna podróbka ale najważniejsze że już działa. Link do komentarza Share on other sites More sharing options...
KD93 Marzec 29, 2010 Udostępnij Marzec 29, 2010 Być może twój pilot ma jakiś przycisk zmieniający kodowanie, który naciskasz przypadkowo. Ja tak miałem kiedy wykorzystywałem pilot z radia Philips: naciskając przypadkowo przycisk FM zmieniałem kodowanie i program nie działał prawidłowo. Trzeba było nacisnąć przycisk CD i pilot wracał do poprzedniego kodowania. Link do komentarza Share on other sites More sharing options...
szymonweeia Lipiec 12, 2010 Udostępnij Lipiec 12, 2010 Witam. A czy próbował ktoś napisać kod do nadajnika w RC5? Z odbiorem przez TSOP1736 sobie poradziłem ale chciałbym zbudować mniejszy pilot czyli potrzebuje sposobu na wysłanie konkretnego kodu w RC5. Link do komentarza Share on other sites More sharing options...
newman Sierpień 7, 2010 Udostępnij Sierpień 7, 2010 witam,ten kod mazicorta uruchamialiście ? ja próbowałem i bez efektów,pod bascomem ładnie działa, przy tym kodzie już nie. Działam pod attiny2313, ustawiłem odpowiednie rejestry, końcówka idzie na pin od INT1. pozdrawiam Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »