4 A Basic Example For Mid-range Devices

The following example of a complete assembly program is written for a PIC16F18446 device, although much of this example is also applicable for other devices. It performs the mundane task of repeatedly reading the value on PORTC and recording the highest value that has been read. This example follows on from information presented in section A Basic Example For PIC18 Devices and aspects of the code are discussed in the sections that follow.

A Basic PIC16 Example

/*
 * Find the highest PORTC value read, storing this into the object max
 */

PROCESSOR 16F18446

#include <xc.inc>

CONFIG "FEXTOSC = OFF"      // External Oscillator mode->Oscillator not enabled
CONFIG "RSTOSC = HFINT1"    // Power-up default value for COSC->HFINTOSC (1MHz)
CONFIG "CLKOUTEN = OFF"     // CLKOUT disabled; i/o or osc function on OSC2
CONFIG "CSWEN = ON"         // Clock Switch Enable->Writing to NOSC and NDIV allowed
CONFIG "FCMEN = ON"         // Fail-Safe Clock Monitor Enable->FSCM timer enabled

CONFIG "MCLRE = ON"         // Master Clear->MCLR pin is Master Clear function
CONFIG "PWRTS = OFF"        // Power-up Timer Enable bit->PWRT disabled
CONFIG "LPBOREN = OFF"      // Low-Power BOR enable bit->ULPBOR disabled
CONFIG "BOREN = ON"         // Brown-out reset enable->Enabled, SBOREN bit ignored
CONFIG "BORV = LO"          // Brown-out Reset Voltage Selection->VBOR set to 2.45V
CONFIG "ZCDDIS = OFF"       // Zero-cross detect disable->disabled at POR
CONFIG "PPS1WAY = ON"       // PPSLOCK cleared/set only once
CONFIG "STVREN = ON"        // Stack Over/underflow causes reset

CONFIG "WDTCPS = WDTCPS_31" // WDT Period Select->Ratio 1:65536; software control
CONFIG "WDTE = OFF"         // WDT operating mode->WDT Disabled, SWDTEN is ignored
CONFIG "WDTCWS = WDTCWS_7"  // WDT Window Select->always open; software control
CONFIG "WDTCCS = SC"        // WDT input clock selector->Software Control

CONFIG "BBSIZE = BB512"     // Boot Block Size Selection->512 words boot block size
CONFIG "BBEN = OFF"         // Boot Block Enable bit->Boot Block disabled
CONFIG "SAFEN = OFF"        // SAF Enable bit->SAF disabled
CONFIG "WRTAPP = OFF"       // Application Block not write protected
CONFIG "WRTB = OFF"         // Boot Block not write protected
CONFIG "WRTC = OFF"         // Configuration Register not write protected
CONFIG "WRTD = OFF"         // Data EEPROM NOT write protected
CONFIG "WRTSAF = OFF"       // Storage Area Flash not write protected
CONFIG "LVP = ON"           // LV Programming Enabled, MCLR/Vpp pin is MCLR

CONFIG "CP = OFF"           // UserNVM Program memory code protection->Disabled

skipnc  MACRO
    btfsc      CARRY
ENDM

;objects in bank 0 memory
PSECT udata_bank0
max:
    DS         1                   ;reserve 1 byte for max
tmp:
    DS         1                   ;reserve 1 byte for tmp

PSECT resetVec,class=CODE,delta=2
resetVec:
    PAGESEL    main                ;jump to the main routine
    goto       main

/* find the highest PORTA value read, storing this into
   the object max */
PSECT code
main:
    ;set up the oscillator
    movlw      0x62
    movlb      17
    movwf      OSCCON1
    movlw      2
    movwf      OSCFRQ
    PAGESEL    loop                ;ensure subsequent jumps are correct
    BANKSEL    max                 ;starting point
    clrf       BANKMASK(max)
    BANKSEL    ANSELC
    clrf       BANKMASK(ANSELC)    ;select digital input for port C
loop:
    BANKSEL    PORTC               ;read and store port value
    movf       BANKMASK(PORTC),w
    BANKSEL    tmp
    movwf      BANKMASK(tmp)
    subwf      max^(tmp&0ff80h),w  ;is this value larger than max?
    skipnc
    goto       loop                ;no - read again
    movf       BANKMASK(tmp),w     ;yes - record this new high value
    movwf      BANKMASK(max)
    goto       loop                ;read again

    END        resetVec