possibly new for most of you, lately I’ve started practising with some pic processors. not with a specific type of a pic microcontroller, but mostly with the 14-bit core pic16 family.
here’s the deal, i’m not going to dive deep into pic16 or any microcontroller architecture, but give this brief statement on what i’m trying to do:
using the pic assembly language, if you try to code a loop, you can use a file register(that is, one byte of pic’s ram) as the counter variable. but using one file register, since the processor is an 8-bit processor, you can count up to 256 at most. so, how do you code a loop that iterates up to 3956, for example?
what you have to do is simple. using two file registers in order to iterate up to a number that is bigger than 256. but since the processor is an 8-bit processor, you have got to do the decrement operation diligently, since you have two seperate registers. this is the way i implemented it:
LIST p=16F628A ;the processor i used for this example is PIC16F628A
#include <p16F628A.inc>
;========================
;RESET VECTOR
ORG 0
nop ; 0×00
nop ; 0×01
nop ; 0×02
goto Start ; 0×03
;========================
;INTERRUPT VECTOR
ORG 4
Interrupt
retfie ; 0×04
CBLOCK 0×20
CL ;the low portion of count register
CH ;the high portion of count register
VAL_L ;this is the counter which is used for debugging (low portion)
VAL_H ;this is the counter which is used for debugging (high portion)
ENDC
Start
clrf VAL_L
clrf VAL_H
movlw 0x0F
movwf CH
movlw 0x7D
movwf CL ;so that CH:CL is now 0x0F7D
LOOP_BEGIN
incfsz VAL_L ;loop body
goto $ + 2 ;consists of these 3 commands
incf VAL_H ;which simply increments the counter used for debugging
decfsz CL ;first decrease the low portion. if it’s zero, skip the goto below and try to decrease the high portion
goto LOOP_BEGIN ;low portion is not zero after decreasement, so go to loop body
movf CH, F ;this effectles command is for its flag effect (effect of effectless?)
btfsc STATUS, Z ;see if you can borrow from the high portion
goto LOOP_END ;if you can’t, end the loop
decf CH, F ;if you can, borrow then.
goto LOOP_BEGIN ;and after you borrow, go to loop body
LOOP_END ;this is the end of the loop code. (below is out of the loop)
nop ;my favourite command
nop
END
after i run this code, i’ve seen that VAL_H:VAL_L is 0x0F7D . seems correct. after this, i’ve tried these:
C_H:C_L before the loop VAL_H:VAL_L after the loop
0×0000 0×0100 ;as expected*
0×0001 0×0001
0×0100 0×0200; oops, seems we got a bug here
0xABCD 0xABCD
0xFFFF 0xFFFF
except for the bug on the 0×0100 input, loop seems to be working correctly. and the asterisk item’s explanation is:
while using single 8-bit registers, if the initial register value is 0×00, the loop has to iterate 256 (0xFF + 1) times. I think therefore the asterisk signed line of results is as expected.
As soon as i fix the bug on the 0×0100 input, I’ll inform you here.
See you later for now.
edit: the 0×0100 input is interpreted as 0×01 : (0xFF+1), therefore 0×0200. do i have to find a solution or is this what’s expected? i’ll think on this issue and write here as soon as i decide.