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

[atmega8] wysyłanie RC5 w C - proszę o pomoc

esnow 05 Sty 2010 12:18 1857 4
REKLAMA
  • #1 7487934
    esnow
    Poziom 14  
    witam,
    zrobiłem wysyłanie RC5 na zwykłych delay'ach... (czemu delay? bo na timerze nie potrafiłem) rozwiązanie działa, ale po pewnym czasie opóźnienie najprawdopodobniej się zmienia i wysyłane są inne komendy.

    dioda nadawcza IR jest podłączona przez tranzystor PNP BC516 (stan niski na bazie powoduje świecenie diody)
    baza tranzystora jest na porcie PB1(OC1A)

    jak zrobić to wykorzystując TIMER w trybie toggle? (modulacja 36kHz)

    obecny kod:
    
    void rc5send(uint16_t adres, uint16_t komenda)
    {
    uint16_t temp=0;  //zmienna tymczasowa
    uint16_t RRR=0;   //kod rc5
    
    adres <<= 6;      //przesunięcie adresu na odpowiednia pozycje w kodzie rc5
    
    RRR = start_toggle + adres + komenda;  //złożenia w całość ramki RC5
    
    	for(int i=13; i>=0; i--)  //wysłanie 14 bitów ramki rc5
    	{
    		PORTC ^= _BV(5); // mrugniecie dioda
    		temp=RRR>>i;     // kolejny bit
    		if(!(temp & 1))
    		{
    			for(int i=0; i<32; i++) //stan wysoki modulacja 36kHz
    			{
    				PORTB &= ~_BV(1);
    				_delay_us(13.88);
    				PORTB |= _BV(1);
    				_delay_us(13.88);
    			}
    			
    			for(int i=0; i<64; i++) //stan niski
    				_delay_us(13.88);			
    		}
    		else
    		{
    			for(int i=0; i<64; i++)
    				_delay_us(13.88);
    			
    			for(int i=0; i<32; i++)
    			{
    				PORTB &= ~_BV(1);
    				_delay_us(13.88);
    				PORTB |= _BV(1);
    				_delay_us(13.88);
    			}			
    		}
    	}
    }
    
  • REKLAMA
  • REKLAMA
  • #3 7510170
    esnow
    Poziom 14  
    ok poradziłem sobie z nadawaniem:
    
    //init
        TCCR1A = (1<<COM1A0);
        TCCR1B = (1<<WGM12)|(1<<CS10);
        OCR1A = F_CPU/2/36000L;
    
    
    //RRR 14 bit code
    
      for (int i = 13; i >= 0; i--)
      {
        if (RRR & (1 << i))
        {
          TCCR1A &= ~(1 << COM1A0);
          _delay_us(889);
          TCCR1A |= (1 << COM1A0);
          _delay_us(819);
        }
        else
        {
           TCCR1A |= (1 << COM1A0);
          _delay_us(889);
          TCCR1A &= ~(1 << COM1A0);
          _delay_us(819);
        }
      }
     
      _delay_us(70);
      TCCR1A &= ~(1 << COM1A0);
      _delay_ms(89);  //przerwa pomiedzy dwiema ramkami 
    


    ale mam jeszcze taki problem, że jak w termianlu przytrzymam dłużej jakiś klaiwsz, np. "3" i potem naduszę inny TO ZA KAŻDYM RAZEM MUSZĘ DANY KLAWISZ 4 RAZY aby został wysłany.

    nie wiem jak się z tym uporać, że potem gdy wciskam inny klawisz to lecą 3 poprzednie rozkazy najpierw z każdym wciśnięciem klawisza.

    funkcje USART przepisane z noty katalogowej atmegi8

    pętla główna programu:
    
        while(1)  
        {
    	    //nadawanie rc5 - przykładowe działanie guziki 0-9.
    		if(bit_is_clear(PIND,PD0))
    		{
    			char xxx = USART_Receive();
    			if(atoi(&xxx)>=0 && atoi(&xxx)<=9)
    			rc5send(atoi(&xxx));
    			
    		}
    		
    		//odbieranie rc5 
    		if(RC5BitLow())
    			rc5decode();
    			
    			
        }
    
  • REKLAMA
  • #4 7513987
    wladziu22
    Poziom 17  
    Cytat:
    ..ale mam jeszcze taki problem, że jak w termianlu przytrzymam dłużej jakiś klaiwsz, np. "3" i potem naduszę inny TO ZA KAŻDYM RAZEM MUSZĘ DANY KLAWISZ 4 RAZY aby został wysłany.

    nie wiem jak się z tym uporać, że potem gdy wciskam inny klawisz to lecą 3 poprzednie rozkazy najpierw z każdym wciśnięciem klawisza.


    Nie, chcę być upierdliwy ..ale proszę napisz to jeszcze raz, bo nie rozumiem...
    Jak przytrzymasz dłużej jakiś klawisz to wysyła Ci sie więcej niż jedna ramka RC5 ?

    A czy na terminalu jak wlaczysz "echo" to trzymając np "3" - na klawiaturze to nie wyświetla się czasem ciąg "3"-jek? Jeśli by tak bylo to ramka powinna wysłać się tyle razy ile jest tych trojek (nie mam portu com w laptopie wiec nie sprawdzę). Standardowa funkcja USART_Receive(); powinna odbierać tylko jeden znak, czyli następnie powinna być wysłana jedna ramka RC5.

    
    if(bit_is_clear(PIND,PD0)) 
    ..

    Nie wiem jeszcze co przez to chcesz osiągnąć, tzn co tam masz podłączone? Jakiś button/microSwitch?

    Kiedys robilem na ATmega16 i powineiens miec tak samo:
    
    	unsigned int USART_odbior(void)
    	{
    		while(!(UCSRA & _BV(RXC)))
    
    		return UDR;					//wpisuje dane do bufora
    	}
    

    
    ...
    do
    {
    //podaj liczbe od 0-9
    unsigned char b = USART_odbior();
    
    switch(b)
    {
    case '0':
    ... wyslij kod jakis tam w postaci ramki RC5
    break;
    case '1'
    ... wyslij kod jakis tam w postaci ramki RC5
    break;
    ...
    default:
    break;
    }
    
    }while(1);
    
  • #5 7514111
    esnow
    Poziom 14  
    już rozwiązałem ten problem, odbieram znak w przerwaniu i wszystko działa elegancko!
REKLAMA