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 support@ccsinfo.com

Problem with IR transmitter project

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



Joined: 16 Sep 2008
Posts: 51

View user's profile Send private message Send e-mail

Problem with IR transmitter project
PostPosted: Mon Jan 12, 2009 11:45 am     Reply with quote

Hello 2 all !

I'm trying to design a IR transmitter using pic18f452 @ 10 Mhz and CCS C compiler version 4.057.

Unfortunately, the code doesn't work as it should and i don't know where the problem lies.

So....any input is more than welcomed.

I wish to say that i've researched the problem for over 1 week and the solution eludes me ...for the moment.

So...i get a character from the serial port, i convert it to binary form and then modulate the waveform.

Assuming i'm transmitting a command like : 00000010 (0x02) i aspect that the output should be under the form :
Code:
 

     ___     ___     ___     ___     ___     ___         ______
    |   |   |   |   |   |   |   |   |   |   |   |       |      |
    |   |   |   |   |   |   |   |   |   |   |   |       |      |
-----   -----   -----   -----   -----   -----   ---------      -----
    |       |       |       |       |       |       |       |       |
    |bit 1=0|bit 2=0|bit 3=0|bit 4=0|bit 5=0|bit 6=0|bit 7=1|bit 8=0|

 |


As you can see:
- a logic bit "0" is represented as a portion of 0,842 ms "HIGH" and a portion of 0,842 ms "LOW"
- a logic bit "1" represented as a portion of 0,842 ms "LOW" and a portion of 0,842 ms "HIGH"

Here is the code of the application (i haven't used the PWM module for simplicity):

Code:


#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
char i,c,d;

#INT_TIMER0
void timer0_isr( )
{
   boolean led_on0,led_on1;
   switch(d)
             {
      case '0':
          if (led_on0)
                  {
               set_timer0(131);
               led_on0 = false;
               output_low(pin_b1);       //for debuging purposes only
                  }
               else
                  {
              set_timer0(131);
              led_on0 = true ;
              output_high(pin_b1);      //for debuging purposes only
              }
              break;
       case '1':
              if (led_on1)
                  {
               set_timer0(131);
               led_on1 = false;
               output_high(pin_b2);    //for debuging purposes only
                  }
               else
                  {
              set_timer0(131);
              led_on1 = true ;
              output_low(pin_b2);     //for debuging purposes only
                  }
              break;     
             
       default: output_high(pin_b7);       
}
}

//==================================
void main()
 {
 char c,i,d, buffer[9];
 unsigned int16 timeout;
 output_toggle(pin_b0);
 setup_timer_0(RTCC_INTERNAL |RTCC_8_BIT | RTCC_DIV_16);
 
 do {
while(!kbhit() && (++timeout< (5000)))
      delay_us(10);
   if(kbhit())         
{
c=getc();
for(i = 0; i < 8; i++)
{
if(c & 0x80)
 d='1';
 else
 d='0';
c <<= 1;
buffer[i]=d;
}
buffer[8]=0;
}
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0); 
set_timer0(131);
} while(true);
 }



Thank you very much !!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Jan 12, 2009 6:10 pm     Reply with quote

There are several problems in your code.
First of all, make reading to us easier by getting the indentation right. This will get you quicker and better responses.

Code:
    while(!kbhit() && (++timeout< (5000)))
      delay_us(10);
Timeout is never initialised, so the first time you have an undefined timeout and for all the next loops the timeout will be much larger than you expected.

Why do you have this loop of 50ms here anyway?

Code:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
at 9600 baud characters will be received at about 1 char per ms. With the delay of 50ms there is a good chance of the hardware UART receive buffer overflowing (it can only buffer up to 3 characters). At overflow the UART will top receiving until the error condition is reset.
Add the 'ERRORS' directive to the above RS232 setup so the CCS compiler will add code for resetting the error condition.
Code:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, errors)


Code:
   switch(d)
The variable 'd' in the interrupt handler is not the same 'd' as used in main. One is global and the other local.

There are some more problems involved with the way you are trying to use the interrupt, for example the value of 'd' never changes after the first interrupt, so how do you want to generate a pulse train?

Why do you want to use interrupts? Your code would be much easier if you forget about interrupts and implement the delays using delay_us() instead.
Andrew83



Joined: 16 Sep 2008
Posts: 51

View user's profile Send private message Send e-mail

PostPosted: Tue Jan 13, 2009 3:54 am     Reply with quote

Thank you ckielstra !

You were absolutely right about everything. Smile

I've managed to obtain the desired output using the delay_us() function.
However, there is a small problem.
First of all, i have to mention that i don't have a oscilloscope at hand (i am a highschool student) so my means of verifying the correct operation are relatively small. However, i'm using a pic simulator from OSHON (version 2.55). The simulation results, show that when i set the value: delay_us(842), the actual duration is close to 800 uS, so i've loaded a value of 845 and got a duration of about 836 uS wich is close enough to 842 uS (i think).

So, knowing this, i've tryed to use interrupts in the hope that i could get as close to 842 uS as possible.

I'm sorry for the foolish code i posted last night ...it was late. Embarassed

Today, i've modified the code in the following way (BUT IT STILL ISN'T WORKING THE WAY IT SHOULD) :

Code:


#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
char buffer[9];

#INT_TIMER0
void timer0_isr( )
{
 boolean led_on0, led_on1;
 char n;
 
      for(n=0; n<8 ;n++)
              {
          switch(buffer[n])
                  {
case '0':       
          if (led_on0 )              //Logic ZERO
                  {
             set_timer0(128);        //Logic ZERO
             led_on0 = false;        //Logic ZERO
             //setup_ccp1(ccp_off);  //Logic ZERO
             output_low(pin_b1);     //Logic ZERO
                  }
               else
                  {
             set_timer0(128);        //Logic ZERO
             led_on0 = true ;        //Logic ZERO
             //setup_ccp1(CCP_PWM);  //Logic ZERO
             output_high(pin_b1);    //Logic ZERO
                  }
       
case '1':
             if (led_on1)            //Logic ONE
                  {
             set_timer0(128);        //Logic ONE
             led_on1 = true ;        //Logic ONE
             //setup_ccp1(CCP_PWM);  //Logic ONE
             output_high(pin_b1);    //Logic ONE
                  }
               else
                  {
              set_timer0(128);       //Logic ONE
              led_on1 = false;       //Logic ONE
              //setup_ccp1(ccp_off); //Logic ONE
              output_low(pin_b1);    //Logic ONE
                  }
               }
             }
           }
           
//==================================
void main()
 {
 char c,d,i;
 setup_timer_2(T2_DIV_BY_1, 65, 1);
 set_pwm1_duty(32);
 setup_timer_0(RTCC_INTERNAL |RTCC_8_BIT | RTCC_DIV_16);

 while(1)
  {
   if(kbhit())         
      {
         c=getc();
         for(i = 0; i < 8; i++)
            {
             if(c & 0x80)
               d='1';
             else
               d='0';
               c <<= 1;
               buffer[i]=d;
             }
        buffer[8]=0;
        enable_interrupts(INT_TIMER0);
        enable_interrupts(GLOBAL);
        set_timer0(255);
        output_toggle(pin_b0);
         }
     }
 }
 



Please verify the following statements and correct me, where i'm wrong:

1. If a character is transmitted over serial, i get it and store it in "char c".
2. I convert the variable c, into binary form, and store the result into a array "buffer[9]" wich is declared as a global, because i have tu use it also in the interrupt.
3. As soon as the conversion is done, i have to go to the ISR. So..i eneble the interrupt and load the timer with a value of 255 to imediately go to the ISR routine.
4. In the ISR routine, i go through the buffer and compare each of it's elements with the character '0', respectively '1'.
5. I modulate the waveform accordingly.

Where is my mistake ?? Please help me to understand the correct way of doing these things !
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