CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

sony ir receiver

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kara_kalem



Joined: 15 Oct 2006
Posts: 1

View user's profile Send private message

sony ir receiver
PostPosted: Sat Jul 04, 2009 3:35 am     Reply with quote

Code:
/
#include <16f877.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

// Denetleyici konfigürasyon ayarları
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay (clock=4000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.

#use fast_io(a) //Port yönlendirme komutları A portu için geçerli
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli
#include<lcd.c>

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#ignore_warnings none

#zero_ram

/* TIMER0 configuration */
#define TIMER0_CONFIG   RTCC_INTERNAL | RTCC_DIV_1

/* Interrupt rate:                     */
/* 4/32000000*65536*1 = 8.192 ms       */
/*  4/4000000*65536*1 = 65,53 ms                                   */
/*     Start: 3.0 ms (ignored)         */
/*     "1":   1.8 ms (1800)           */
/*     "0":   1.2 ms  (1200)           */

#define one_min 1675               //no of counts to safely detect bit1
#define one_max 1925               //optimal @4 MHz is 1800
#define zero_min 1075               //no of counts to safely detect bit0
#define zero_max 1325


/* irframes[0] (start) will be garbage, ignore it...  */
int16 irframes[13];
int8 ircount = 0;
int1 irdone = FALSE;


#int_ext
void ext_isr() {
  if (irdone) return;
  irframes[ircount++] = get_timer0();
  if (ircount >= 13)
    irdone = TRUE;
    ircount++;
  set_timer0(0);
 enable_interrupts(INT_TIMER0);
}


#int_timer0
void timer0_isr() {
  disable_interrupts(INT_TIMER0);
}


#separate
int1 decode_ir(int8 &addr, int8 &cmd) {
  int8 i;
  int8 mask;
  int8 bits[13];

  addr = 0;
  cmd = 0;

  for (i=1; i<=12; i++) {
    if ((ONE_MIN <= irframes[i]) && (irframes[i] <= ONE_MAX))
      bits[i] = 0x01;
    else
      if ((ZERO_MIN <= irframes[i]) && (irframes[i] <= ZERO_MAX))
        bits[i] = 0x00;
      else        // Error
        return FALSE;
  }

  mask = 0x01;
  for (i=1; i<=7; i++) {
    if (bits[i])
      cmd = cmd | mask;
    mask <<= 1;
  }

  mask = 0x01;
  for (i=8; i<=12; i++) {
    if (bits[i])
      addr = addr | mask;
    mask <<= 1;
  }

  return TRUE;
}


void start_ir() {
  memset(irframes, 0x00, sizeof(irframes));
  ircount = 0;
  irdone = FALSE;
  set_timer0(0); //++
}



/********* ANA PROGRAM FONKSİYONU********/

void main ( )
{
int duty;

 int8 addr, cmd;
  int1 ok;
 
 
  delay_ms(100);
 


  set_tris_c(0b11111011);  // PIN_C2 used for the LED
 
 
  setup_spi(FALSE);
 
 
   //set_tris_a(0x03);   // RA0 ve RA1 pinleri giriş
   set_tris_c(0x00);   // C portu komple çıkış

 
 lcd_init();
 output_bit(PIN_C2, 0);
 delay_ms(100);

  lcd_putc("\fWaiting...");
 setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_spi(SPI_SS_DISABLED);     // SPI birimi devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_timer_1(T1_DISABLED);
   setup_timer_0(TIMER0_CONFIG);
  setup_timer_2(T2_DISABLED, 255, 1);
 
  ext_int_edge(0, L_TO_H);
  enable_interrupts(INT_EXT);
  enable_interrupts(GLOBAL);

  start_ir();
//#ignore_warnings 203
  while(TRUE) {
//#ignore_warnings NONE
    if (irdone) {
      ok = decode_ir(addr, cmd);
      printf(lcd_putc, "\fCmd  %3u\nAddr %3u", cmd, addr);
      if (!ok)
        lcd_putc("  ERROR");
      else
        output_bit(PIN_C2, 1);
      delay_ms(50);
      output_bit(PIN_C2, 0);
      start_ir();
    }
  }
}



i use in my project 16f877 and 4Mhz crystal, but i think wrong some think at TIMER0's timing. Can any one help me?
Ttelmah
Guest







PostPosted: Sat Jul 04, 2009 4:45 am     Reply with quote

Several comments:
First, after setting the interrupt edge, and _before_ enabling the interrupt, _clear_ INT_EXT. Whenever you change the active edge on an interrupt, it can result in the interrupt being set. This is in the data sheet.
Second, why on earth are you enabling int_timer0?. This just potentially results in a 'wasted' call to the timer handler.... You are not using timer0, as an interrupt at all, but just as a counter, to 'time' the period from one edge to the next.
The third problem is that you increment ircount, _twice_ in each ISR... This is a killer.
Then you have the problem of timing. It takes _time_ to get into the ISR. perhaps 30 counts of timer0. Then it takes time to write the value to an array (perhaps another 20 instructions). The test a few more instructions. When you set timer0, back to zero, you are effectively losing, perhaps 30+ counts from the time between the edges.
Better, to clear timer0, _once_ on the first edge. Then just record it's values. Even better, use the CCP, to allow the value on the timer to be accurately recorded, at the moment the edge goes high.
Your code really needs to ensure the IR line _is_ low, before starting counting edges, or it'll never resynchronise if an edge is missed. You could even use the timer interrupt, as a 'timeout'.
A search here will find posts about using an interrupt flag, without using an interrupt handler, as a faster way of performing this type of handling.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group