I have a project for the PIC18F25K50 of mixed C and Assembly; most of what I want to do I can easily manage (and must for efficiency) in Assembly, but some parts where I care more about ease of development use C. I actually have a couple of these, and I keep encountering the same issue: I can't use ASM to jump to a label. Every single function to jump - CALL
, GOTO
, BNC
, and so on - will fail if given a label, setting PC to some random-but-consistent value where there are no instructions, causing the program to hang. Using an address works fine: BC $+4
skips the next line.
An example of what does not work is this:
#asm
_waitUS:
GLOBAL _waitUS
waitLoop:
//12 cycles = 1 microsecond:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ WREG, F, ACCESS
GOTO waitLoop
RETURN
#endasm
void main() {
//DEBUG:
waitUS(6);
}
Now, this may not work overall, and I am begging you to focus on the issue of jumping - this is still in prototyping because I can't even get the function called. The program does compile without issue.
As soon as waitUS(6)
is called, the PC jumps from - in my case - 0x7C96
to 0x52
. Swapping the C call out for MOVLW 6; CALL _waitUS
MOVLW 6; CALL _waitUS
breaks in exactly the same way.
If I strictly use C for calling/jumping (as I had to in the previous project), it works fine, and figures out where it's going.
I've been searching for an answer to this for a few weeks now, and still haven't seen anyone else with this problem, even though every project I make (including plaintext in notepad, compiling via command line) has the exact same issue. What the heck is up with this?
Edit: Having discovered the program memory view, I was able to get a better idea of what it's doing. The compiler does know where the functions are, and it is trying to jump to the right location. Apparently, CALL just doesn't know where it's going.
Example: Address 0x7C92
contains CALL 0x2044, 0
. That is precisely what it ought to, that is where the desired function starts. However, upon running this instruction, PC
is altered to 0x205E , missing half of the function.
Attempting to be clever, I decided to tack on several NOPs to the start of the function after its label, lining the real code up with 0x205E
. Unfortunately, it seems any change alters where its unpredictable jumping will land, and it then landed at 0x2086
instead.
Incidentally, when it starts running at random places, it will often run across a GOTO
- and it will jump to the specified location as intended. This only works within the same function, as trying to use GOTO
instead of CALL
ends up in the same incorrect location, despite what the compiled result demands.
the .pdf document at:
<http://ww1.microchip.com/downloads/en/DeviceDoc/33014K.pdf>
has many examples on how to code the PIC18.
Here is one such example:
RST CODE 0x0 ;The code section named RST
;is placed at program memory
;location 0x0. The next two
;instructions are placed in
;code section RST.
pagesel start ;Jumps to the location labelled
goto start ;’start’.
PGM CODE ;This is the beginning of the
;code section named PGM. It is
;a relocatable code section
;since no absolute address is
;given along with directive CODE.
start
movlw D'10'
movwf delay_value
xorlw 0x80
call delay
goto start
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.