• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

No interrupt on PIC10F causing me trouble

Status
Not open for further replies.

Broz

New Member
Ok, here's a strange situation, or maybe not so strange for some more experienced than I. I have two identical devices running identical programs. The devices send an IR signal, and then look for an IR input from the other device. I thought about the possibility of the program timings meshing up and not detecting the other device, but I thought at the speed these things are running, it would not be a problem. Well, I think it is a problem now. There are cycles of about 10 seconds or so when neither will accept an input from the other. I'm thinking the programs are meshed up and they're both looking for inputs at the same time. Is that possible?

If so, how can I fix this? It would be easy if the 10F had interrupts, but it doesn't and I'm dedicated to using the 10F. Is there some crafty way to ensure the program timings are not meshed up and looking for inputs at the same time?

I hope I'm making sense, it makes sense in my mind.
 

Broz

New Member
Ok, but this was the first real program I wrote myself, and it works for the most part and I never cleaned it up. I'm sure I could make things more efficient and have better comments and names for my blocks and such. So go easy on me.

Code:
list      p=10F206            ; list directive to define processor
	#include <p10F206.inc>        ; processor specific variable definitions

	__CONFIG   _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file. 
; See respective data sheet for additional information on configuration word.



;**********************************************************************
	ORG     0x1FF             ; processor reset vector

; Internal RC calibration value is placed at location 0x1FF by Microchip
; as a movlw k, where the k is a literal value.

	ORG     0x000             ; coding begins here
	movwf   OSCCAL            ; update register with factory cal value
	bcf		CMCON0, CMPON
	movlw	b'00000000'
	OPTION

    cblock 0x08
Delay1                  
Delay2                  
Count
Count1
Shooter
SF1
SF2
     endc

Start:
     movlw	   b'1000'
	 TRIS	   GPIO
Main:
	 movlw	   d'5'
	 movwf	   Count1
Repeat:
	 movlw	   d'5'                ; Loading the count block
	 movwf	   Count			   ; For how many times the LED will blink
	 decfsz	   Count1
	 goto      MainLoop1
	 goto 	   Shoot
MainLoop1:
	 decfsz	   Count,f             ; Countdown starts for LED blinking
	 goto 	   On1                 ; Goto instruction for start of blinking
	 goto	   Repeat2             ; Goto for the second LED
On1:
	 movlw	   b'0001'
     movwf     GPIO                ; turn on LED C0
	 movlw	   .010                ; setting the timing
	 movwf	   Delay2              ; for delay loop
OnDelayLoop1:
     decfsz    Delay1,f            ; Wasting time.  
     goto      OnDelayLoop1        ; 
     decfsz    Delay2,f            ; 
     goto      OnDelayLoop1        ; 
                                   ; 
	 movlw	   b'0000'
      
     movwf     GPIO                ; Turn off LED C0
	 movlw	   .150                ; Load timing for LED off loop
	 movwf	   Delay2
OffDelayLoop1:
     decfsz    Delay1,f            ; same delay as above
     goto      OffDelayLoop1
     decfsz    Delay2,f
     goto      OffDelayLoop1
     goto      MainLoop1            ; Do it again...
Repeat2:
	 movlw	   d'5'
	 movwf	   Count
	 
MainLoop2:                          ;This is the same instruction set as above except for it's the C1 LED
	 decfsz	   Count,f
	 goto 	   On2
	 goto	   Repeat
On2:
	 movlw	   b'0010'
	 movwf	   GPIO
	 movlw	   .010
	 movwf	   Delay2
OnDelayLoop2:
	 decfsz	   Delay1,f
	 goto	   OnDelayLoop2
	 decfsz	   Delay2,f
	 goto	   OnDelayLoop2
	 movlw	   b'0000'
	 movwf	   GPIO
	 movlw	   .150
	 movwf	   Delay2
OffDelayLoop2:
	 decfsz	   Delay1,f
	 goto	   OffDelayLoop2
	 decfsz	   Delay2,f
	 goto	   OffDelayLoop2
	 goto	   MainLoop2
Shoot:
	 movlw	   d'10'                ;Setting how many times IR LED will send signal
	 movwf	   Shooter
Burst:
	 decfsz	   Shooter, f
	 goto	   Burster
	 goto 	   Receive
Burster:
	 movlw	   b'0100'              ;Turning on IR LED
	 movwf	   GPIO
	 nop
	 nop
	 nop
	 nop
	 movlw	   b'0000'              ;Turning IR LED off
	 movwf	   GPIO
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 nop
	 goto	   Burst
Receive:
	 movlw	 d'2'              ;added these comments long after program was written and in use
	 movwf	 SF1               ;I think I was playing around with giving the IR receiver time
	 movlw	 d'2'			   ;to recover before I checked for a signal
	 movwf	 SF2			   ;so it wouldn't receive it's own signal	
Stop:                          ;not sure it's necessary, but it works, so I left it
	 decfsz	 SF1, f
	 goto	 Stop
	 decfsz	 SF2, f
	 goto	 Stop
	 goto	 Check
Check:
	 btfsc	 GPIO, 3           ;checking for input
	 goto	 Shoot			   ;If no input, fire another burst on the IR LED
	 goto	 Main              ;If there is, go blink the red LED's. 

End
 

eblc1388

Active Member
There are cycles of about 10 seconds or so when neither will accept an input from the other. I'm thinking the programs are meshed up and they're both looking for inputs at the same time. Is that possible?
I see that you have used OSCCAL to ensure both PICs are running with nearly the same frequency.

If the two chip has about the same clock, then they will be nearly running in sync but not quite as there are bound to be some slight frequency difference.

What you have observed is the "beat" nature of two nearly same frequencies. This also means that both PIC is running the same line of code in that beat period and thus both is looking for input. It then won't response until the beat period has ended, but only to be in sync again in the next beat period.

If so, how can I fix this?
1. Deliberately keeps the clock frequency of these two PICs further apart so that the beat frequency is higher, making the beat period shorter. You can use OSCCAL to do that.

2. Use slightly different constants in the time waste routine value for each PIC.
 

Broz

New Member
That's exactly what I was thinking was happening, and that's a good way to think of it, beats. The problem is, the programs really need to be the same. Can you think of any other crafty way to fix this without having differences in the programs? Maybe if I added more bit tests, perhaps to replace some of the nop's? I'm trying to think if that would help at all, but I don't think so. Is there some way to simulate an interrupt on a chip that doesn't have an interrupt capability?

Given the programs need to be identical, I can't think of a way to fix this off hand.
 

eblc1388

Active Member
If that is the case, then don't "waste" PIC cycles counting fingers in a loop.

Use all your "delay" cycles for checking IR input. Set a flag if there is a signal.

It still consumes cycles when you do the input checking and can acts as a form of delay.

So 99% of time your PIC is checking for input except when it is outputting an IR signal. If you are clever, you can even use the wait time in between IR output pulses to check for IR input.

In radio transmission, a Morse code message sometimes takes many seconds to send. Therefore the radio transceiver reverts into receiving mode between the gaps of the transmitting "dot" and "dash" so the radio operator can be made aware of what's happening in the airwave during whole length of the message.
 

Pommie

Well-Known Member
Most Helpful Member
You can do a very limited interrupt type function on the 10F chips by setting timer0 to use the external clock input. If you set timer0 to zero then any pulse on GP2 will make it non zero which can be polled for.

I don't really understand what you are trying to do, but if it is simple IR communication between two 10Fs then it should be easily doable. If you explain what you are trying to do then I may be able to help more.

Mike.
 
Last edited:

atferrari

Well-Known Member
To avoid having both checking each other in synch, make the input checking of both, following a somewhat random sequence (albeit still inside the same timeframe) using different random generators for each one.
 

Broz

New Member
To avoid having both checking each other in synch, make the input checking of both, following a somewhat random sequence (albeit still inside the same timeframe) using different random generators for each one.
I just now have some time to work on this, I'm trying eblc's method of adding checks within the IR output pulses. But I'm curious, you talked about a "random generator" to keep them out of sync? What would this look like in code?
 

Mr RB

Well-Known Member
Since you have limited resources on the 10F, the easiest way is to grab the TMR0 value (assuming you have TMR0 as a free running timer) and test bit0, then if bit0=0 delay 1mS or if bit0=1 delay 3mS.

The actual delay times you choose are not critical, nor is the fact that TMR0 bit0 is not perfectly random. It just shakes things up enough so that the 2 PICs will never be synced for more than a few mS before one of them changes timing.
 

Broz

New Member
Well, I can say at this point it is definitely a problem with the timings syncing up. At this point I have one system breadboarded and another on a PCB. I changed the breadboarded one since it has the easy to work with 8 pin dip version and tested against the one on the PCB and it works beautifully, no perceptible problems of syncing up. Of course, they're running slightly different programs.

In my lack of organization in my lab, I misplaced the rest of my 8 pin versions so I can't build another breadboarded unit, and I really don't feel like popping the SOT23 version off my PCB (I didn't give myself the ability to program on the board). So, now I'm debating to keep looking for my 8 pin versions, or pop off the SOT23. I really need to get organized.

But I can say for sure, it's a synchronization problem I was experiencing. Thanks for the help, and when I get two loaded up with the same code I'll let you know the results.

Edit: Just remembered I have a SOT23 soldered to a breadboard adapter. I think I'm still in business here. :)
 

Broz

New Member
Hey, I would like to thank everyone who replied to this thread for help. I went with Mr. RB's solution in the end, though eblc's probably would have worked as well. It was just easier to check bit0 of TMR0 and set a delay based on that. It did the trick and the problem is gone.

Thanks again for everyone's help.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top