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

12F675 toggle problem

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



Joined: 17 Jul 2010
Posts: 26

View user's profile Send private message

12F675 toggle problem
PostPosted: Sun Aug 08, 2010 1:19 am     Reply with quote

Hi all..
I have a problem about toggle to high on 12F675 I/O pin at below code. When I push IR remote on + button pin_A0 should toggle to high until I push on + button again, but they show high a while which long as time relay 200ms then go to low. I test same this code on 16F688 and all work fine. Please let me know what is wrong.
My ccs c is V 4.108.

Code:

// This is code for an IR remote control decoder
// using the 12 bit SIRC protocol. Based on code
// by Aurelian Nichita.
// Hardware - TSOP1738 to GP2 of 12F675. Two LEDs
// on GP4 and GP5 as indicators.
// Sample signal at TSOP data output (taken using
// PICKit2 as a logic analyzer):
//
// ??????\________/??\__/??\__/??\__/??\__/??\__/??\__/??\__/??\____/??\__/??\__/??\__/??\__/?????
// (idle)|  (start) | bit0| bit0| bit0|bit0| bit0| bit0| bit0| bit1 | bit0| bit0| bit0|bit0|(idle)
//
// TSOP data is inverted; it idles high.
// [??\_ : negative going edge; _/?? : positive going edge]
//
//original on Rohit de Sa   15Aug08  v1.0
//--------------------------------------------------------------------------------
#include <12f675.h>
#fuses INTRC_IO,noWDT,PUT,PROTECT,BROWNOUT,noMCLR,CPD
#use delay(clock=4000000)    //one instruction=1us
#use fast_io(a)                           
#zero_ram
#define one_min 1450               //no of counts to safely detect bit1
#define one_max 2200              //optimal @4 MHz is 1800 
#define zero_min 600               //no of counts to safely detect bit0     
#define zero_max 1440               //optimal @4 MHz is 1200 
#define out1 PIN_A0
#define out2 PIN_A4
int16 irframes[14];                  //holds incoming IR data
int8 ircount =0;                  //counts no if bits received
int1 irdone=false;                  //flag bit
int1 okbit  =true;
//--------------------------------------------------------------------------------
#int_ext                        //IR bits detected by edge triggering
void ext_isr()
{
   if(irdone) return;
   irframes[ircount++]=get_timer1();
   if(ircount>=13)                  //if 13 triggers(ie 12 bits+start) found
      irdone=TRUE;               //set "done" flag
   set_timer1(0);                  //restart timer for new bit
   enable_interrupts(int_timer1);      //(is this necessary? I dont really know)
}
//--------------------------------------------------------------------------------
#int_timer1                        //(is this isr necessary? I dont really know)
void timer1_isr()
{
   disable_interrupts(int_timer1);
}
//--------------------------------------------------------------------------------
#separate
int1 decode_ir(int8 &addr,int8 &cmd)   //IR decoding function
{
   int8 i;
   int8 mask;
   int1 bits[12];   
   addr=0;
   cmd=0;
   irframes[13]=1200;               //last bit is always zero   

   for(i=2;i<=13;i++)
      {
      if((one_min<=irframes[i])&&(irframes[i]<=one_max))
         bits[i-2]=0x01;            //if the sampled signal lies within limits
      else                              //set to 1
      if((zero_min<=irframes[i])&&(irframes[i]<=zero_max))
         bits[i-2]=0x00;            //if the sampled signal lies within limits
      else                              //set to 0
      return false;                  //otherwise clear flag
      }     
   mask=0x01;                     //format command
   for (i=0;i<=6;i++)
     {
      if (bits[i])
      cmd=cmd|mask;
      mask<<=1;
      }     
   mask=0x01;                     //format address
   for (i=7;i<=11;i++)
     {
      if(bits[i])
      addr=addr|mask;
      mask<<=1;
     }     
   return TRUE;                  //set flag
}
//--------------------------------------------------------------------------------
void start_ir()
{
   ircount=0;
   memset(irframes,0x00,sizeof(irframes));
   irdone=false;
}
//--------------------------------------------------------------------------------
void main()
{
   int8 addr, cmd;
   delay_ms(50);                   //setting up PIC
   set_tris_a(0b00000100);    // PINA5,A4,A3,A1,A0 =Output ,PINA2 =Input
                                          //timer prescaler dependent on oscillator speed
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   ext_int_edge(0,H_to_L);
   enable_interrupts(global);
   enable_interrupts(int_ext); 
   start_ir();

   while(TRUE)
   {     
      if (irdone)
      {
         decode_ir(addr, cmd);   
         delay_ms(50);
     
         if (okbit)     
           {
           output_bit(out2, 1);
           delay_ms(20);
           output_bit(out2, 0);
               if (addr==1||addr==0)
                {
                     switch (cmd)
                      {
                          case (0x07):         //push "8"
                          {
                          output_bit(out1, 1);
                          delay_ms(50);
                          output_bit(out1, 0);     
                           }                           
                           case (0x12):      //push "+"
                           {
                           output_toggle(out1);
                           delay_ms(200);
                           } 
                           case (0x04):       //push "5"
                           {
                           output_bit(out1, 1);
                           delay_ms(200);
                           output_bit(out1, 0);
                           }   
                   }                 
               }
           start_ir();
      } 
   }
 }
}
masterat



Joined: 17 Jul 2010
Posts: 26

View user's profile Send private message

PostPosted: Tue Aug 10, 2010 10:36 pm     Reply with quote

Any one please give me some hint?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 11, 2010 2:00 pm     Reply with quote

When you modify some code that you found on the forum, and have a
question about it, you should:

1. Post a link to the original code.

2. Post a list of the modifications that you did, and give the reasons
why you did each one.

If the original code has some timing calculations, such as a timer
interrupt rate, you should show how your modified code maintains
the same timing as the original code.
masterat



Joined: 17 Jul 2010
Posts: 26

View user's profile Send private message

PostPosted: Wed Aug 11, 2010 8:07 pm     Reply with quote

Thank you for your kindly suggestion.I hope will have some one who pass this test and get some experience wellcome to give me a hints.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Aug 11, 2010 8:41 pm     Reply with quote

masterat wrote:
Thank you for your kindly suggestion.I hope will have some one who pass this test and get some experience wellcome to give me a hints.


You're not making any sense...

If you can't explain more than just posting code and asking for help even when someone tries to get you to elaborate more, you're going to find yourself in a very quiet room. (virtually speaking)

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu Aug 12, 2010 11:23 am     Reply with quote

try adding 'break;' at the end of each case statement so they don't flow into the next case.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Thu Aug 12, 2010 3:07 pm     Reply with quote

That's a good point...

is:

Code:

 case (0x04):       //push "5"
                           {
                           output_bit(out1, 1);
                           delay_ms(200);
                           output_bit(out1, 0);
                           }   


Valid 'C' syntax?

It looks like you're writing in something scripting-like for Unix. (the braces) and yes, it's missing the break;

That almost looks like PERL.
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
andrewg



Joined: 17 Aug 2005
Posts: 316
Location: Perth, Western Australia

View user's profile Send private message Visit poster's website

PostPosted: Thu Aug 12, 2010 8:48 pm     Reply with quote

bkamen wrote:
That's a good point...

is:

Code:

 case (0x04):       //push "5"
                           {
                           output_bit(out1, 1);
                           delay_ms(200);
                           output_bit(out1, 0);
                           }   


Valid 'C' syntax?


Yes. Braces can show up just about anywhere. I'll do things like:
Code:

  // code here
  #ifdef DEBUG
  {
    int8 i;
    // debug code that uses i here
  }
  #endif
  // more code here
The braces let me keep any variables needed by the debug code with the debug code. See http://en.wikipedia.org/wiki/Duffs_device for more interesting syntax.
_________________
Andrew
masterat



Joined: 17 Jul 2010
Posts: 26

View user's profile Send private message

PostPosted: Fri Aug 13, 2010 4:50 am     Reply with quote

pmuldoon wrote:
try adding 'break;' at the end of each case statement so they don't flow into the next case.


Thank you for all suggestion.Edit to last code include break; command in final of all case and reduce some out but result same. Especially output_toggle() command will toggle till end of delay time then switch to 0 .
Below is last code.
Code:
#include <12f675.h>
#fuses INTRC_IO,NOWDT,PUT,PROTECT,NOBROWNOUT,NOMCLR,CPD
#use delay(clock=4000000)    //one instruction=1us
#use fast_io(a)                           
#zero_ram
#rom  0x3ff={0x3494}            // get value from pkit2 function
#define one_min 1450               //no of counts to safely detect bit1
#define one_max 2200              //optimal @4 MHz is 1800 
#define zero_min 600               //no of counts to safely detect bit0 600
#define zero_max 1440            //optimal @4 MHz is 1200 
#define out1 PIN_A0
#define out2 PIN_A4
int16 irframes[14];                  //holds incoming IR data
int8 ircount =0;                      //counts no if bits received
int1 irdone=false;                   //flag bit
//--------------------------------------------------------------------------------
#int_ext                        //IR bits detected by edge triggering
void ext_isr()
{
   if(irdone) return;
   irframes[ircount++]=get_timer1();
   if(ircount>=13)                  //if 13 triggers(ie 12 bits+start) found
      irdone=TRUE;               //set "done" flag
   set_timer1(0);                  //restart timer for new bit
   disable_interrupts(int_timer1);
}
//--------------------------------------------------------------------------------
#separate
int1 decode_ir(int8 &addr,int8 &cmd)   //IR decoding function
{
   int8 i;
   int8 mask;
   int1 bits[12];   
   addr=0;
   cmd=0;
   irframes[13]=1200;               //last bit is always zero   

   for(i=2;i<=13;i++)
      {
      if((one_min<=irframes[i])&&(irframes[i]<=one_max))
         bits[i-2]=0x01;            //if the sampled signal lies within limits
      else                              //set to 1
      if((zero_min<=irframes[i])&&(irframes[i]<=zero_max))
         bits[i-2]=0x00;            //if the sampled signal lies within limits
      else                              //set to 0
      return false;                  //otherwise clear flag
      }     
   mask=0x01;                     //format command
   for (i=0;i<=6;i++)
     {
      if (bits[i])
      cmd=cmd|mask;
      mask<<=1;
      }     
   mask=0x01;                     //format address
   for (i=7;i<=11;i++)
     {
      if(bits[i])
      addr=addr|mask;
      mask<<=1;
     }     
   return TRUE;                  //set flag
}
//--------------------------------------------------------------------------------
void flash (char x) {
    while (x>0) {
        output_low (out1);
        delay_ms (250);
        output_high (out1);
        delay_ms (250);
        x--;
    }
}
//--------------------------------------------------------------------------------
void start_ir()
{
   ircount=0;
   memset(irframes,0x00,sizeof(irframes));
   irdone=false;
}
//--------------------------------------------------------------------------------
void main()
{
   int8 addr, cmd;
   set_tris_a(0b00000100);    // PINA5,A4,A3,A1,A0 =Output ,PINA2 =Input
   output_a(0b00000000);    // clear all bit =0
   flash (5);                          //flash out1 5 time tell that running ok
   delay_ms(50);                   //setting up PIC
                                          //timer prescaler dependent on oscillator speed
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   ext_int_edge(0,H_to_L);
   enable_interrupts(global);
   enable_interrupts(int_ext); 
   start_ir();
   while(TRUE)
   {     
      if (irdone)
      {
         decode_ir(addr, cmd);   
         delay_ms(50);     
         output_bit(out1, 1);
         delay_ms(20);
         output_bit(out1, 0);
               if (addr==1||addr==0)
                {
                     switch (cmd)
                      {
                          case (0x07):         //push "8"
                          {
                          output_bit(out2, 1);
                          delay_ms(50);
                          output_bit(out2, 0);   
                           break;   
                           }                           
                           case (0x12):      //push "+"
                           {
                           output_toggle(out2); // Out2 should be toggle between 1 or 0
                           delay_ms(200);   // delay for leave from IR button
                           break;
                           } 
                           case (0x04):       //push "5"
                           {
                           output_bit(out2, 1);
                           delay_ms(200);
                           output_bit(out2, 0);
                           break;
                           }   
                   }                 
       } 
         start_ir();
   }
 }
}


When power on cpu start up output flash 5 times to PIN_A0 is working fine then wait for receive IR Remote ,every time when I press on remote code 0x12 PIN_A4 toggle a while and goto 0.Another remote code work fine.
Seem,when end case loop cpu sent some auto command to set bit low.

ccsC asm list code is
Code:
122:                                    switch (cmd)
123:                                     {
   1BC    084B     MOVF 0x4b, W
   1BD    3A07     XORLW 0x7
   1BE    1903     BTFSC 0x3, 0x2
   1BF    29C7     GOTO 0x1c7
   1C0    3A15     XORLW 0x15
   1C1    1903     BTFSC 0x3, 0x2
   1C2    29CD     GOTO 0x1cd
   1C3    3A16     XORLW 0x16
   1C4    1903     BTFSC 0x3, 0x2
   1C5    29D3     GOTO 0x1d3
   1C6    29D9     GOTO 0x1d9
124:                                         case (0x07):         //push "8"
125:                                         {
126:                                         output_bit(out2, 1);
   1C7    1605     BSF 0x5, 0x4
127:                                         delay_ms(50);
   1C8    3032     MOVLW 0x32
   1C9    00CD     MOVWF 0x4d
   1CA    2060     CALL 0x60
128:                                         output_bit(out2, 0);   
   1CB    1205     BCF 0x5, 0x4
129:                                          break;   
   1CC    29D9     GOTO 0x1d9
130:                                          }                           
131:                                          case (0x12):      //push "+"
132:                                          {
133:                                          output_toggle(out2); // Out2 should be toggle between 1 or 0
   1CD    3010     MOVLW 0x10
   1CE    0685     XORWF 0x5, F
134:                                          delay_ms(200);   // delay for leave from IR button
   1CF    30C8     MOVLW 0xc8
   1D0    00CD     MOVWF 0x4d
   1D1    2060     CALL 0x60
135:                                          break;
   1D2    29D9     GOTO 0x1d9
136:                                          } 
137:                                          case (0x04):       //push "5"
138:                                          {
139:                                          output_bit(out2, 1);
   1D3    1605     BSF 0x5, 0x4
140:                                          delay_ms(200);
   1D4    30C8     MOVLW 0xc8
   1D5    00CD     MOVWF 0x4d
   1D6    2060     CALL 0x60
141:                                          output_bit(out2, 0);
   1D7    1205     BCF 0x5, 0x4
142:                                          break;
   1D8    29D9     GOTO 0x1d9
143:                                          }   
144:                                  }                 
145:                      } 
146:                        start_ir();
   1D9    2082     CALL 0x82
147:                  }
148:                }
   1DA    29A7     GOTO 0x1a7
   1DB    0063     SLEEP


Code:
93:                   ircount=0;
   082    01C8     CLRF 0x48
94:                   memset(irframes,0x00,sizeof(irframes));
   083    0185     CLRF 0x5
   084    302C     MOVLW 0x2c
   085    0084     MOVWF 0x4
   086    01CC     CLRF 0x4c
   087    301C     MOVLW 0x1c
   088    00CD     MOVWF 0x4d
95:                   irdone=false;
   091    1049     BCF 0x49, 0
96:                }
   092    0008     RETURN
97:                //--------------------------------------------------------------------------------
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Fri Aug 13, 2010 6:01 am     Reply with quote

sounds like you're int routine is firing again and resetting 'irdone'.
with the other commands it would go unnoticed, but with the toggle it will change state.
Try putting in a very long delay in start_ir() before clearing irdone. That may tell you if your unintentially processing a second command from the remote. Then you'll know what to fix.
masterat



Joined: 17 Jul 2010
Posts: 26

View user's profile Send private message

PostPosted: Fri Aug 13, 2010 8:00 am     Reply with quote

pmuldoon wrote:
sounds like you're int routine is firing again and resetting 'irdone'.
with the other commands it would go unnoticed, but with the toggle it will change state.
Try putting in a very long delay in start_ir() before clearing irdone. That may tell you if your unintentially processing a second command from the remote. Then you'll know what to fix.


Wow Thank you! Your hints is very good I found by use your delay technic. Found that output port was reset by memset command. I replace 13 irframes by normal operator all done.
Thank again.
Code:
void start_ir()
{
   ircount=0;

//   memset(irframes,0x00,sizeof(irframes));
 irframes[0]=0x00;
 irframes[1]=0x00;
 irframes[2]=0x00;
 irframes[3]=0x00;
 irframes[4]=0x00;
 irframes[5]=0x00;
 irframes[6]=0x00;
 irframes[7]=0x00;
 irframes[8]=0x00;
 irframes[9]=0x00;
 irframes[10]=0x00;
 irframes[11]=0x00;
 irframes[12]=0x00;

   irdone=false;
}
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