• 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 Assemble Code Format Part 3

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

    So far we now have this as our code -

    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

    ;*************************************************************************************************
    ;** **
    ;** 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


    Now we can place the start of our main code. For every PIC there will be a "setup routine", which we will call the "initialization routine". This is the routine that sets up the on chip hardware for our use. Things like port I/O assigning as inputs/outputs, USART setup, timer setup, etc etc. For our example, we are again using the PIC 16F628A and we will configure it for all ports as outputs using none of the on chip peripherals -

    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

    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

    ;*************************************************************************************************
    ;** **
    ;** Initialization Routine **
    ;** **
    ;*************************************************************************************************

    START movlw 7 ;disable comparator
    movwf CMCON ;RA0-RA4 function as digital I/O
    clrf PORTA ;init PORTA all lines low
    clrf PORTB ;init PORTB all lines low
    banksel TRISA ;bank 1
    clrf TRISA ;RA0-RA7 outputs, RA5 has MCLRE function
    clrf TRISB ;RB0-RB7 outputs
    banksel 0 ;bank 0


    Notice that between the "goto START" instruction at ROM address 0x000 and the actual line that is labeled START we have the jump instruction "goto ISR" for the interrupt handler as well as a look up table. However, when the PIC powers up or resets, the first instruction it sees is "goto START". This will simply vector the program counter to the line that is labeled START while skipping everything in between the "goto START" instruction and the line with the label START.

    Our init routine is really simple. First we write the value of 7 to register CMCON. This disables the on chip comparator on the 16F628A (which is in "Comparators Reset" mode by default), which enables pins RA0/AN0 - RA4/CMP2 to function as digital I/O pins. This is a step that is specific to the 16F627A/16F628A/16F648A PIC that must be carried out in order to use RA0-RA4 as digital I/O pins.

    The next thing we do is write an initial value to PORTA and PORTB prior to configuring them as outputs. On power up/reset, the bits in these registers come up in random states because they are set to input mode by default. Writing a value to them prior to configuring them as outputs enables the pins to come up in a known state upon setting them up as outputs. The "clrf" instruction clears the PORTA and PORTB registers to all 0's.

    The next thing we do is select RAM bank 1 so that we can access the port TRIS registers, which contain the control bits that set each pin for either input or output mode. Any bits which you write a 1 to will set its corresponding pin up as an input, while writing a 0 to the TRIS bits will set the bit's corresponding bit up as an output. The "clrf" instruction clears the registers to all 0's, which sets up all of the port pins for that port up as outputs. The only exception to this is on pin RA5. The hardware limits this pin to be set up as input only, so its corresponding TRIS bit will always be read as 1.

    Comments
 

EE World Online Articles

Loading

 
Top