I'm working with some arrays and my program doesn't work as espected; not sure if this is the problem, but in the generated asm i see something looking like an error:
I have an array declared this way:
Dim registro(64)
And there is a subroutine reading the array and working with other variables:
Sub calc_output
lectura = 0
For actual = 0 to 63
if registro(actual) > cont_Task7 then lectura += 1
Next
End Sub
That's all fine, arrays are addressed independently of normal variables.
Arrays use indirect addressing, in which the memory address is provided by the IRP bit of STATUS as well as the value in FSR. Normal variables use direct addressing, where the low 7 bits of the address come from the instruction and the high bits come from the RP1 and RP0 bits of STATUS. banksel sets RP1 and RP0, bankisel sets IRP.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You are right... i found the error in another place, but thank you very very much for the explanations, it has been very usefull for me.
I'm trying to control 64 pwm leds at a time and need every cicle to fit alltogether in 100 us if possible.
The real program is little more complex than the sub i posted, then i could save some instructions writing it directly in asm.
from this (repeated 64 times):
movlw low REGISTRO
addwf ACTUAL,W
movwf FSR
bankisel REGISTRO
movf INDF,W
subwf CONT_TASK7,W
btfss STATUS, C
bsf LECTURA,0
incf ACTUAL,F
Then i don't need a bankisel every time and i don't need the variable "actual"... i can just increment FSR and save 4 instructions (there is a previous bankisel):
...
incf FSR
movf INDF,W
subwf CONT_TASK7,W
btfss STATUS, C
bsf LECTURA,0
...
i could save: 4 x 64 intrucction cicles = 256 ic = 51 us (at 20 Mhz) ... that is from 135 us to 84 us... now i can fit it in 100 us !!! ... :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi again.
I'm working with some arrays and my program doesn't work as espected; not sure if this is the problem, but in the generated asm i see something looking like an error:
I have an array declared this way:
Dim registro(64)
And there is a subroutine reading the array and working with other variables:
Sub calc_output
lectura = 0
For actual = 0 to 63
if registro(actual) > cont_Task7 then lectura += 1
Next
End Sub
The generated asm look like this:
;********************************************************************************
;Set aside memory locations for variables... GOOD PLACE FOR SYS VARIABLES!!!!
DELAYTEMP EQU 112
SysSTATUS EQU 127
SysW EQU 126
SysWaitTempUS EQU 117
SysWaitTempUS_H EQU 118
REGISTRO EQU 429 ;.................HERE IS THE ARRAY: Bank3
........
........
ACTUAL EQU 32 ;...........................HERE OTHER VARIABLES: Bank0
........
CONT_TASK7 EQU 41
........
LECTURA EQU 45
........
........
;********************************************************************************
CALC_OUTPUT
clrf LECTURA
movlw 255
movwf ACTUAL
SysForLoop2
incf ACTUAL,F
movlw low REGISTRO
addwf ACTUAL,W
movwf FSR
bankisel REGISTRO ;................. select Bank3
movf INDF,W
subwf CONT_TASK7,W ;..........But this variable is in Bank0
btfss STATUS, C
incf LECTURA,F
movlw 63
subwf ACTUAL,W
btfss STATUS, C
goto SysForLoop2
return
;********************************************************************************
I think bank3 is selected to read the array, but afther that there isn't any banksel to come back to Bank0....
is there a missing "banksel CONT_TASK7" ????
Thaks in advance.
That's all fine, arrays are addressed independently of normal variables.
Arrays use indirect addressing, in which the memory address is provided by the IRP bit of STATUS as well as the value in FSR. Normal variables use direct addressing, where the low 7 bits of the address come from the instruction and the high bits come from the RP1 and RP0 bits of STATUS. banksel sets RP1 and RP0, bankisel sets IRP.
You are right... i found the error in another place, but thank you very very much for the explanations, it has been very usefull for me.
I'm trying to control 64 pwm leds at a time and need every cicle to fit alltogether in 100 us if possible.
The real program is little more complex than the sub i posted, then i could save some instructions writing it directly in asm.
from this (repeated 64 times):
movlw low REGISTRO
addwf ACTUAL,W
movwf FSR
bankisel REGISTRO
movf INDF,W
subwf CONT_TASK7,W
btfss STATUS, C
bsf LECTURA,0
incf ACTUAL,F
Then i don't need a bankisel every time and i don't need the variable "actual"... i can just increment FSR and save 4 instructions (there is a previous bankisel):
...
incf FSR
movf INDF,W
subwf CONT_TASK7,W
btfss STATUS, C
bsf LECTURA,0
...
i could save: 4 x 64 intrucction cicles = 256 ic = 51 us (at 20 Mhz) ... that is from 135 us to 84 us... now i can fit it in 100 us !!! ... :)