[Company Logo Image]        Code Tips 

Home Up Contents Search Articles Caveat Purpose Notice                                                           

Tips on PIC Programming

by

Michele Schieppati

Version 2 dated 04 November 2003

The following notes are a short example of ASSEMBLER code for a PIC that can be used as a reference for code writing in a ‘clean’ and ‘tidy’ manner.

Coloured numbers, which are hyperlinks,  have been placed to identify the different notes in the code.   The notes are brief and are not a total ‘explanation’ .

1

It is a good practice to start the program listing of the code with some information about the version, date, remarks, etc.; You should always describe the device pin-out as well.

 

2

Sometimes it is easier to develop the code on a bigger microprocessor and move the code to a smaller device when it works well. Using a bigger CPU, you have more pins available that can be dedicated to the debug function, such as stopping the microprocessor after some blocks of operations and reading a coded output to verify the CPU state, or simply sending information to a PC using the serial line.

Using a flash microcontroller allows you to quickly re-program the code without removing the microcontroller from the circuit and burning the OTP (chip that has to be 'burned') only at the end when everything is right.

The ifdef __microcontroller name   allows you to select part of the code that must be assembled as function of the microcontroller selected in the MPLAB environment.  In the example below, the final micro is a  12C508A, but the code can be also debugged on a 16F84A.  

Editor's Note: The 12C508A is an older chip (OTP) that is "burned" and can only be erased using ultraviolet light.  The 16F84A is a "flash" chip that is an EEPROM - it is programmed electrically and can be erased and reprogrammed thousands of times electrically.

 

3

RAM_START defines the first RAM location for variables storage. In the example, it is automatically adopted according with the microcontroller selection.

The include “p12C508A.inc”  is used to have the standard original names for microcontroller registers, port, special bit,… without having to re-declare the address, the name of the port and other registers.

#DEFINE will insert in the code during assembling the value (second operand) in place of the first name. In the example, when the 508A is selected the name IOPORT is replaced by GPIO, while when the 84A is selected it is replaced by PORTB.   In the common part of the code referring to IOPORT, it will address operations to the correct port register depending on the selected microcontroller.

 

4

Defining I/O with a mnemonic name associated to the address (name of the IO Port) and bit number allows the use of the bit instruction using the symbolic name.  For example,   btfsc Inp will test bit 3 of the IO port (GPIO or PORTB). 

In the future, if you have to move to a different bit, the code remains the same and you have to change only the declaration line defining Inp to a different bit.

 When you write your code you can concentrate on the function (testing the Inp), rather than on the port name and bit number.

 

5

CBLOCK defines a variable block definition.   The starting address is defined in the cblock directives and all other variables are automatically allocated. 

Using this directive allows you to handle variables with the symbolic name in the watch windows during program debug.

 

6

Constant defines all the constant values that can be entered and evaluated as an expression.

 

7

The same concept used in IO port declaration can be used to assign a symbolic name to bits used as a flag.

 

8

At the start of the code, in the init section, the conditional statement is used again to select two different initialization sections.



1
;*******************************************************************
; Flasher V1.0 03.02.2002
; code developed by Michele Schieppati - all rights reserved
; CPU Deb. 12C508A/16F84A Clock  1 uS 4 Mhz
;
; 12C508A/16F84A Pin Out
;
; Pin 1/14: VDD +5V
; Pin 8/5:  VSS GND
; Pin 15-16 Osc F84A only
;
; Pin 7/6:  GP0/RB0 Output Navigation light
; Pin 6/7:  GP1/RB1 Output Flash 1
; Pin 5/8:  GP2/RB2 Output Flash 2
; Pin 4/9:  GP3/RB3 Input Command
; Pin 3/10: GP4/RB4 Output Flash 3
; Pin 2/11: GP5/RB5 Output Flash 4
;
;*******************************************************************

2
ifdef __12C508A


3
RAM_START equ 0x07
LIST P=12C508A, C=132, N=74, ST=OFF
include "p12C508A.inc"
__CONFIG _IntRC_OSC & _WDT_ON & _CP_ON & _MCLRE_OFF
#DEFINE IOPORT GPIO

else

RAM_START equ 0x20
LIST P=16F84A, C=132, N=74, ST=OFF
include "p16F84A.inc"
__CONFIG _XT_OSC & _WDT_OFF & _CP_OFF
#DEFINE IOPORT PORTB
#DEFINE Page_1 STATUS,RP0                 ; Page 1 bank switch

endif

;*******************************************************************
; Definition I/O
;*******************************************************************
;
4
#DEFINE Inp IOPORT,3


;*******************************************************************
; Variables
;*******************************************************************
;
5
CBLOCK RAM_START
Count_P ; Pulse counter H
Count   ; Generic counter
Cnt_On  ; Command on pulse counter
Cnt_Off ; Command off pulse counter
TabPtr  ; Table pointer
TabCnt  ; Table counter
SlotCnt ; Bit counter
FlDat1  ; Data flash sequence 1
FlDat2  ; Data flash sequence 2
FlDat3  ; Data flash sequence 3
FlDat4  ; Data flash sequence 4
FMode   ; Flash mode [0-7]
PortImg ; Image of output port
Temp    ; Temporary register
Flag    ; Flag register
ENDC

;*******************************************************************
; Constants
;*******************************************************************
;
6

;Editor's Note:  The radio control receiver interprets a centre stick value as 1.5 msecs, left stick 1.0 msecs ;and right stick 2.0 msecs.  In the lines below, any value less than 1.3 mSecs will turn OFF something and ;anything above 1.7 msecs will turn ON something.
CONSTANT Trg_Off=1300/10 ; < 1300             
CONSTANT Trg_On=1700/10  ; > 1700
CONSTANT NChan = 4       ; Number of channel
CONSTANT NPulse = 6      ; Number of valid pulses to trigger   ; Editor: Demanding multiple pulses rejects spurious glitches


;*******************************************************************
; Description flag bit
;*******************************************************************
;
7
#DEFINE TOver  TMR0,7    ; Half Timer overflow flag
#DEFINE OldCmd Flag,0    ; Last command 0:Off 1:On
#DEFINE Direct Flag,1    ; Direct / table data

8
;*******************************************************************
; Start of Code
;*******************************************************************
;
ORG 0
goto SysInit


SysInit

ifdef __12C508A  ; Assemble for 12C508/9
movlw 0x08       ; xxOO IOOO Data direction
TRIS GPIO        ; I/O Port
movlw 0x80       ; No WU, P-up
OPTION           ; Presc to WD
movlw 0x00       ; xx00 0000
movwf GPIO       ; Clear output
else             ; Assemble for 16F84A
bsf Page_1       ; Set page 1
movlw 0x01       ; xxOO OOOI Data direction
movwf TRISA      ; I/O Port
movlw 0x08       ; OOOO IOOO Data direction
movwf TRISB      ; I/O Port
movlw 0x87       ; No WU, No P-up
movwf OPTION_REG ; Presc to WDT
bcf Page_1       ; Clr page 1
movlw 0x00       ; xx00 0100
movwf PORTB      ; Clear output

endif
clrf Flag
clrf TMR0
clrf FMode       ; Flash mode

DataInit

 

 

Home ] Up ]                                                                                                                                               

Send mail to ironsidz@hotmail.com with questions or comments about this web site.
Copyright © 2003 
Last modified: March 18, 2004