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:
Jeśli natomiast przerwanie będzie wyglądać tak:
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.
#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.