Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

A little confused on PIC18 assembly

Status
Not open for further replies.
I'm learning what I can to migrate from the 16F to the 18F.

What really has attracted me to the 18F is the bank switching headaches in the 16F on the bigger versions of that family.

However, I'm still not clear on how banking is handled on the 18F. I've done some datasheet reading, and reading of the tutorials, but I'm still coming up a little short.

Can I use a MOVFF to move any file to any other file, or is it only for movement between two RAM locations. For instance can I do this:

MOVFF ADRESH,RESULTHOLD1 ;RESULTHOLD1 is a user file

What about this:
MOVFF RESULTHOLD1,PORTB ;RESULTHOLD1 is a user file

Can some one break down how I need to use the "a" (access) in a MOVWF or ADDWF command? For instance, is the "a" required here. If so, why? What is it doing? Why 1 and why 0 in place of the "a"?
MOVLW 0xF0
ADDWF USERFILE1,f,a

I guess I'm just plain not understanding the difference in "banked" and "access" commands.

Please enlighten me.
 
Last edited:
I'm sorry I have to comment, I can't help you with your solution, but the entire nightmare of bank switching is exactly the reason I chose Atmel's AVR line. Sorry I can't offer any suggestions hopefully some of the good PIC folks here can explain things.
 
Bankswitching is like going up and down ramps to different levels on a Lightcycle in TRON legacy. It can be fun...it can be dangerous.
I too am considering the move to 18F's WHEN the app requires it. If a 16F will do, I'll deal with the bank switching.

Wannab ...just dload the oshonsoft trial simulators and try out your commands while observing the MCU pin status or GPR watchlist etc.
 
That's why I started with AVR's, there is no bank switching, the 32 by register file is open season by large and far. Some instructions can't be used on the lower portion of the register file but these are typically used for variables, where the other 16 bytes are usable by every instruction that can use a register. You can use only the 16 'good' registers, and not use the limited registers at all (common) or use the limited registers to store things like constant that might need to be changed, you can use them as a page file for manually banking your registers but the general register file system is much more flexible, even the lowest model AVR uses the same architecture.
 
If you look at the PIC datasheet it states that a=1 when you are specifying the RAM bank using the BSR (Bank Select Register).

The MOVFF command specifies that the 2 input parameters are Fs and Fd, File source and File destination, therefore you should be able to move ANY file register around unless it is read only, then you wont be able to move INTO it. So I would think that as long as you are in the correct bank for the file registers then you can move between them.

If you look at the PIC18F97J60 datasheet for example, you will notice that in section 5.3 it explains about the banks.

For that particular chip there are 16 banks of 256 contiguous bytes, and is used to select the register by using the full 12 bits or 8 bits data and a 4 bit bank pointer (BSR), it is used by instructions to rapidly access registers in different locations, it works as an "offset" so the PIC doesn't have to search through unnecessary data.

The ACCESS register is a bit like a single bank select register, but it allows you to access commonly used SFR and GPR (special function and general purpose registers), this is so you can access a particular register in a single cycle.

For example, instead of having to bank select, then issue a command then bank select and then issue another command on 2 common registers, so you may want to read from the RX and write to the TX register for example, and if they are on different banks you will have to do the above, however, if the RX and TX registers are in the access bank then you just set a=1 and it will be able to find the register without bank selecting.

I am no PIC asm expert, I have dabbled with 16f's and 12f's, 18f's I tend to use a high level compiler, such as C18 or CCS for example, but I think the above explanation is how it all works.

Wilksey
 
Hi,

You don't say which 18F chip you are using but I will assume its one with more than one bank of ram.

As you can see from the memory map all the system registers are typically in the top half of bank15 - which the pic can address without any banking.

You then have n number of ram banks according to the chips size.
To select a ram bank you use this code -
movlb D'1' ; define bank1

So you now have use of 256 bytes in bank 1 plus the 128 byes of access ram in the lower half of bank0.

If you change the ram bank to say bank2 you still have all the access ram available.

As usual the datasheet makes it sound so complicated -you just use the code instructions as normal , you do not need to specify access or bank on each instruction as intimated in the datasheet.

Paging is also a thing of the past

Have used movff but never tried it to address bytes in different banks 1 -5 etc,
it works fine between the access ram and the currently selected ram bank.
 
Thanks for the info guys. I think I'm starting to come around. The datasheet seems to indicate that if the register is between 060h and FFFh, that it can be addressed via the access bank. So it would just be a MOVFF 0x060,0xFFF then (if I used the address and not the name of the register), right? Does mplab assume "a" is 0 if I don't always specify it? I'm still not understanding the need for the BSR at all if the access register can do it all.
 
From the datasheet:
If a is 0’, the Access Bank is selected.
If a is 1’, the BSR is used to select the
GPR bank (default).
So the default is a=1

The most common registers are stored in the access bank, not all of them, there may still be some that you need that is not in the access bank.

You may find however that everything you need is in the access bank and you can ignore the BSR.

Wilksey
 
Okay, I've got ya. It's not a matter of "sometimes you want to do it this way, and sometimes you want to do it that way," it's a matter of "most times you can do it this easy way, but sometimes you must do it the hard way."

It also kinda sucks that default in mplab is a = 1 when not specified, because I'd imagine the access bank is used most often.

Perhaps it's just because I'm so accustom to the 16F, but it seems like the memory organization is better explained in those datasheets.
 
True, but I should imagine that when porting from 16F to 18F assembler it would be "easier" to assume you are bank selecting rather than relying on the access register, which doesn't exist in the 16F's, I would think that is why Microchip did it that way, otherwise you may run into issues and have to learn about the access bank from the start, throwing you in at the "deep end" so to speak.

Wilksey
 
Okay, I took some sample code from PIC18F and I moved some stuff around to test my understanding.

Here is what I have gathered to be the case on these 18F pics.

1)
Any file can be moved to another file with a "MOVFF" command, regardless of what banks they are in, and regardless of what bank you are currently in.

2)
If the RAM file is in the access bank, it can be operated on with math, compare tests, bit tests, sets, clears, etc, regardless of the bank you are currently in.

3)
If the RAM file is not in the access bank, the appropriate bank must be selected with a "MOVLB X" or "BANKSEL XXXXX" command to do any math, compare tests, bit tests, sets, clears, etc, on it.

Does this sound correct?
 
Last edited:
Hi,

Single Step this bit of code in Mpalb Sim with a watch window for the variables and see it work.



Code:
;******************************************************************************
;
;	Processor Type
;	==============

	LIST P=18F4520,r=hex,n=80,x=off,st=off

	#include <P18F4520.INC>	



;******************************************************************************
; 
;	Configuration bits 
;	==================
  
; specified here are changes to the .inc file defaults

 CONFIG OSC=INTIO67, PWRT=ON, BOREN=OFF, WDT=OFF, MCLRE=OFF, LPT1OSC=OFF, PBADEN=OFF
 CONFIG LVP=OFF, XINST=OFF, DEBUG=OFF




;******************************************************************************
;
;	Variables
;	=========


	cblock  0x000


	test01
	test02
	

	endc


	cblock  0x100


	test11
	test12
	

	endc


	cblock  0x200


	test21
	test22
	

	endc




	movlb	D'1'			; select Bank1 and Access Ram


	movlw 0x0A

	movwf	test01

	movwf	test11

	movwf	test21


	movff	test01,test02

	movff	test01,test12
	
	movff	test01,test21

	movff	test11,test22

	end
 
Last edited:
Thanks for that Wp. That helped to further clear it up for me. Basically, if I wanted to write a value to a file not in the access bank and not in the currently selected bank (per the BSR), and I didn't want to do any bank switching, I could just MOVLW "xx" then MOVWF into a file in either the access bank or the currently selected bank. Then I could use a MOVFF to copy it over to the desired file. That's all only if I didn't want to bank switch, and is probably more trouble than it's worth.
 
Hi,

Think you will have seen the only mov that did not work when bsr 1 was specified was the 'movwf test21'

Had never used movff outside the existing specifed bank, but as you can see from the instruction set description fs and fd can be anywhere in a 4k ram area.
Also just seen how it says W can be the fs or fd so thats even handier

You can also use the FSR registers to point to other areas of ram if you are dealing with large volumes of data.

Location of source ‘fs’ can be anywhere
in the 4096-byte data space (000h to
FFFh) and location of destination ‘fd’
can also be anywhere from 000h to
FFFh.
Either source or destination can be W
(a useful special situation).
MOVFF is particularly useful for
transferring a data memory location to a
peripheral register (such as the transmit
buffer or an I/O port).
 
Okay, I took some sample code from PIC18F and I moved some stuff around to test my understanding.

Here is what I have gathered to be the case on these 18F pics.

1)
Any file can be moved to another file with a "MOVFF" command, regardless of what banks they are in, and regardless of what bank you are currently in.

2)
If the RAM file is in the access bank, it can be operated on with math, compare tests, bit tests, sets, clears, etc, regardless of the bank you are currently in.

3)
If the RAM file is not in the access bank, the appropriate bank must be selected with a "MOVLB X" or "BANKSEL XXXXX" command to do any math, compare tests, bit tests, sets, clears, etc, on it.

Does this sound correct?

That is correct.

When I was programming an 18F, I left the bank select at 1. That meant that I could access the half of bank 0 as it is in the access bank, and the whole of bank 1 without doing any bank selection changes. The SFRs are all in the access bank. That gives 384 registers.

That is a lot of registers to read or write directly. As each register needs one or more lines of code to write to it, and at least another to read from it, that is likely to be in excess of 1000 lines of code that only access the registers, so 384 is probably enough for that.

It is likely that registers beyond 384 are only going to be needed for blocks of data or text, so those are going to be handled indirectly, and for indirect addressing, the banks don't apply.

The three indirect registers can point to the whole of memory without worrying about banking, and they can be loaded in a single instruction. That means that it's just as quick to load one of those and use indirect addressing as it is to change the bank and use direct addressing.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top