Saturday 8 February 2014

Implementing Time Delay in PIC Assembly program

Delay in Assembly Language Program 

Delay is indispensable in any functional piece of code developed for a given embedded system. Delay in assembly program is not just easy as in high level programs such as embedded C. Delay in assembly is normally done by executing lines of instructions in a loop to realize a given delay.


Implementing the delay - PIC16F84A

The basic principle behind implementing delay in Assembly (ASM) language is based on the fact that each instruction takes a given number of machine cycle/s to complete execution. The machine cycle/s for each of the PIC16F84A instructions can be seen on page 36 of the PIC16F84A datasheet. The machine cycle is determined by the machine (PIC) oscillator frequency. 1 machine cycle for PIC16F84A with 4MHz oscillator is equal to Period T = 1/ (4M/4) = 1us.

With the knowledge that each instructions takes a given time to complete execution, the programmer can then write a number of instructions and loop accordingly to implement different delays. To minimize the number of instructions used in a delay, the “decfsz” and "goto" instructions are normally used. The “decfsz” instruction decrements a number in a file register, while the "goto" instruction is used to achieve looping until the file being decremented becomes zero. Once the  file register value becomes zero, the "goto" instruction is skipped and the loop ends.


Nevertheless, this may appear quite complicated for some, hence the easy way out is to use a Delay Code Generator online tool. The tool just requires the user to input the desired delay (say 0.5ms) in the "Delay" input box and the PIC oscillator frequency (e.g. 4MHz) in the "Clock frequency" input box as shown in the figure below. Since the delay is for PIC, make sure that the "PIC" is selected and not "SX" as can be seen from the figure. Once done, click "Generate code!" to see the delay code.




The delay code for the inputs of 0.5ms and 4MHz is shown:

; Delay = 0.0005 seconds
; Clock frequency = 4 MHz

; Actual delay = 0.0005 seconds = 500 cycles
; Error = 0 %

        cblock
        d1
        endc

                       ;499 cycles
        movlw   0xA6
        movwf   d1
Delay_0
        decfsz  d1, f
        goto    Delay_0

                       ;1 cycle
        nop

The main delay code is the ones without the ASM comment syntax ";". For the delay implemented in the SVM Inverter Code blog post, you may ignore the "cblock" and "endc"code and replace “d1” with 0Fh. The “d1” is the temporary register used to store variables used for the delay. The “d1” can also be replaced with any unused general purpose register file from 0Ch to 4Fh for PIC16F84A - datasheet (pg 6).

Further tips

You may like to take a look at an LED flash tutorial where the "cblock" code is used to implement a delay that blinks an LED. 

To gain more insight on assembly language programming, refer to Assembly Language tutorial blog post.

No comments:

Post a Comment