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

Wysłanie kodu RC5 przez RS232 [C]

jaros85 29 Gru 2009 18:38 3284 14
REKLAMA
  • #1 7453904
    jaros85
    Poziom 20  
    Witam z tej strony http://homepage.hispeed.ch/peterfleury/avr-software.html ściągnąłem program do odbioru danych w kodzie RC5.
    Program działa ok ale chcę wysłać zdekodowanie danie przez RS232 i tu występuje problem ponieważ Hyper Terminal odbiera dżem

    Tutaj program zapala diody podłączone do portu PB
    PORTB = ~(rc5data & 0x003f);
    


    To jest kod wysyłający dane przez RS
    //Wysłanie pojedynczego znaku
    void nadajznak (char dana1)
    {
    while(!(UCSRA & (1<<UDRE)));
    UDR=dana1;
    }
    
    //Zliczanie liter w wyrazie i wysyłanie ich do funkcji nadajznak
    void nadajstring (char *dana)
    {
    int dlugosc,i=0;
    dlugosc = strlen(dana);
    for(i=0;i<dlugosc;i++)
    	{
    	nadajznak(dana[i]);
    	}
    }
    


    Dane do wysłania przekazuję następująco
    nadajstring((~(rc5data & 0x003f))); 


    Co muszę zmodyfikować żeby wyświetlić odbierany kod w postaci binarnej czy tylko zer i jedynek.
  • REKLAMA
  • #2 7454012
    gothye
    Poziom 33  
    void nadajstring (char dana)
    {
    	unsigned char wyslij[2];
    	for(z=0;z<8;z++)
    	{ 
    		dana = dana>>1;
    		sprintf(wyslij, "%d", dana );
    		nadajznak(*wyslij);		
    	}
    }


    spróbuj tak

    nie sprawdzałem ,pisane na szybko
  • #3 7454408
    michalko12
    Specjalista - Mikrokontrolery
    gothye napisał:
    void nadajstring (char dana)
    {
    	unsigned char wyslij[2];
    	for(z=0;z<8;z++)
    	{ 
    		dana = dana>>1;
    		sprintf(wyslij, "%d", dana );
    		nadajznak(*wyslij);		
    	}
    }


    spróbuj tak

    nie sprawdzałem ,pisane na szybko


    I co ta procedura robić?
    W twoim przypadku najlepiej będzie jak coś sprawdzisz zanim wyślesz.
  • #4 7454480
    gothye
    Poziom 33  
    zanim zaczniesz krytyke ,to może sam coś zaproponujesz kod ?
  • REKLAMA
  • #5 7454526
    michalko12
    Specjalista - Mikrokontrolery
    jaros85 napisał:
    Dane do wysłania przekazuję następująco
    nadajstring((~(rc5data & 0x003f))); 


    Co muszę zmodyfikować żeby wyświetlić odbierany kod w postaci binarnej czy tylko zer i jedynek.


    void nadajstring (char dana)
    {
       unsigned char i;
       
       for(i=0; i<8; i++)
       {
             nadajznak(dana & 0x80 ? '1' : '0');
             dana<<=1;
       }
    }
  • #6 7455716
    jaros85
    Poziom 20  
    Dzięki ale niestety ani jeden ani drugi kod nie działa prawidłowo w przypadku drugiego kodu odbieram zawsze same zera. A poza tym dlaczego obydwie pętle for wykonują się tylko 8 razy :?:

    Może wyjaśnię dokładniej zdekodowany kod RC5 chcę wysłać do PC ponieważ nie wiem dokładnie ile znaków jest ostatecznie dekodowany nie znam jego długości. I dlatego chcę tą informację wysłać przez RS. Wydaje mi się że są to zera i jedynki bo diody podłączone do portu PB zakalają się i gasną.

    Może dodam że gdy na pilocie wciskam zero to H T wyświetla pojedynczy znak % a wszystkie diody gasną na wszystkich portach PB występuje stan wysoki(porty PB7 i 8 przy moim pilocie nigdy nie zmieniają stany zawsze jest wysoki).
    Wysłanie kodu RC5 przez RS232 [C]
    Może ten obrazek coś pomoże :idea:
  • #7 7456077
    michalko12
    Specjalista - Mikrokontrolery
    jaros85 napisał:
    Dzięki ale niestety ani jeden ani drugi kod nie działa prawidłowo w przypadku drugiego kodu odbieram zawsze same zera. A poza tym dlaczego obydwie pętle for wykonują się tylko 8 razy :?:

    Może wyjaśnię dokładniej zdekodowany kod RC5 chcę wysłać do PC ponieważ nie wiem dokładnie ile znaków jest ostatecznie dekodowany nie znam jego długości. I dlatego chcę tą informację wysłać przez RS. Wydaje mi się że są to zera i jedynki bo diody podłączone do portu PB zakalają się i gasną.


    Chyba sam nie wiesz jaki rezultat chcesz uzyskać poprzez wysyłanie danych przez UART
    Chcesz wyświetlić numer wciśniętego klawisza - binarnie?
    Pytasz się dlaczego pętla powtarza się tylko 8 razy ? Bo tak naprawdę potrzebujesz tylko 6 razy!
    nadajstring((~(rc5data & 0x003f))); 

    Mówi o tym te 0x003f, ale że parametrem funkcji jest typ char to masz 8 razy żeby wyświetlić cała daną.
    To co pokazałeś na obrazku wiele nie mówi, może równie dobrze oznaczać źle skonfigurowany UART.
    Najlepiej jak wstawisz cały kod.
  • #8 7460976
    jaros85
    Poziom 20  
    /******************************************************************************
        Title:    Philips RC-5 Remote Control Decoder
        Author:   Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
        Date:     December 2002
        Purpose:  Decodes RC5-commands
        Software: AVR-GCC 3.3
        Hardware: AT90S8515 at 4 Mhz, IR-Receiver SFH506-36
    
        RC5 data format:
            SB1 SB2 TB AB5 AB4 AB3 AB2 AB1 AB0 CB5 CB5 CB4 CB3 CB2 CB1 CB0
            SB = Start bit, TB = Toggle bit, AB = address bits,  CB = command bits
        
        Program description:
        
        The IR-Receiver SFH506-36 receives and demodulates the IR-signal from the 
        remote control into an active-low signal, which is feed into port PD3.
        
        The rc5decode function first measures the length of the first start bit. 
        If the start bit is recognized as a valid RC5 bi-phase code, the routine 
        synchronizes into the middle of the first half of the second bit. Then the 
        state is stored into variable rc5data. The function uses the edge in the 
        middle of every bit to synchronize the timing. 3/4 bit length after this 
        edge, the state is sampled. This is repeated for the following bits.
        
        The function returns the decoded RC5-command or zero if valid RC5-code 
        not recognized.
        
        Timer0 is used as a time base. The timer0 overflow interrupt sets the 
        global variable timerflag to 1. 
        
        See also Atmel AVR Application Note AVR410
        
    *******************************************************************************/
    #define F_CPU 4000000
    #define UART_BAUD	4800
    #define UBRR	(F_CPU/(16ul*UART_BAUD)-1)
    
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    /* this should be in <avr/io8515.h> !! */
    #define TMC8_STOP	0
    #define TMC8_CK8	_BV(CS01)
    
            
    /*
    ** Macros and constants
    */
    #define RC5BitHigh()    (bit_is_set(PIND,PD3))
    #define RC5BitLow()     (bit_is_clear(PIND,PD3))
    #define WAITFORTIMER()  { while ( timerflag == 0); timerflag = 0; }
    
    #define TIMER_0_CNT 0xCA     //  111us with CLK/8 prescale
    #define RC5BITREF1  6  
    #define RC5BITREF2  11
    #define RC5BITREF3  14
    
    
    /*
    ** function prototypes
    */
    unsigned int rc5decode( void );
    
    
    /*
    ** module global variables 
    */
    static volatile uint8_t timerflag;  //must be volatile because modified by interrupt handler
    
    
    SIGNAL(SIG_OVERFLOW0)
    /*
    **  signal handler for timer0 overflow interrupt
    */
    {
        timerflag = 1;               // set global variable 
    
        TCNT0 = TIMER_0_CNT;         // reset counter to get this interrupt again 
    }
    
    
    unsigned int rc5decode( void )
    /*
    **  decoded RC5 data is returned, or 0x0000 if RC5 data not recognized
    */
    {
        unsigned int    rc5data;
        unsigned char   timer, i;
        
    
        // init timer/Counter0    
        TCCR0 = TMC8_CK8;                // use CLK/8 prescale
        TCNT0 = TIMER_0_CNT;             // set timer T/16 = 111us 
        TIMSK = _BV(TOIE0);              // enable TCNT0 overflow interrupt
        
        // measure startbit
        timerflag = 0; timer = 0; 
        while ( RC5BitLow() && (timer < RC5BITREF2) ) {
            WAITFORTIMER();
            timer++;
        }
        if ( (timer > RC5BITREF1) && (timer < RC5BITREF2) ) {
            // startbit ok, decode 
    
            // wait T/4: synchronize in the middle of first half of second bit
            while ( timer < RC5BITREF3 ) {
                WAITFORTIMER();
                timer++;
            }
            
            // read the remaining bits
            rc5data = 1;
            for (i=0; i<13; i++) {
                rc5data <<= 1;  
                if ( RC5BitHigh() ) {
                    rc5data |= 0x0001;
                    // wait max T/2 for H->L transition (middle of next bit)
                    timer = 0;
                    while ( RC5BitHigh() && (timer < 16) ) {
                        WAITFORTIMER();
                        timer++;
                    }
                }else{ 
                    rc5data &= ~0x00001;
                    // wait max T/2 for L->H transition (middle of next bit)
                    timer = 0;
                    while ( RC5BitLow() && (timer < 16) ) {
                        WAITFORTIMER();
                        timer++;
                    }
                } 
                if ( timer == 16 ) {
                    rc5data = 0x0000;   // error, next bit not found
                    break;
                }
                
                // wait 3/4 T: await next bit
                for ( timer=0; timer < 12 ; timer++) WAITFORTIMER();
            }
    
        }else {
            rc5data = 0x0000;  // error, invalid RC-5 code
        }
        TCCR0 = TMC8_STOP;            // stop timer0    
        
        return (rc5data);
    
    }//rc5decode
    
    
    
    //Inicjalizacja UARTU
    void USARTInit(unsigned int ubrr)
    {
    UBRRH = (ubrr>>8);
    UBRRL = (unsigned char) ubrr;
    //Włączenie nadawania i odbioru oraz przerwania dla odbioru
    UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    //Włączono dostęp do ubbh ustawiono 8 bitów danych parzystość oraz 2 bity stopu
    UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)|(1<<UPM1)|(1<<USBS);
    sei();
    }
     
    //Wysłanie pojedynczego znaku
    void nadajznak (char dana1)
    {
    while(!(UCSRA & (1<<UDRE)));
    UDR=dana1;
    }
    
    //Zliczanie liter w wyrazie i wysyłanie ich do funkcji nadajznak
    void nadajstring (char *dana)
    {
    int dlugosc,i=0;
    dlugosc = strlen(dana);
    for(i=0;i<dlugosc;i++)
    	{
    	nadajznak(dana[i]);
    	}
    }
    
    SIGNAL (SIG_UART_RECV)
    {
    nadajznak(UDR);
    }
    
    
    
    
    int main(void)
    {
        unsigned int rc5data, tmp;
        
        
        DDRB  = 0xff;               // use all pins on port B for output 
        PORTB = 0x7f;
      
        DDRD  = 0x00;               // use all pins on port D for input
        PORTD = 0xff;               // enable internal pull-up resistors
        USARTInit(UBRR);
        sei();                      // enable interrupts
        
        for(;;)    // loop forever
        {
            while ( RC5BitHigh() );           // wait until RC5 code received
            
            rc5data = rc5decode();
            if ( rc5data & 0x2000 ) {
               PORTB = ~(rc5data & 0x003f);   // output command bits of RC5 command
    		   tmp = ~(rc5data & 0x003f);
               nadajstring(tmp);
    	}
        }
    }
    


    Oto cały kod.
    Samo dekodowanie znalazłem na stronie w pierwszym poście ja dodałem tylko komunikację przez RS.
    Sama komunikacja przez RS działa OK bo przesyła odebrane znaki z klawiatury.
  • REKLAMA
  • Pomocny post
    #9 7461254
    michalko12
    Specjalista - Mikrokontrolery
    jaros85 napisał:
    
     
    //Wysłanie pojedynczego znaku
    void nadajznak (char dana1)
    {
    while(!(UCSRA & (1<<UDRE)));
    UDR=dana1;
    }
    
    //Zliczanie liter w wyrazie i wysyłanie ich do funkcji nadajznak
    void nadajstring (char *dana)
    {
    int dlugosc,i=0;
    dlugosc = strlen(dana);
    for(i=0;i<dlugosc;i++)
    	{
    	nadajznak(dana[i]);
    	}
    }
    
    
    
        
        for(;;)    // loop forever
        {
            while ( RC5BitHigh() );           // wait until RC5 code received
            
            rc5data = rc5decode();
            if ( rc5data & 0x2000 ) {
               PORTB = ~(rc5data & 0x003f);   // output command bits of RC5 command
    		   tmp = ~(rc5data & 0x003f);
               nadajstring(tmp);
    	}
        }
    }
    


    Oto cały kod.
    Samo dekodowanie znalazłem na stronie w pierwszym poście ja dodałem tylko komunikację przez RS.
    Sama komunikacja przez RS działa OK bo przesyła odebrane znaki z klawiatury.


    Nie wiem co chciałeś osiągnąć w tej procedurze:
    void nadajstring (char *dana)
    {
    int dlugosc,i=0;
    dlugosc = strlen(dana);
    for(i=0;i<dlugosc;i++)
       {
       nadajznak(dana[i]);
       }
    } 



    Funkcja przyjmuje wskaźnik jako argument, a ty wywołujesz ja podając jej bezpośrednio zmienną a nie adres. To po pierwsze.

    Po drugie. Co chcesz zmierzyć funkcją strlen()?
    Funkcja podaje długość stringa zakończonego znakiem \0, a ty żadnego stringa nawet nie tworzysz w tym programie.

    Funkcja którą ci wysłałem jest działająca
    void nadajstring (char dana)
    {
       unsigned char i;
       
       for(i=0; i<8; i++)
       {
             nadajznak(dana & 0x80 ? '1' : '0');
             dana<<=1;
       }
    }

    Jedyne co to są niezgodne typy danych, ty bez konwersji wywołujesz tą funkcję z int, ale nie powinno być z tym problemu

    Spróbuj:
       PORTB = ~((unsigned char)(rc5data & 0x003f));   // output command bits of RC5 command
       nadajstring(~PORTB);
       nadajstring(0xA5);             // dla sprawdzenia
    
    void nadajstring (unsigned char dana)
    {
       unsigned char i;
       
       for(i=0; i<8; i++)
       {
             nadajznak(dana & 0x80 ? '1' : '0');
             dana<<=1;
       }
        nadajznak('\r');
        nadajznak('\n');
    } 


    Nie wiem czy zauważyłeś, ale na załączonym obrazku hiperterminala masz wyłaczoną parzystość?????
  • REKLAMA
  • #10 7463029
    jaros85
    Poziom 20  
    Wielkie dzięki teraz już działa prawidłowo.
    Ale to było banalne.

    Co do parzystości to wiem bo tak jest ustawiony RS

    Jeżeli chodzi o wywołanie funkcji nadajstring to była ona przeznaczona pierwotnie do wysyłania stringa i tam była liczona jego długość myślałem że to i w tym momencie zadziała ale rzeczywiście myliłem się.

    A z którego miejsca tego dekodera RC5 mam pobrać dane żeby na RS wysłać całą ramkę 14 bitów :D
  • Pomocny post
    #11 7464808
    michalko12
    Specjalista - Mikrokontrolery
    jaros85 napisał:

    A z którego miejsca tego dekodera RC5 mam pobrać dane żeby na RS wysłać całą ramkę 14 bitów :D



    Wystarczy tylko trochę zmienić kod

    	PORTB = ~((unsigned char)(rc5data & 0x003f));   // output command bits of RC5 command
    	nadajstring(rc5data );
    
    
    void nadajstring (unsigned int dana)
    {
    	unsigned char i;
       
    	for(i=0; i<16; i++)
    	{
    		nadajznak(dana & 0x8000 ? '1' : '0');
    		dana<<=1;
    	}
    	nadajznak('\r');
    	nadajznak('\n');
    }
  • #12 7471870
    jaros85
    Poziom 20  
    Mam jeszcze jedno pytanie w jaki sposób przestawić preskaler Timer0 aby uC mógł by być taktowany zegarem 8MHz.
  • #13 7471894
    gothye
    Poziom 33  
    zmianę taktowania uC dokonujesz przez zmianę Fuse bitów procesora
  • Pomocny post
    #14 7472965
    michalko12
    Specjalista - Mikrokontrolery
    gothye napisał:
    zmianę taktowania uC dokonujesz przez zmianę Fuse bitów procesora

    Chyba nie chodziło o zmianę taktowania.

    Żeby ten kod działał z 8MHz zmień:

    #define F_CPU 8000000 
    #define TIMER_0_CNT 0x91     //  111us with CLK/8 prescale 
    
  • #15 7497464
    jaros85
    Poziom 20  
    Dziękuję za pomoc michalko12

    Już tylko ostatnie pytanie jak zależy wartość rejestru TCNT0 od częstotliwości taktowania :?:
    Wartość 0x91 jest dla 8MHz, 0xCA jest dal 4 MHz a w jaki sposób obliczyć dla dowolnej częstotliwości taktowania.

    Co do wysłania wszystkich 14 bitów kodu RC5 to niestety odbieram same zera w Hyper Terminalu coś jest nie tak
REKLAMA