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

[C][atmega8] RC5 - problem z synchronizacją przy odbiorze.

esnow 19 Lis 2009 12:30 2920 19
REKLAMA
  • #1 7280866
    esnow
    Poziom 14  
    witam,
    od jakiegoś czasu walczę z dekodowanie sygnału RC5
    TSOP1736 <--> PD2 (INT0)
    dioda nadawcza IR <--> BC516(PNP) <--> PB1

    układ na 100% działa ponieważ przetestowałem go w BASCOMIe rc5send i getrc5(); działają znakomicie. pilot philips 100% rc5 - sprawdzone

    problem mam taki, że w terminalu dostaje przedziwne rzeczy.
    np. dla tego samego klawisza prawie za każdym razem jest co innego.

    kod:
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <avr/signal.h> 
    
    //hFuse : 0xD9
    //lFuse : 0xFF
    
    #define F_CPU 8000000L                    //f osc
    #define UART_BAUD   9600         		  //prędkość transmisji rs232
    #define UART_CONST   (F_CPU/(16ul*UART_BAUD)-1)
    
    void USART_Transmit( unsigned char data );
    unsigned char USART_Receive( void );
    void USART_Init( unsigned long int ubrr );
    void send_string(const char *tekst);
    void receive_string(void);
    
    unsigned char bufor[32]; 				  //zmienna globalna bufor'a
    volatile unsigned char flaga=0;  		  //flaga do przerwań
    uint16_t data;
    
    
    
    
    SIGNAL(SIG_INTERRUPT0)
    {
    	PORTC ^= _BV(5); 					  //zmiana stanu diody
    	TCCR1B |= ((1<<WGM12) | (1<<CS12)); //tryb CTC und preskaler 256
    	
    	//GICR &= ~(1<<INT0); 				 // wylaczenie przerwania od INT0
    	GICR = 0x00;
    	//GIFR |= _BV(INTF0);                //kasowanie flagi INTF0 , 
    }
    
    
    SIGNAL(TIMER1_COMPA_vect)
    {
    	OCR1A = 0x36;    					//nastepna pętla po 1,778ms
    	PORTC ^= _BV(5); 					//zmiana stanu diody
    	
    	if(bit_is_clear(PIND,2))
    	data++;
    	data<<=1;	
    	
    	if((data & 0xC000) == 0xC0000)
    	{
    		sprintf(bufor,"%d",data);
    		send_string(bufor);
    		TCCR1B = 0x00;
    		OCR1A = 0x2A;  					//znowu petla 1.35ms (poczatek nowej ramki)
    		//GICR |= (1<<INT0); 			//wlaczenie przewania od INTO
    		GICR = 0x40; 					// INT0  ON!
    	}
    }
    
    
    int main(void)
    {
    	DDRC |= _BV(5);  					//led
    	DDRB |= _BV(1); 					//led_IR
    	PORTB |= _BV(1); 					//dioda IR off
    
    	USART_Init(UART_CONST); 			// inicjalizacja rs'a
    	
    	// A|=B oraz A&=~B ustawiane / kasowanie bitów
    	// kasowanie w zmiennej/rejestrze A tych bitów, które są ustawione w B
    
    	//GICR |= 1<<INT0;    				//wlaczenie przerwania na INT0
    	GICR = 0x40;      					
    
    	//MCUCR = (1<<ISC01); 				//INT0 reaguje na zbocze opadajace
    	MCUCR = 0x02;     
    
    	OCR1A = 0x2A;  						//pierwsza pętelka po 1,35
    
    	TIMSK = (1<<OCIE1A); 				//zezwolenie dla przerwania od CTC
    
    	sei();              				//globalne zezwolenie na przerwania
    	
    	while(1)
    	{
    	}
    	
    }
    
    
    
    
    void USART_Transmit( unsigned char data )
    {
       while ( !( UCSRA & (1<<UDRE)) );   	       // Wait for empty transmit buffer 
       UDR = data;               				   // Put data into buffer, sends the data 
    }
    
    unsigned char USART_Receive( void )
    { 
       while ( !(UCSRA & (1<<RXC)) );             // Wait for data to be received 
       return UDR;                         		   // Get and return received data from buffer 
    }
    
    void USART_Init( unsigned long int ubrr )
    {
       UBRRH = (unsigned char)(ubrr>>8);          // Set baud rate 
       UBRRL = (unsigned char)ubrr;   
       UCSRB = (1<<RXEN)|(1<<TXEN);               // Enable Receiver and Transmitter 
       UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);  // Set frame format: 8data, 1stop bit 
    }
    
    void send_string(const char *tekst)
    {
      while(*tekst)
        USART_Transmit(*tekst++);
    }
    
    void receive_string(void)
    {
    	unsigned char i=0;
    	do
    	{
    		if((bufor[i] = USART_Receive()) == '\n') break;
    		i++;
    	}while(i < 32); //zeby nie przepelnic bufora
    }
    

    [C][atmega8] RC5 - problem z synchronizacją przy odbiorze. [C][atmega8] RC5 - problem z synchronizacją przy odbiorze.
    wydaje mi się, że problem leży w źle dobranych czasach wpisywanych do rejestru OCR1A albo w tym, że INT0 jest wywoływany przez opadające zbocze.
    z góry dziękuje za pomoc!
  • REKLAMA
  • #2 7290692
    esnow
    Poziom 14  
    poprawiłem trochę kod, wyżej napewno miałem źle czasy dobrane.

    teraz (nie wiem czy dobrze) robię tak; odbieram "półbity" czyli razem 28 bitów
    i konwertuje do 14 bitów. 01-->1 lub 10-->0

    wbijam się w sygnał po 0.432 ms i dalej sprawdzam co 0.864ms czy to jest dobra metoda?

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <avr/signal.h> 
    
    //hFuse : 0xD9
    //lFuse : 0xFF
    
    #define F_CPU 8000000L                    //f osc
    #define UART_BAUD   9600         		  //prędkość transmisji rs232
    #define UART_CONST   (F_CPU/(16ul*UART_BAUD)-1)
    
    void USART_Transmit( unsigned char data );
    unsigned char USART_Receive( void );
    void USART_Init( unsigned long int ubrr );
    void send_string(const char *tekst);
    void receive_string(void);
    
    unsigned char bufor[32]; 				  //zmienna globalna bufor'a
    volatile unsigned char flaga=0;  		  //flaga do przerwań
    uint32_t data;
    uint16_t p;
    
    
    SIGNAL(SIG_INTERRUPT0)
    {
    	TCCR1B |= ((1<<WGM12) | (1<<CS10)); //tryb CTC und preskaler 1
    	GICR = 0x00;//GICR &= ~(1<<INT0); 	 // wylaczenie przerwania od INT0
    	//GIFR |= _BV(INTF0);                //kasowanie flagi INTF0 , 	
    }
    
    
    SIGNAL(TIMER1_COMPA_vect)
    {
    	OCR1A = 0x1B02;    					//nastepna pętla po 0,864ms
    	PORTC ^= _BV(5);
    	
    	if(bit_is_clear(PIND,2))
    	data++;
    	data<<=1;
    	
    	if((data & 0x5000000)==0x5000000)
    	{
    		for(int i=0; i<14; i++)
    		{
    			p = (data & 0x3)%2;
    			data >>= 2;
    		}
    		
    		sprintf(bufor,"%d",p);
    		send_string(bufor);
    		TCCR1B = 0x00;  //wylaczenie timera
    		OCR1A = 0xD7F;  //znowu pętelka po 0,428ms   na początek
    		GICR = 0x40;    // wlaczenie przerwania od INT0
    	}
    
    }
    
    
    int main(void)
    {
    	DDRC |= _BV(5);  					//led
    	DDRB |= _BV(1); 					//led_IR
    	PORTB |= _BV(1); 					//dioda IR off
    
    	USART_Init(UART_CONST); 			// inicjalizacja rs'a
    	
    	// A|=B oraz A&=~B ustawiane / kasowanie bitów
    	// kasowanie w zmiennej/rejestrze A tych bitów, które są ustawione w B
    	
    	GICR = 0x40;  //GICR |= 1<<INT0;    //wlaczenie przerwania na INT0    					
    	MCUCR = 0x02; //MCUCR = (1<<ISC01); //INT0 reaguje na zbocze opadajace    
    	OCR1A = 0xD7F;  					//pierwsza pętelka po 0,428ms
    	TIMSK = (1<<OCIE1A); 				//zezwolenie dla przerwania od CTC
    	sei();              				//globalne zezwolenie na przerwania
    	
    	while(1){}	
    }
    


    w terminalu same 1....
  • #3 7290975
    zdebel
    Poziom 15  
    na pierwszy rzut oka, nie incjalizujesz zmiennej data niczym i pewnie jest śmieciem :P
  • #5 7291122
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #6 7293313
    esnow
    Poziom 14  
    1. atom1477 czy chodzi o takie coś jak w tym poście: https://www.elektroda.pl/rtvforum/topic601492.html#3108618
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    unsigned char przelacznik=0;
    
    SIGNAL(SIG_INTERRUPT0)
    {
       unsigned int action=0;
    
       for(action=0;action<40;action++)
       {
          if(bit_is_set(PIND,PD2))
            {
             break;
            }
        }
       
       if(action>20)          
        {
          if(przelacznik==0)
            {
                PORTC = 0x01;
             przelacznik=1;
          }
    
            else
          {
                PORTC = 0x00;
             przelacznik=0;
          }
        }
    }
    
    int main ()
    {   
       GICR = 0x40;      // INT0 is set
       MCUCR = 0x02;     // INT0 reactions on falling edge
       DDRC = 0xFF;   //port C jako wyjście
           // tu funkcja opóźniająca o kilka milisekund
       
       sei (); // włączenie przerwań na INT
       
       for (;;) {}
        return (0);             
    }
    


    2. mam odbierać pół-bity, czy sprawdzać tylko 14 bitów ramki rc5?
  • #7 7293327
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #8 7293336
    esnow
    Poziom 14  
    Rozumiem, że tą metodą próbkowanie ma się odbyć bez wykorzystania timer'a?
  • #9 7293377
    Konto nie istnieje
    Poziom 1  
  • #10 7293487
    esnow
    Poziom 14  
    a jakbyś to rozwiązał, bo mi się pomysły skończyły. A większość tematów jest rc5+bascom....
  • REKLAMA
  • #11 7293635
    Konto nie istnieje
    Poziom 1  
  • #12 7294387
    esnow
    Poziom 14  
    a jak to rozwiązać w kodzie?
  • #13 7295584
    Konto nie istnieje
    Poziom 1  
  • #14 7295618
    esnow
    Poziom 14  
    to mam opóźniać o 864us i sprawdzać stan nóżki, czy co ile próbkować?
  • #15 7295640
    Konto nie istnieje
    Poziom 1  
  • #16 7295691
    esnow
    Poziom 14  
    Cytat:
    Chyba że w jednym przerwaniu chcesz odbierać całą ramkę RC5. Wtedy można zrobić programowe odliczanie czasu.


    to programowe odliczanie czasu, co ile ma być?
  • #17 7295909
    Konto nie istnieje
    Poziom 1  
  • #18 7296085
    esnow
    Poziom 14  
    w jakim celu ma być mierzony ten czas? bo nie wiem jak go później wykorzystać....

    a czemu nie powinni się zacząć próbkować np. w 2/3 czasu trwania bitu, i potem sprawdzać stan nóżki co 1,728ms. (wykorzystując do tego timer w trybie CTC) ?
  • #19 7296228
    Konto nie istnieje
    Poziom 1  
  • #20 7300494
    esnow
    Poziom 14  
    atom1477,
    miałeś rację między 1 a 2 bitem upływa 1744 us, a dalej to szkoda gadać...
    proszę o pomoc z tą synchronizacją!

    co tą są bity synchronizacji AGC ?

    przeczytałem AVR410, ale po przeczytaniu 5 zdań na temat synchronizacji, nie jestem w stanie tego zrozumieć, tym bardziej, że kod jest w assemblerze;/
REKLAMA