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

16F: Proper Assembly Code Format Part 2

    Blog entry posted in 'Uncategorised', November 29, 2011.

    So far our code should look like this -

    Code:

    ;*************************************************************************************************
    ;** **
    ;** Header Information **
    ;** **
    ;*************************************************************************************************

    list p=16F628A, r=dec, w=-302
    include <P16F628A.INC>
    __config _LVP_OFF & _BOREN_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT

    ;Processor Type: 16F628A
    ;Default Radix: Decimal
    ;Error Level: Suppress Error 302
    ;Reference header file P16F628A.INC for SFR address and config word labels
    ;Code Protection Off
    ;Data Code Protection Off
    ;Low Voltage Programming Off
    ;Brown Out Reset Off
    ;RA5 is MCLRE
    ;Power Up Timer On
    ;Watchdog Timer Off
    ;Internal Oscillator - I/O on RA6/OSC2 and RA7/OSC1

    ;Fosc = 16MHz

    ;*************************************************************************************************
    ;** **
    ;** Variable Declarations **
    ;** **
    ;*************************************************************************************************

    cblock 0x70
    W_TEMP ;interrupt context save for W
    STATUS_TEMP ;interrupt context save for STATUS
    PCLATH_TEMP ;interrupt context save for PCLATH
    COUNT1 ;delay counter 1
    COUNT2 ;delay counter 2
    COUNT3 ;delay counter 3
    endc


    ;*************************************************************************************************
    ;** **
    ;** I/O Pin Definitions **
    ;** **
    ;*************************************************************************************************

    #define SDO PORTA,0 ;SPI bit bang Serial Data Out
    #define SCK PORTA,1 ;SPI bit bang Serial Clock
    #define LAT PORTA,2 ;latch strobe for 74HC595
    #define COMMON PORTB,0 ;common side of button switches
    #define CHANNEL PORTB,4 ;Vss drive for channel select button
    #define SOLO PORTB,5 ;Vss drive for solo boost select button
    #define FX PORTB,6 ;Vss drive for fx loop select button
    #define LEARN PORTB,7 ;Vss drive for learn mode button


    All we have done so far is set up the assembler parameters and define our labels. Now we get to start off the main code.

    The org Directive

    The next assembler directive to know is the "org" directive. The org directive stands for "origin". This directive allows us to tell the assembler which specific program ROM address to place a specific line of code. The syntax for using this directive is to type "org" followed by the program ROM address where you want to place a specific line of code. The line of code that will be placed at this address will follow the line with the org directive. Such an example can be seen here -

    Code:

    ;*************************************************************************************************
    ;** **
    ;** Start of Main Program **
    ;** **
    ;*************************************************************************************************

    org 0x000 ;reset vector
    goto START ;jump to start of main code


    This code will place the instruction/operand "goto START" at program ROM address 0x000, which is the reset vector. Upon the PIC encountering a power up/reset condition, the program counter will be vectored to (i.e. "directed to) program ROM address 0x000, in which it will fetch the instruction "goto START", which the CPU will then execute. This will jump the program counter to the line of code that is labeled "START".

    What this does is allow us to place the start of the main program anywhere in the code we want to. If there is code that exists between the "goto START" instruction and the start of the main code (which is labeled START), the program counter will simply jump over that code to get to the start of the main program. This gives us space to place the interrupt handler (which will go at program ROM address 0x004, which is the interrupt vector) as well as any look up tables we may have in our code.

    Since the interrupt vector address is ROM address 0x004, we can do the same thing with the interrupt handler code -

    Code:

    ;*************************************************************************************************
    ;** **
    ;** Start of Main Program **
    ;** **
    ;*************************************************************************************************

    org 0x000 ;reset vector
    goto START ;jump to start of main code

    org 0x004 ;interrupt vector
    goto ISR ;jump to interrupt service routine


    So we now have the instruction "goto START" residing at program ROM address 0x000 and the instruction "goto ISR" residing at program ROM address 0x004. As long as we label the start of the main code with the label START and we label the start of the interrupt handler code with the label ISR, the program counter will jump to the start of the main code upon being vectored to ROM address 0x000 upon power up/reset, and will also jump to the start of the interrupt handler code upon being vectored to ROM address 0x004 once an interrupt condition has been set. This gives us flexibility to place the start of our main code as well as our interrupt handler code anywhere in the code we want to.

    Now before we place the start of our main code, we want to place our look up tables if we have any. The reason for placing look up tables before the start of the main code is because this will place the tables in the lower 256 addresses of program ROM, which is the first of 8 program ROM 256 byte page boundaries. This will keep us from having to mess with the page boundary bits in PCLATH prior to calling the table. The only exception to this would be if our table was longer than 256 lines of code long, in which we would have to mess with the page boundary bits in PCLATH to access the lower lines of the table prior to calling the table. In short, placing the look up tables in the lower 256 program ROM location simply makes look up tables easier to deal with.

    Shown below is our code with a common anode LED display look up table placed after the org statements -

    Code:

    ;*************************************************************************************************
    ;** **
    ;** Start of Main Program **
    ;** **
    ;*************************************************************************************************

    org 0x000 ;reset vector
    goto START ;jump to start of main code

    org 0x004 ;interrupt vector
    goto ISR ;jump to interrupt service routine

    ;*************************************************************************************************
    ;** **
    ;** Start of Main Program **
    ;** **
    ;*************************************************************************************************

    org 0x000 ;reset vector
    goto START ;jump to start of main code

    org 0x004 ;interrupt vector
    goto ISR ;jump to interrupt service routine

    TABLE addwf PCL,F ;jump to table line currently stored in W
    retlw b'10000000' ;0
    retlw b'11011001' ;1
    retlw b'01000100' ;2
    retlw b'01010000' ;3
    retlw b'00011001' ;4
    retlw b'00010010' ;5
    retlw b'00000010' ;6
    retlw b'11011000' ;7
    retlw b'00000000' ;8
    retlw b'00010000' ;9
    retlw b'11011111' ;blank

    Comments
 

EE World Online Articles

Loading

 
Top