Skocz do zawartości

[C] ATmega8 i RC5


siemian

Pomocna odpowiedź

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

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

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

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

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

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

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

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

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

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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.