TITLE: Some PIC Utility Macros for the LAB-X3
AUTHOR: Chuck McManis
LAST UPDATE: 25-Dec-2001

Description

These are some macros I wrote to make writing code for the LAB-X3 simpler. They include macros to do the following;

Basically syntactic sugar to lessen the pain of writing everything in assembly language!

The Source Code

; vim: set syntax=pic :
; UTIL.INC      - Utility Routines
; This Version    28-Dec-01
        NOLIST
; Written by      Chuck Manis (http://www.mcmanis.com/chuck)
; Copyright (c) 2001 Charles Manis, All Rights Reserved
;
; Change Log:
;       28-DEC-01       Added Digit conversion routines
;       22-DEC-01       Initially created with the WAIT
;                       macro for computing delays.
;
; NOTICE: THIS CODE COMES WITHOUT WARRANTY OF ANY KIND EITHER
;         EXPRESSED OR IMPLIED. USE THIS CODE AT YOUR OWN RISK!
;         I WILL NOT BE HELD RESPONSIBLE FOR ANY DAMAGES, DIRECT 
;         OR CONSEQUENTIAL THAT YOU MAY EXPERIENCE BY USING IT.
;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
util_inc equ 0
;
; Digit Conversion Macro
;
; This macro converts one "digit" of a 5 digit number
; into ASCII It is used in the routine CVT_NUM that
; converts the number in NUM_HIGH and NUM_LOW, into 5
; ASCII digits stored in DIGIT_0, DIGIT_1, ... DIGIT_4.
; DIGIT_0 is the MSD, DIGIT_4 is the LSD.
;
; It works by initializing the DIGIT location to '0' - 1 (ASCII
; zero minus 1) and then begins subtracting the value you pass and
; counts how many times it can be subtracted before underflow (very
; simple divide operation). Then adds back the last value and returns.
; It leaves NUM_LOW and NUM_HIGH with a value that is the modulus
; of NUM % VALUE (the remainder) and DIGIT_n has the divider.
; 
; Cycle computation :
; 3 preamble
; 10 per digit increment
; 6 postamble
; 19 + 10 * actual digit
;
_ONE_DIGIT        MACRO NUMBER, DIGITS, DIG_NUM, VALUE
        MOVLW   '0' - 1
        MOVWF   DIGITS + #v( DIG_NUM )

        LOCAL LOOP
LOOP:
        INCF    DIGITS + #v( DIG_NUM ),F
        MOVLW   low (VALUE)             ; Low byte of value
        SUBWF   (NUMBER),F              ; Count = count - value
        MOVLW   high (VALUE)
        SKPC
        MOVLW   (high (VALUE)) + 1
        SUBWF   (NUMBER)+1,F
        SKPNC
        GOTO    LOOP                ; Not done yet so loop
        MOVLW   low (VALUE)         ; Else add back VALUE
        ADDWF   (NUMBER),F          ; To the count
        MOVLW   high (VALUE)
        SKPNC
        MOVLW   (high (VALUE)) + 1
        ADDWF   (NUMBER)+1,F
        ENDM

;
; Call's DO_DIGIT 5 times to convert the number in 'NUMBER'
; into a string at 'DIGITS'
;
BIN2ASCII       MACRO   NUMBER, DIGITS
        nolist
        _ONE_DIGIT NUMBER, DIGITS, 0, D'10000'
        _ONE_DIGIT NUMBER, DIGITS, 1, D'1000'
        _ONE_DIGIT NUMBER, DIGITS, 2, D'100'
        _ONE_DIGIT NUMBER, DIGITS, 3, D'10'
        MOVF    (NUMBER),W      ; Get last digit
        ADDLW   '0'             ; Add ascii 0 to it
        MOVWF   ((DIGITS)+4)    ; Store it in last digit
        CLRF    (NUMBER)
        list
        ENDM

;
; Wait Macro
; 
; This macro comes from the "Advanced" PIC programming seminar
; and it will build a delay of 'n' machine cycles which are 
; 1/4 the clock frequency. So for a 4Mhz crystal a delay of
; 1 cycle is 4 ticks, or 1 instruction cycle which is 1uS. 
;
WAIT    MACRO   CYCLES
        nolist
X SET (CYCLES) % 4
        IF (X == 1) || (X == 3)
            NOP
        ENDIF

        IF (X == 2) || (X == 3)
            GOTO $+1
        ENDIF

X SET (CYCLES) / 4
        IF (X)
            IF (X == 256)
X SET 0
            ENDIF

            MOVLW   X
            ADDLW   -1
            SKPZ
            GOTO    $-2
        ENDIF
        list
        ENDM

; msg: MOVF     INDEX,W
;      ADDWF    PCL     
;      DT       <pos>,"The Message", 0
;
DM      MACRO   msg, index
        MOVF    INDEX,W
        ADDWF   PCL
        DT      msg,0
        ENDM

;
; Send a message to the LCD, the format of the message is
; <position>, text message, nul byte. 
; No interpretation of special numbers is done at all.
;
SENDMSG MACRO   msg, index
        LOCAL   LOOP,MSG_EXIT
        CLRW
        MOVWF   index
        CALL    msg
        CALL    LCD_CMD
LOOP:
        INCF    index,F
        CALL    msg
        ANDLW   H'FF'
        SKPNZ
        GOTO    MSG_EXIT
        CALL    LCD_CHAR
        GOTO    LOOP
MSG_EXIT:
        ENDM


        LIST

License

Creative Commons License

This work is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License. You are free to play around with it and modify it but you are not licensed to use it for commercial purposes. Click the link above for more details on your rights under this license.