News:

;) This forum is the property of Proton software developers

Main Menu

PIC 18F assembler

Started by m.kaviani, Mar 19, 2021, 01:19 PM

Previous topic - Next topic

m.kaviani

Did anyone have an assembler tutorial for the PIC 18F series?

TimB

IMHO

I would only learn assembler so you can marvel at the brillent code Positron produces. There are very few instructions to learn and they are listed in the appropriate device PDF/Manual. After that you will be learning how to do the basics like comparisons and jumps.

I do think it's handy to understand how assembler works. But there is no reason to actually write it. Gone are the days I would strain over doing a comparison on a byte to a word. When I can just write
If bMyByte > wMyWord then


Endif

Try this....
Write some code in Positron then hit F2 and look through the asm produced.
As Les said recently Break your code up into discrete sections
 
Do not write
If (bmByte x wmyword / 2) + Portb >> 4 = 100

Write

bTempB = Portb >> 4
wmyword = bmByte x wmyword
wmyword = wmyword / 2
wmyword = wmyword + bTempB
If wmyword = 100 then

That may not be a perfect example but you get the idea.



top204

#2
It's always good to hear that someone wants to get lower down into the microcontroller's architecture, and understand how it works.

For that reason, I have tried to make the assembler code created by the compiler as tight as possible and as clear as possible to read and learn Asm coding from it, and the next update to the compiler produces even clearer Asm code.

For example. The simple, and rather pointless, BASIC code:
    Device = 18F25K20
    Declare Xtal = 16
   
    Dim WordIn As Word
    Dim WordOut As Word
 
'-----------------------------------------------------------------------------
Proc ResetProc()
    WordIn = 0              ' Limit Wordin and WordOut
    WordOut = 1000
EndProc
   
'-----------------------------------------------------------------------------
Main:
    WordIn = 0                      ' Reset Wordin   
    Do                              ' Create a loop
        WordIn = WordIn + 1         ' Increment WordIn
        WordOut = WordIn + 10       ' Load WordOut with Wordin + 10 
        If WordOut > 1000 Then      ' Has WordOut gone over bounds?
            ResetProc()             ' Yes. So limit Wordin and WordOut
        EndIf
    Loop                            ' Close the loop

Will produce the asm code:

 LIST  P = 18F25K20, F = INHX32, W = 2, X = ON, R = DEC, MM = ON, N = 0, C = 255, T = ON
; MICROCONTROLLER'S SFRS
SSPMSK equ 0X0F77
SLRCON equ 0X0F78
CM2CON1 equ 0X0F79
CM2CON0 equ 0X0F7A
CM1CON0 equ 0X0F7B
;
; <<<<< More SFR names fill here, but removed to make the asm text more clear in the example
;
PC equ 0X0FF9
PCL equ 0X0FF9
PCLATH equ 0X0FFA
PCLATU equ 0X0FFB
STKPTR equ 0X0FFC
TOS equ 0X0FFD
TOSL equ 0X0FFD
TOSLH equ 0X0FFE
TOSH equ 0X0FFE
TOSU equ 0X0FFF
; I2C PINS USED BY HBUSIN AND HBUSOUT
_I2C_SCL_port=TRISC
_I2C_SCL_pin=3
_I2C_SDA_port=TRISC
_I2C_SDA_pin=4
; SFR BITS USED INTERNALLY BY THE COMPILER
C=0
DC=1
Z=2
OV=3
N=4
PD=5
To=6
PP_TXIF=4
;
; <<<<< More bit names fill here, but removed to make the asm text more clear in the example
;
PP_T2CKPS1=1
PP_TMR2ON=2
PP_TMR1ON=0
PP_RBPU=7
; MEMORY MAP OF THE DEVICE
  __MAXRAM  0X0FFF
  __BADRAM  0X0600-0X0F5F
  __BADRAM  0X0F83
  __BADRAM  0X0F85-0X0F88
  __BADRAM  0X0F8C-0X0F91
  __BADRAM  0X0F95-0X0F9A
  __BADRAM  0X0F9C
  __BADRAM  0X0FA3-0X0FA5
  __BADRAM  0X0FAA
  __BADRAM  0X0FD4
; CONFIG FUSE NAME VALUES
config1h equ 0X300001
config2l equ 0X300002
config2h equ 0X300003
config3h equ 0X300005
config4l equ 0X300006
config5l equ 0X300008
config5h equ 0X300009
config6l equ 0X30000A
config6h equ 0X30000B
config7l equ 0X30000C
config7h equ 0X30000D
FOSC_LP_1 equ 0XF0
FOSC_XT_1 equ 0XF1
FOSC_HS_1 equ 0XF2
FOSC_RC_1 equ 0XF3
FOSC_EC_1 equ 0XF4
;
; <<<<< More fuse names fill here, but removed to make the asm text more clear in the example
;
EBTR3_OFF_7 equ 0xFF
EBTRB_ON_7 equ 0XBF
EBTRB_OFF_7 equ 0xFF
; COMPILER'S INTERNAL CONSTANTS AND ALIASES
#define __18F25K20 1
#define xtal 16
#define _core 16
#define _MaxRAM 1536
#define _Ram_End 0X0600
#define _MaxMem 0X8000
#define _ADC 11
#define _ADC_res 10
#define _eeprom 256
; STANDARD VARIABLES
WordIn equ 0x00
WordInH equ 0X01
WordOut equ 0X02
WordOutH equ 0X03
; CONSTANTS
#define __xtal 16
;---------------------------------------------
; START OF THE COMPILER'S LIBRARY ROUTINES
_compiler__start_
    org 0x00
    nop
    nop
    goto _compiler_main_start_
    org 0X08
_compiler_main_start_
    movlb 0
;---------------------------------------------
; START OF THE USER'S PROGRAM CODE
F1_SOF equ $ ; TEST_18F25K20_MK2.BAS
    clrf ANSEL,0
    clrf ANSELH,0
    clrf CM1CON0,0
    clrf CM2CON0,0
    clrf SLRCON,0
Main
F1_000016 equ $ ; in [TEST_18F25K20_MK2.BAS] WordIn = 0
    clrf WordInH,0
    clrf WordIn,0
F1_000017 equ $ ; in [TEST_18F25K20_MK2.BAS] Do
_lbl__2
F1_000018 equ $ ; in [TEST_18F25K20_MK2.BAS] WordIn = WordIn + 1
    infsnz WordIn,F,0
    incf WordInH,F,0
F1_000019 equ $ ; in [TEST_18F25K20_MK2.BAS] WordOut = WordIn + 10
    movlw 10
    addwf WordIn,W,0
    movwf WordOut,0
    movlw 0
    addwfc WordInH,W,0
    movwf WordOutH,0
F1_000020 equ $ ; in [TEST_18F25K20_MK2.BAS] if WordOut > 1000 Then
    movlw 233
    subwf WordOut,W,0
    movlw 3
    subwfb WordOutH,W,0
    bnc _lbl__6
F1_000021 equ $ ; in [TEST_18F25K20_MK2.BAS] ResetProc()
    rcall ResetProc
F1_000022 equ $ ; in [TEST_18F25K20_MK2.BAS] endif
_lbl__6
_lbl__4
F1_000023 equ $ ; in [TEST_18F25K20_MK2.BAS] Loop
    bra _lbl__2
_lbl__3
F1_000002 equ $ ; in [TEST_18F25K20_MK2.BAS] Stop
_pblb__7
    bra _pblb__7
;---------------------------------------------
F1_000009 equ $ ; in [TEST_18F25K20_MK2.BAS] Proc ResetProc()
ResetProc
F1_000010 equ $ ; in [TEST_18F25K20_MK2.BAS] WordIn = 0
    clrf WordInH,0
    clrf WordIn,0
F1_000011 equ $ ; in [TEST_18F25K20_MK2.BAS] WordOut = 1000
    movlw 3
    movwf WordOutH,0
    movlw 232
    movwf WordOut,0
F1_000012 equ $ ; in [TEST_18F25K20_MK2.BAS] EndProc
    return 0 ; EndProc
;---------------------------------------------
F1_EOF equ $ ; TEST_18F25K20_MK2.BAS
__eof
;---------------------------------------------
; CONFIG FUSES
config DEBUG=off
config XINST=off
config STVREN=off
config WDTEN=off
config FCMEN=off
config FOSC=HS
config IESO=off
config WDTPS=128
config BOREN=off
config BORV=18
config MCLRE=on
config HFOFST=off
config LPT1OSC=off
config PBADEN=off
config CCP2MX=PORTC
config LVP=off
config CP0=off
config CP1=off
config CPB=off
config CPD=off
config WRT0=off
config WRT1=off
config WRTB=off
config WRTC=off
config WRTD=off
config EBTR0=off
config EBTR1=off
config EBTRB=off
    end

I've removed a lot of the device specific SFRs, bit names and fuses etc, so the above listing is not too long for this thread.

Notice that each section of the asm code is named for the user to identify with, and the assembler code is clearly setout with the BASIC code that produced it. Unlike other compilers, the Proton8 (soon to be Positron8) and the Proton24 (soon to be Positron16) compilers produce very clean assembler and it is not scattered all over the place in it. However, procedures are placed after the main code, but each procedure is clearly named and has markers to indicate where they are, so the user can identify them.

None of these markers are required by the compiler, and I have added them purely for the user to understand the asm code better.

There are many books on the internet that are out or print and are free to download as PDFs. And some of them are for 18F assembler code.

okmn

#3
Quote from: m.kaviani on Mar 19, 2021, 01:19 PMDid anyone have an assembler tutorial for the PIC 18F series?

,
actually me too i am looking orginal documents of Microchip,
i remember they had perfect guide wizard to learn assembler for pic 18 when they are presenting their masters organization
if someone has these "master documents" can share!!

m.kaviani

dear Top204
there is a routine that a user starts to create a code in proton programming.
1- define the device
2- define peripheral device
3- define required ram value. bit byte word etc.
4- define symbols
5- interrupt routine
6- main program
7- subroutines
...
When I read the pic datasheet found the CPU assembly commands. but the main question is where is the starting point?
how start coding at the first line compile and get the hex code?

m.kaviani

consider that I want to make a blinking LED on a specific port.
I know to select ram banks based on PIC datasheet and define a delay loop. i did test a simple code like that inside proton.