|
|
View previous topic :: View next topic |
Author |
Message |
Nepersky
Joined: 10 May 2011 Posts: 15
|
Accessing Non-Access Bank Special Function Registers |
Posted: Fri May 13, 2011 11:48 am |
|
|
Hello!
I ran into a problem when trying to set one of the bits of the DSCONH register on a PIC 18F24J11. The code written below (or more precisely, the DSEN=1; line), was compiled by CCS as BSF 0x4d, 0x7, BANKED.
Code: |
#include "18F24J11.h"
#ZERO_RAM //clear all RAM
#FUSES INTRC_IO
#FUSES NOXINST
//----------DSCONH: DEEP SLEEP CONTROL REGISTER HIGH-----------------
#byte DSCONH= getenv("SFR:DSCONH")
#BIT RTCWDIS = DSCONH.0
#BIT DSULPEN = DSCONH.1
#BIT DSEN = DSCONH.7
#use delay (internal=8MHz)
void main()
{
DSEN=1; //PROBLEMATIC LINE
while(1){}
} |
But this does not set the wanted bit, when examining the register with a debugger. Since the DSCONH is a Non-Access Bank Special Function Register, the code should, in my opinion, look like this (0xF4D is the DSCONH address):
Code: |
movlb 0xf
movlw 0x80
movwf 0x4d,BANKED |
I tried inserting the above into #ASM ....#ENDASM, but an "Expecting an opcode mnemonic" error is output by CCS for the movwf 0x4d,BANKED line. It is the same with movwf 0x4d,0
Any idea how to access Non-Access Bank Special Function Registers?
Compiler version:
PCH 4.121
IDE,PCB and PCM 4.112
Thank you in advance for all your help.
Cheers!
p.s.: The bit in question is the deep sleep enable bit. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 13, 2011 12:43 pm |
|
|
I installed vs. 4.121 and ran your code in MPSIM and looked at DSCONH
in a Watch window and it works. It gets set to 0x80. You can see in the
code below that it sets the bank to "F", which is correct. I don't see a
problem.
Quote: | .................... void main()
.................... {
0004: CLRF FF8
0006: BCF FD0.7
0008: MOVLW BE
000A: MOVWF 00
000C: MOVLW 0F
000E: MOVWF 01
0010: MOVLW 02
0012: MOVWF FE9
0014: MOVLW 00
0016: MOVWF FEA
0018: CLRF FEE
001A: CLRWDT
001C: DECFSZ 00,F
001E: BRA 0018
0020: DECFSZ 01,F
0022: BRA 0018
0024: CLRF FEA
0026: CLRF FE9
0028: MOVLW 70
002A: MOVWF FD3
002C: MOVF FD3,W
002E: MOVLW FF
0030: MOVLB F // Set the bank
0032: MOVWF x48
0034: BCF FC2.6
0036: BCF FC2.7
0038: MOVF x49,W
003A: ANDLW E0
003C: IORLW 1F
003E: MOVWF x49
0040: MOVLW 07
0042: MOVWF FB4
.................... DSEN=1; //PROBLEMATIC LINE
0044: BSF x4D.7
.................... while(1){}
0046: BRA 0046
.................... }
............... |
|
|
|
Nepersky
Joined: 10 May 2011 Posts: 15
|
|
Posted: Fri May 13, 2011 1:25 pm |
|
|
It works in the simulator, you are right. But on the PIC it does not.
In the mean time I managed to convince the compiler to do what I wanted before:
Code: | movlb 0xf
movlw 0x80
movwf 0x4d,BANKED |
but this still does not set the proper bit when debugging on a PIC 18F24J11.
The problem is becoming really annoying.
I tried to set a bit in one of the registers located a couple of bytes from the DSCONH. I defined:
Code: | //----------TCLKCON-----------------
#byte TCLKCON= getenv("SFR:TCLKCON")
#BIT TCLKCON0 = TCLKCON.0
#BIT TCLKCON1 = TCLKCON.1 |
and then set the TCLKCON1=1; This worked, so the debugger is most likely not to blame.
Why this is interesting is, that both registers (TCLKCON and DSCONH) are Non-Access Bank Special Function Registers located only 5 addresses apart, the first being at F52 and the second at F4D. One would conclude, that perhaps the DSCONG register is write protected or does not exist on PIC18F24J11. But the data sheet states that only PIC18LF devices are without this register. I am also pretty sure it is not write protected as it needs to be accessed when entering deep sleep mode.
If anyone has any further ideas I will be very grateful.
Cheers! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 13, 2011 2:22 pm |
|
|
The paragraph below from the 18F24J11 data sheet explains why you
can't see the DSEN bit = 1 in the debugger or at run-time with a printf:
Quote: |
3.6 Deep Sleep Mode
In order to minimize the possibility of inadvertently entering
Deep Sleep, the DSEN bit is cleared in hardware
two instruction cycles after having been set. |
Using that information, I can make a test program that will work.
If I run the modified program below on my 18F24J11 board, I get
this result in the TeraTerm window:
Code: |
#include <18F24J11.h>
#FUSES HS,NOWDT
#use delay(clock=20M)
#use rs232(baud=9600, UART1, ERRORS)
//----------DSCONH: DEEP SLEEP CONTROL REGISTER HIGH-----------------
#byte DSCONH= getenv("SFR:DSCONH")
#BIT RTCWDIS = DSCONH.0
#BIT DSULPEN = DSCONH.1
#BIT DSEN = DSCONH.7
//============================
void main()
{
int8 temp;
DSEN=1; //PROBLEMATIC LINE
temp = DSCONH;
printf("DSCONH = %X \n\r", temp);
while(1){}
} |
|
|
|
Nepersky
Joined: 10 May 2011 Posts: 15
|
|
Posted: Fri May 13, 2011 3:51 pm |
|
|
You are absolutely right!
I did notice the sentence in the data sheet you pointed out though. It was the reason I started writing part of the code in assembler, to make sure nothing comes in between the DSEN clearing and the sleep instruction. But It never occurred to me, that "two instruction cycles" refers to an absolute time (meaning 2*(4/Fosc)). I was sure, that when the debugger stops the program execution and therefore all the instructions from executing, the two instruction cycles needed to clear the DSEN bit will not happen until the debugger releases the PIC.
I guess this misunderstanding is due to the language barrier, since I do not come from an English speaking country.
Thank you again for your help. It is much appreciated.
Cheers! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|