  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			masterat
 
 
  Joined: 17 Jul 2010 Posts: 26
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| 12F675 toggle problem | 
			 
			
				 Posted: Sun Aug 08, 2010 1:19 am     | 
				     | 
			 
			
				
  | 
			 
			
				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
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Tue Aug 10, 2010 10:36 pm     | 
				     | 
			 
			
				
  | 
			 
			
				| Any one please give me some hint? | 
			 
		  | 
	 
	
		  | 
	 
	
		
			PCM programmer
 
 
  Joined: 06 Sep 2003 Posts: 21708
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Aug 11, 2010 2:00 pm     | 
				     | 
			 
			
				
  | 
			 
			
				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
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Aug 11, 2010 8:07 pm     | 
				     | 
			 
			
				
  | 
			 
			
				| 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: 1617 Location: Central Illinois, USA 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Aug 11, 2010 8:41 pm     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Aug 12, 2010 11:23 am     | 
				     | 
			 
			
				
  | 
			 
			
				| 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: 1617 Location: Central Illinois, USA 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Aug 12, 2010 3:07 pm     | 
				     | 
			 
			
				
  | 
			 
			
				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 
			
			 
			 
			
			 
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Aug 12, 2010 8:48 pm     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Aug 13, 2010 4:50 am     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Aug 13, 2010 6:01 am     | 
				     | 
			 
			
				
  | 
			 
			
				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
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Aug 13, 2010 8:00 am     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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; 
 
}  | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  
		 |