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

Wpisywanie wartości do tablicy, ATmega16 - jak wykonać?

Drako1988 29 Sty 2010 13:00 1243 2
REKLAMA
  • #1 7610355
    Drako1988
    Poziom 20  
    Witam serdecznie. Z racji chwili wolnego czasu piszę sobie kod do odbiornika IR na ATmega16. Korzystam ze scalonego odbiornika TSOP1736. O tym jak wygląda kodowanie sygnału w przypadku pilota do telewizora firmy Philips dowiedziałem się ze strony http://www.sbprojects.com/knowledge/ir/rc5.htm. Po odkodowaniu sygnału wszystko jest ok, ale tutaj pojawił się problem. Otóż w przerwaniu Timera 1 program nie chce wpisywać wartości do tablicy(przynajmniej po wielu próbach doszedłem do takiego wniosku). Poniżej przedstawiam kod:

    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <stdint.h>
    #include <stdlib.h> 
    
    #ifndef F_CPU
    #define F_CPU 16000000ul
    #endif
    
    #include "lcd.h"
    
    #define IR_PORT PORTD
    #define IR_PIN PIND
    
    #define IR 3
    
    //#define MY_OCR(time, prescaler)	( (time * F_CPU)/(2*prescaler) - 1 )
    
    #define SBI(addr, bit)	(addr |= (1<<bit)) 
    #define CBI(addr, bit)	(addr &= ~(1<<bit)) 
    #define TBI(addr, bit)	(addr ^= (1<<bit)) 
    
    #define D_ON	(SBI(PORTD, PD0))
    #define D_OFF	(CBI(PORTD, PD0))
    #define D_TOG	(TBI(PORTD, PD0))
    
    #define INT1_FALLING (CBI(MCUCR, ISC10)); (SBI(MCUCR, ISC11)); (SBI(GICR, INT1))
    #define INT1_RISING	 (SBI(MCUCR, ISC10)); (SBI(MCUCR, ISC11)); (SBI(GICR, INT1))
    #define INT1_OFF	 (CBI(GICR, INT1))
    
    #define START_CLOCK		SBI(TCCR1B, WGM12); SBI(TCCR1B, CS10); SBI(TIMSK, OCIE1A)
    #define STOP_CLOCK		CBI(TCCR1B, CS10);
    
    volatile int kod[26];
    volatile int licznik = 0;
    volatile int DlugoscKodu = 0;
    
    ISR(TIMER1_COMPA_vect)
    {
    	if(bit_is_set(IR_PIN, IR))
    	{
    		kod[licznik++] = 0;
    	}
    	else if(bit_is_clear(IR_PIN, IR))
    	{
    		kod[licznik++] = 1;
    	}
    	if(licznik >= 26)
    	{
    		STOP_CLOCK;
    		_delay_ms(100);
    		INT1_FALLING;
    	}
    }
    
    ISR(INT1_vect)	//wywołane po wykryciu pierwszego znaku wysłanego z pilota
    {
    	licznik = 0;
    	INT1_OFF;
    	_delay_us(450);	//czekaj aby próbkować sygnały w połowie ich czasu trwania
    	START_CLOCK;
    }
    
    int main(void)
    {
    	uint8_t kod[13];
    	char buf[10];
    
    	DDRD = 0b11110011;
    	PORTD = 0b00001100;
    	OCR1A = 14396;	//na czas 450 us
    
    	lcd_init(LCD_DISP_ON);
    	INT1_FALLING;
    
    	sei();
    	
    	while(1)
    	{
    		if(licznik >= 26)
    		{
    			for(int i = 0; i < 26; i++)
    			{	
    				if(kod[i] == 0)
    					lcd_putc('0');
    				else if(kod[i] == 1)
    					lcd_putc('1');
    				else
    				{
    					itoa(kod[i], buf, 10);
    					lcd_puts(buf);
    				}
    			}
    			_delay_ms(1000);
    		}
    	}
    
    	return 0;
    }
    


    Jeśli natomiast przerwanie będzie wyglądać tak:

    
    ISR(TIMER1_COMPA_vect)
    {
    	if(bit_is_set(IR_PIN, IR))
    	{
    		lcd_putc('0');
    	}
    	else if(bit_is_clear(IR_PIN, IR))
    	{
    		lcd_putc('1');
    	}
    	if(licznik == 16)
    		lcd_gotoxy(0,1);
    	if(licznik >= 26)
    	{
    		STOP_CLOCK;
    		_delay_ms(100);
    		INT1_FALLING;
    	}
    }
    


    To na wyświetlaczu ukazuje mi się pełny odkodowany sygnał (w postaci zero jedynkowej) Nie wiem w czym może być problem bo wydaje mi się że próbowałem już wszystkiego. Proszę o pomoc w tej sprawie. Dodam, że ATmega pracuje na kwarcu 16MHz a wersja avrStudio na jakiej pracuję to 4.16. Z góry serdecznie dziękuję za pomoc.
  • REKLAMA
  • #2 7610377
    _Robak_
    Poziom 33  
    Masz dwa razy deklaracje tablicy kod[]. Z tego co pamiętam to zmienna lokalna przysłania globalną, więc w mainie i przerwaniu operujesz na dwóch róznych zmiennych.

    EDIT:
    Tak, dobrze pamiętam, lokalna zmienna przesłania globalną ;)
  • #3 7610734
    Drako1988
    Poziom 20  
    Dzięki Ci wielki, przesiadując tyle nad tym kodem pominąłem taki detal. Teraz już wszystko śmiga. I można pobawić się pilocikiem.

    Pozdrawiam.
REKLAMA