Continue to Site

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.

  • 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.

Execution time of code

Status
Not open for further replies.
Please forgive the rather long post. I am working on building an infrared remote controlled light switch/dimmer that will utilize zero crossing detection thru an interrupt. (60 Hz so 2 crossings per cycle) I am using Jason's (Atomsoft) SourceBoost C code for SIRC to receive the IR code and just want someone to check my math. I will be using a 12F629 at 4 MHz so figuring the max time for BTFSS's, DECFSZ's, BTFSC's of 2 instructions, plus 2 for all CALL's, GOTO's, and RETURN's I calculate the following code will take approx. 3137 uS to get 1 button press and set a pin high. Since the code in sections label 8 through label 13 will execute 7 times and the code in sections label 14 through label 19 will execute 5 times. I should have plenty of time between zero crossings to do this since 120 hz equates to 8333 uS if my math serves me right. But it is late and I might have miscounted so I am asking for opions on my thinking.

Code:
GetSIRC_00000
; { GetSIRC ; function begin
label6
	CLRF GetSIRC_00000_1_ir_cmd
	MOVLW 0x00
	CLRF GetSIRC_00000_1_ir_add
label7
	BTFSC gbl_gpio,5
	GOTO	label7
	CLRF gbl_lTime
label8
	BTFSC gbl_gpio,5
	GOTO	label9
	INCF gbl_lTime, F
	MOVLW 0x13
	MOVWF delay_10us_00000_arg_del
	CALL delay_10us_00000
	GOTO	label8
label9
	MOVF gbl_lTime, W
	SUBLW 0x0A
	BTFSC STATUS,C
	GOTO	label6
	MOVLW 0x0E
	SUBWF gbl_lTime, W
	BTFSC STATUS,C
	GOTO	label6
	CLRF gbl_lTime
	CLRF GetSIRC_00000_1_x
label10
	MOVLW 0x07
	SUBWF GetSIRC_00000_1_x, W
	BTFSC STATUS,C
	GOTO	label14
	BCF STATUS,C
	RRF GetSIRC_00000_1_ir_cmd, F
label11
	BTFSC gbl_gpio,5
	GOTO	label11
	CLRF gbl_lTime
label12
	BTFSC gbl_gpio,5
	GOTO	label13
	INCF gbl_lTime, F
	MOVLW 0x13
	MOVWF delay_10us_00000_arg_del
	CALL delay_10us_00000
	GOTO	label12
label13
	MOVLW 0x06
	SUBWF gbl_lTime, W
	BTFSC STATUS,C
	BSF GetSIRC_00000_1_ir_cmd,6
	INCF GetSIRC_00000_1_x, F
	GOTO	label10
label14
	CLRF GetSIRC_00000_1_x
label15
	MOVLW 0x05
	SUBWF GetSIRC_00000_1_x, W
	BTFSC STATUS,C
	GOTO	label19
	BCF STATUS,C
	RRF GetSIRC_00000_1_ir_add, F
label16
	BTFSC gbl_gpio,5
	GOTO	label16
	CLRF gbl_lTime
label17
	BTFSC gbl_gpio,5
	GOTO	label18
	INCF gbl_lTime, F
	MOVLW 0x13
	MOVWF delay_10us_00000_arg_del
	CALL delay_10us_00000
	GOTO	label17
label18
	MOVLW 0x06
	SUBWF gbl_lTime, W
	BTFSC STATUS,C
	BSF GetSIRC_00000_1_ir_add,4
	INCF GetSIRC_00000_1_x, F
	GOTO	label15
label19
	MOVF GetSIRC_00000_arg_address, W
	MOVWF FSR
	MOVF GetSIRC_00000_1_ir_add, W
	MOVWF INDF
	MOVF GetSIRC_00000_arg_command, W
	MOVWF FSR
	MOVF GetSIRC_00000_1_ir_cmd, W
	MOVWF INDF
	RETURN
; } GetSIRC function end


delay_10us_00000
; { delay_10us ; function begin
label1
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ delay_10us_00000_arg_del, F
	GOTO	label1
	RETURN
; } delay_10us function end
 
You could run it in MPLAB SIM and use the StopWatch to double check your calculations.
 
The timings of the btfsc btfss and decfsz instructions is easier to understand if you realise that they cause a nop to be executed if they skip. So the timing is the same whether they skip or not.

eg

Code:
    btfss     0x20, 2        ;1st  instruction
    addlw    0x03            ;2nd instruction

That will take 2 instructions cycles to execute, whether or not the addlw was actually run.

If the second instruction is a goto, that will take 2 cycles, after the 1 cycle of the btfss or whatever.

It boils down to the fact that it is one cycle per line unless there is a branch.
 
Last edited:
You could run it in MPLAB SIM and use the StopWatch to double check your calculations.


I tried this but since I have very little experience with MPSIM I wasn't able to figure out how to build a stimulus file so it just sat there when it reached the first statement checking to see if a pin was high or low. I need to figure out how to do this but it will have to wait for now.
 
It is quite simple to use. First you select the SIM as your debugger. Then you go here:
stim-png.32085



Then you simply select the port bit you wish to toggle and how it shall toggle:

stimulus-png.32087


And click the "fire" button to stim the pin. You don't have to save it as a file if you don't want to. Simply minimize the stim window and continue debugging.
 

Attachments

  • stim.PNG
    stim.PNG
    15.1 KB · Views: 423
  • Stimulus.PNG
    Stimulus.PNG
    19.2 KB · Views: 414
...
I calculate the following code will take approx. 3137 uS to get 1 button press and set a pin high.
...

Wow! 3137 uS is over 3 thousand PIC instructions just to get a button press and and set a pin hi??? :eek:
 
Wow! 3137 uS is over 3 thousand PIC instructions just to get a button press and and set a pin hi??? :eek:

It is receiving a button press from a TV remote (Sony). Decoding it to verify it is a valid SIRC signal and determing if the correct button was pressed to turn on the output. SIRC is a 12 bit code and each bit has to be measured to determine if it is a 0 ( 600 uS high followed by 600uS low ) or a 1 ( 1200 uS high followed by 600 uS low ). The 12 bit code is preceded by a start burst 2.4 mS high + 600 uS low.
 
kchristie, thanks for showing me that. I will try it out later and see how it works out.
 
It is receiving a button press from a TV remote (Sony). Decoding it to verify it is a valid SIRC signal and determing if the correct button was pressed to turn on the output. SIRC is a 12 bit code and each bit has to be measured to determine if it is a 0 ( 600 uS high followed by 600uS low ) or a 1 ( 1200 uS high followed by 600 uS low ). The 12 bit code is preceded by a start burst 2.4 mS high + 600 uS low.

I see. :)

So why ask for the PIC code execution time if the main determining factor is the SIRC transmission time?

I would just sense the zero crossing in interrupt with a very short int that just resets TMR1 (you only have to save off STATUS not W), and give processing priority to the receival of the SIRC data. You can software poll for your phase switching event between and during SIRC bits.
 
Here is another trick that you can use in situations where you have a btfss loop, but you also need symetrical timing (even on the exit cycle of the loop)

Code:
loop 
btfss PORTA,0 ;1 clock cycle
goto loop ;2 clock cycles

So when it keeps looping it uses up 3 clock cycles...
But when PORTA,0 goes high and it exits the loop:

Code:
loop 
btfss PORTA,0 ;2 clock cycles
goto loop ;
                  <---code continues here

So when it exits the loop it only uses up 2 clock cycles. If you want it to take the same amount of clock everytime (even on exit), you can simply do this:

Code:
loop 
btfss PORTA,0 ;2 clock cycles
goto loop ;
nop          ;1 clock cycle

Now it uses 3 clock cycles every cycle, it's symetrical, and it makes calculating the time that it uses up easier (especially if it is part of a function call that gets called many times).
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top