Author Topic: Nothing more than a memory  (Read 4946 times)

0 Members and 1 Guest are viewing this topic.

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Nothing more than a memory
« on: July 03, 2018, 01:02:43 pm »
I'm trying to get to grips with the memory in my PIC16F1827.
The datasheet says there are three types: programme, data, EEPROM.
Is have been taught to begin progs like this:

#include p16f1827.
var_1      equ 0x20
var_2      equ 0x21

               org 0x0000
               goto start
               org 0x0004
               goto intrpt

               org 0x0005
               main prog ...

So, this is programme memory and the datasheet goes on to specify that this is then split into "Page 0" and "Page 1".
What is the significance of detailing this break at 07FFh / 0800h - is there any?

It then goes on to data memory: core registers, SFRs, General purpose RAM (GPRAM) and common RAM.
When it says that the core registers, SFRs and common RAM occupy "every data memory bank" does this mean that whatever is written in one register in one bank is "copied" to the same register in all banks?
Am I right though that GPRAM is not the same and that each bank can hold different values in the equivalent positions?
Is the "equ" in my example above somehow writing directly to the first and second positions in the GPRAM? I've never been told what this is but just to do it!
The datasheet text says there is 80 bytes of GPRAM and 16 bytes of common RAM. However, in the memory map it shows 96 bytes in bank 0. Is this because this is where you write into common RAM that is then accessible in all banks? Can you write to this area when another bank is selected or do you have to be in bank 0 to write?

EEPROM is said to be from 0h to 0ffh.
You can ignore the fact that data memory and programme memory also being at 0h because the context of the commands being use will prevent any conflicts - is this correct?

That's a lot, I'm sorry but if you could help please … thank you.

You can release yourself but the only way to go is down!
RJD
 

Offline Berni

  • Super Contributor
  • ***
  • Posts: 4946
  • Country: si
Re: Nothing more than a memory
« Reply #1 on: July 03, 2018, 01:11:54 pm »
My first advice is just use a high level language, the assembler on the PIC16F family is horrible.

But if you still want to do it the thing is that instructions on the 16F can't address much memory. As a result most chips have pages that have to be switched between by flipping some special bits in a SFR. Trough some adressing forms you can get to memory regardless of the page setting. Other addressing modes or chunks of RAM are only addressable when the corresponding page is selected.

The pages contain both RAM and SFRs, but they are mixed without any consistant structure and there are no long runs of contiguous memory. Some SFRs appear on multiple pages, some don't.

Reading from flash memory needs a special instruction and reading from eeprom needs a different special instruction.

All in all its horrible.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: Nothing more than a memory
« Reply #2 on: July 03, 2018, 01:42:36 pm »
Is have been taught to begin progs like this:

#include p16f1827.
var_1      equ 0x20
var_2      equ 0x21

               org 0x0000
               goto start
               org 0x0004
               goto intrpt

               org 0x0005
               main prog ...

So, this is programme memory and the datasheet goes on to specify that this is then split into "Page 0" and "Page 1".
What is the significance of detailing this break at 07FFh / 0800h - is there any?

Yes. The place where GOTO goes depends on the PCLATH register, so your GOTO in the interrupt may go to either page, depending on what PCLATH was when the interrupt has happened. So, you need to set PCLATH before goto.

Code: [Select]
               org 0x0000
               goto start
               org 0x0004
               pagesel intrpt
               goto intrpt

               org 0x0006
               main prog ...

Or better yet (eliminating unnecessary jump and decreasing interrupt latency):

Code: [Select]
               org 0x0000
               goto start
               org 0x0004
               ; your ISR goes here

               retfie

start
               main prog ...


It then goes on to data memory: core registers, SFRs, General purpose RAM (GPRAM) and common RAM.
When it says that the core registers, SFRs and common RAM occupy "every data memory bank" does this mean that whatever is written in one register in one bank is "copied" to the same register in all banks?
Am I right though that GPRAM is not the same and that each bank can hold different values in the equivalent positions?

The bank is selected by BSR register. The address within the bank comes from the command.

If the address in the command is 0x00 to 0x0f, BSR is ignored and command accesses coomon FSRs (such as WREG, PCLLATH etc.).

If the address is 0x01 to 0x1f, the command accesses different SFRs depending on BSR.

If the address is 0x20 to 0x6f, the command accesses regular RAM. BSR selects the bank. Each bank has 80 bytes of RAM (if populated).

If the address is 0x70 to 0x7f, BSR is ignored and command accesses "common RAM" - 16 bytes of it.

Is the "equ" in my example above somehow writing directly to the first and second positions in the GPRAM?

No. The "equ" merely says that the "var_1" symbol should be replaced by 0x20 thereafter.

 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #3 on: July 04, 2018, 09:07:47 am »
Thanks Berni but I really want to get to grips with assembly and the PICs inner workings.

Thanks NorthGuy. With the equ and var_1 situation, where is the data for this variable actually stored?
You can release yourself but the only way to go is down!
RJD
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: gb
Re: Nothing more than a memory
« Reply #4 on: July 04, 2018, 10:41:42 am »
All in all its horrible.

Very horrible, an AVR is a much nicer thing to program at this level.
 

Offline glarsson

  • Frequent Contributor
  • **
  • Posts: 814
  • Country: se
Re: Nothing more than a memory
« Reply #5 on: July 04, 2018, 11:01:23 am »
With the equ and var_1 situation, where is the data for this variable actually stored?
It is stored in RAM owned by the assembler. It is not a variable, just a name that can be used instead of the number. It just makes the source code neater and easier to understand and maintain.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: Nothing more than a memory
« Reply #6 on: July 04, 2018, 12:02:14 pm »
@PerranOak
Since you seem to be starting with that chip, there is a third "type" of  RAM memory labeled, "Linear Data Memory."   It accesses GPM but without paging using the FSR registers (FSR0 and/or FSR1).   It has the advantage of not requiring paging.   In brief, it can access all 384 bytes of GPM in a linear manner.   See these sections of the datasheet: 2.3, 3.2.3.1, and most important, 3.5.2.  FSR itself can access those areas, but if you set bit<5> of FSRnH (i.e., FSR = 0x2nnn), it is done as if the register is much larger (i.e, 384 bytes).  That can be convenient if you need a large buffer.  Much like the INDFn registers, it is not a physical register, but you can track is in a watch window.  It will look something like this:


As some user have stated, it is just another door to the GPM and Common Ram locations.  Of course, Common Ram (limited to 16 bytes) does not require paging either.

John
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: Nothing more than a memory
« Reply #7 on: July 04, 2018, 03:03:06 pm »
Thanks NorthGuy. With the equ and var_1 situation, where is the data for this variable actually stored?

This is not actually a variable. EQU doesn't reserve a space. It simply associates a name with a number.

After your EQU you can do:

Code: [Select]
  movf var_1,w
It's the same as:

Code: [Select]
  movf 0x20,w
It is up to you to make sure that the correct bank is selected and that other parts of the program don't use the same space.

The closest C equivalent would be

Code: [Select]
#define var_1 0x20
but not

Code: [Select]
char var_1 @0x20;
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #8 on: July 06, 2018, 04:53:57 pm »
Cheers all.

I'm still not straight re the programme memory and RAM.

Programme memory is where the programme code that you write is actually stored, yes? If so, in datasheet s.11.3 it talks about writing directly to "Flash Programme Memory" - is this the same thing? If it is the same thing, how is it possible/desirable to write data directly to where the programme is stored - will this not corrupt the programme? Is this different from s.3.1.1.2 "Indirect Read with FSR"?

Ah. thanks, there is also what is in s.3.5.2 "Linear memory" thought it is not really there it is the same as GPRAM. Is GPRAM an area that if you use direct addressing with FSRs then is may overwrite where the assembler stores variables?

Also, in the EEPROM write it talks about using the EEADRL, etc. registers. Theses need the value passed to them from variables but are variables in bank0 while these registers are in bank0>

Phew!

Thank you.
You can release yourself but the only way to go is down!
RJD
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: Nothing more than a memory
« Reply #9 on: July 06, 2018, 05:13:12 pm »
Programme memory is where the programme code that you write is actually stored, yes? If so, in datasheet s.11.3 it talks about writing directly to "Flash Programme Memory" - is this the same thing? If it is the same thing, how is it possible/desirable to write data directly to where the programme is stored - will this not corrupt the programme?

It certainly will corrupt the program if it's there. You can use some areas for program and others for data. Or you can create a bootloader which automatically program the new version of your firmware.

Ah. thanks, there is also what is in s.3.5.2 "Linear memory" thought it is not really there it is the same as GPRAM. Is GPRAM an area that if you use direct addressing with FSRs then is may overwrite where the assembler stores variables?

FSR can address memory through banks.

In addition to this, all the regular memory areas from all banks (80 bytes from a bank) are mapped consecutively to the addresses starting from 0x2000. E.g, first bank (0x20-0x6f) is mapped to (0x2000-0x204f), second bank (0xa0-0xef) is mapped to (0x2050-0x209f) etc. The 0x2000 area is only accessible through FSRs. This lets you have consecutive arrays which are longer than 80 bytes which would otherwise be impossible.

Also, in the EEPROM write it talks about using the EEADRL, etc. registers. Theses need the value passed to them from variables but are variables in bank0 while these registers are in bank0>

EEPROM is a separate space, different from either program or date space. You only access it through special registers. Other PICs may have EEPROM mapped to the program memory space, but I don't think yours is one of them.
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #10 on: July 09, 2018, 12:07:23 pm »
Thank you very much.

How do you know where your programme is in memory so that you can avoid it when using the programme memory for data?

Also, when a programme uses variables are these just stored dynamically and not in any specific memory location?
You can release yourself but the only way to go is down!
RJD
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: Nothing more than a memory
« Reply #11 on: July 09, 2018, 01:21:54 pm »
How do you know where your programme is in memory so that you can avoid it when using the programme memory for data?

You decide where you put the program and where you put the data.

Also, when a programme uses variables are these just stored dynamically and not in any specific memory location?

It is up to you to decide where your variables are. When you decide this, you use commands to access your variables at the known addresses.

The Mucrochip's asm has a relocatable mode where you write code, then the linker allocates your variables for you.

Better yet, if you use C, it'll allocate all the variables for you, will take care of banking/paging etc. If you don't feel you can benefit from doing these things manually, it's a good idea to use C.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14445
  • Country: fr
Re: Nothing more than a memory
« Reply #12 on: July 09, 2018, 05:13:53 pm »
Ahh, the fond memories of bank selection in older PICs... :D
Either use C which will take care of bank selection... or if you still want to use ASM, you will have to properly lay out your variables in memory and change banks when needed. Selecting the bank at every variable access would be very inefficient (and C compilers usually try to minimize bank selection).
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #13 on: July 09, 2018, 08:32:20 pm »
Hmm. I think the programme memory allocation stuff is beyond me at the moment but I do want to continue with assembly for now.

How do you organise variables in memory?
You can release yourself but the only way to go is down!
RJD
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13741
  • Country: gb
    • Mike's Electric Stuff
Re: Nothing more than a memory
« Reply #14 on: July 09, 2018, 09:29:20 pm »
Hmm. I think the programme memory allocation stuff is beyond me at the moment but I do want to continue with assembly for now.

How do you organise variables in memory?
You use C - the compiler does it for you.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #15 on: July 10, 2018, 02:57:15 pm »
… but then I'll never understand it.
You can release yourself but the only way to go is down!
RJD
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Nothing more than a memory
« Reply #16 on: July 11, 2018, 08:32:45 am »
Hmm. I think the programme memory allocation stuff is beyond me at the moment but I do want to continue with assembly for now.

How do you organise variables in memory?

When I did PIC assembly, I just started at address 20 (in hex) and just gave each byte-sized variable the next address.

If something needed more than 8 bits I defined the high and low bytes separately - e.g TEMPH and TEMPL.

However, once you use the first bank of memory (224 bytes, IIRC) things rapidly get very complex, as you need to put a lot more structure is what is stored in which bank.

The small PIC micros are a terrible target for C compilers. The banked data and code memories is just C friendly (not to mention the shallow call stack). The instruction set is so small and has a lot of features that C cannot access directly (like a carry flag, or bit test operators).

They are nice for assember coding. The entire instruction set can be fully documented on one side of one page and counting clock cycles is easy.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: Nothing more than a memory
« Reply #17 on: July 11, 2018, 11:36:22 am »
Hmm. I think the programme memory allocation stuff is beyond me at the moment but I do want to continue with assembly for now.

How do you organise variables in memory?

It would be a little easier, if you told us which family of chips you plan to use.   Although the method in Assembly is basically the same for most chips, there are differences.  If you are using an enhanced mid-range chip, then there are more options as I and NorthGuy have pointed out.

First, I try to minimize the number of variables I use.   Most of my stuff has a 'temp' and a 'count' register; although, I may not use both in a final version of the code.   You could call them whatever, e.g., temp0, temp1, ...  Some people prefer acc or accum, etc.

For such variables, I use Common RAM.   It starts at 0x70 and goes to 0x7F.  It is accessible from any bank, but of course can hold only 16 bytes.

For variables that will only be accessed when in bank 0, I use the space beginning at 0x20 and going to 0x6F.  It is called General Purpose RAM.  Most important, it is banked.  That is, each bank has its own section.  Go to Table 3-3 (usually)called "Memory Map."

If you need a really large area of contiguous RAM, then you can use what is called "Linear Memory" (also described by NorthGuy).  That uses indirect accessing (i.e., FSRn and INDFn) and acts as if all of GP RAM was one space.   Depending on the chip, that can give access to hundreds of contiguous bytes.

In actual practice, I use mainly GP RAM at 0x20..0x6F (Bank 0) and Common RAM at 0x70..0x7F almost exclusively.   If I need a large space for variables that change frequently, like for a buffer, I use Linear Memory.   I tend to start that buffer at 0x80 (actually accessed indirectly at 0x2080) to preserve the lowest bank of GP RAM.   Banking is really a non-issue for me.

EDIT: BTW, if you like a lot of different register names ("aliases").  You use as many as you want.  The same register location can have several aliases as can the individual bits in different registers.  Just look at the .inc file for your chip and you will an extreme example of that. 
« Last Edit: July 11, 2018, 11:43:52 am by jpanhalt »
 

Offline StillTrying

  • Super Contributor
  • ***
  • Posts: 2850
  • Country: se
  • Country: Broken Britain
Re: Nothing more than a memory
« Reply #18 on: July 11, 2018, 11:55:16 am »
Hmm. I think the programme memory allocation stuff is beyond me at the moment but I do want to continue with assembly for now.

Have a look at the Assembler's  View > Program Memory  or  View > Disassembly Listing.

Worry about calls and gotos above 07ffh and PCLATH when you get to them. :)

Quote
How do you organise variables in memory?

cblock and endc are useful, they save having to use all the "equ"s. You can just list your ram variables between them.

Code: [Select]
cblock 0x20
  tempL, tempH
  bin    :4    ;  = 4 bytes, named "bin" to "bin+3"
endc

cblock 0x70
  ram bytes common to all banks
endc
« Last Edit: July 11, 2018, 11:58:00 am by StillTrying »
.  That took much longer than I thought it would.
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #19 on: July 11, 2018, 12:49:55 pm »
Thanks all.

At the moment all I do is use memory at 20h and this larger structure is what I can't quite get.

I am using the PIC16F1827. So, the common RAM is that last 16 bytes after general purpose RAM which is where the 20h area (that I use now) is located. The advantage of the common RAM is that you don't have to use banksel?
The linear memory INCLUDES the general purpose and common RAM does it? I hadn't picked that up as each section shows a different memory map.

I can't see cblock or endc in the datasheet … oh wait, yes I se it's in the MPASM manual, cheers.
You can release yourself but the only way to go is down!
RJD
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: Nothing more than a memory
« Reply #20 on: July 11, 2018, 04:01:16 pm »
I have experience with the 16F1827.

Linear Memory does not include Common Ram.  You can say where to start it, which is why I start after 0x6F.  If you look at the registers, you will see Linear RAM mapped to the various physical GP RAM registers, but from the user's perspective it is a contiguous block of 350+ bytes accessed indirectly.  I start at 0x80 so as to avoid "looking like" it starts in Common Ram.  That way, I know where to look for the registers.

Like all threads, this one seems to have wandered.   What is your current question?
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #21 on: July 12, 2018, 12:55:02 pm »
Thank you.
It's really just to get to grips with all the different kinds of memory. The "memory maps" confuse me as there are different ones for different purposes and they all seem to start at 00h without there being one master map that shows where they all reside relative to each other. This is how I got confused with linear memory and GP RAM.

So, the map I think  understand is the one in banks with all the registers and the 80bytes of GP RAM and 16bytes of common RAM at the bottom.
I think that the GP RAM is what I am using when I use the equ command to "name" memory locations. I've not used the common RAM yet but I think this is similar to GP RAM but does not require banksel. I think that these are incorporated into what is called "traditional data memory", shown as from 0000h to 0FFFh, in one memory map?

I now think that linear data memory, shown as from 2000h to 29AFh, is further memory separate from those above and can be addressed indirectly with the use of certain registers but not used by the equ command. I am also getting the feeling that people see the equ command as something used for storing constants rather than variables. Maybe linear data memory is for constants?

I think the program memory is somewhere else entirely and can be used for data but I'm not really understanding how to that ensure this doesn't overwrite my programmes - I'll park this one for now. I'm not sure if "program flash memory" is the same as this?

Sorry to waffle on.
You can release yourself but the only way to go is down!
RJD
 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1611
  • Country: gb
Re: Nothing more than a memory
« Reply #22 on: July 13, 2018, 06:59:27 pm »
The directive "equ" quite literally equates - it just allows one to assign a name to a value.  This can be for variables - which are just address locations, or constants, which are just literal values.  Which one depends on how you used that value.

If you have:

Code: [Select]
pooname1 equ 0x20     ; replaces all instances of "pooname1" with 0x20
pooname2 equ 35         ; replaces all instances of "pooname2" with 35, or 0x23

Either can be a variable, but if we assume pooname1 is a variable, you can use it with
Code: [Select]
movf pooname1,w        ; moves the contents of 0x20 memory location to the working reg
movwf pooname1         ; moves the contents of the working reg to location 0x20

but if its a constant, it can still be used:

Code: [Select]
movlw pooname1         ; move the literal value of pooname1 (0x20 in hex, or 32 in decimal) into the working reg
movlw pooname2         ; move the literal value of pooname1 (0x23 in hex, or 35 in decimal) into the working reg

I believe "#define" is used in assembly in the same way it is for C.  Similar to equ but.. it can be anything including a macro.  I *think* equ is limited to just values.  Eg:
Code: [Select]
#define LED1_ON   bsf PORTB,0x03  ; Set bit 3 of portb where an LED is connected

LED1_ON;

This can be a bit of a gotcha because if you make a mistake and use movlw instead of movf  x,w - then you end up putting the address location into the W reg every time, regardless of what value is stored in that location.  I could be wrong here, it's been a couple of decades since I did assembly - very few instances where it is required.  I implore you to just switch directly to C - it makes life much easier and allows you to focus on practical things rather than spending much of your time moving stuff in and out of the W reg.  And it really isn't that less efficient - a decent compiler like MikroC or even XC8 (if you set it up right) won't hog much program space.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: Nothing more than a memory
« Reply #23 on: July 13, 2018, 09:40:52 pm »
An easy way to remember it is that an equate must be a value(number).   A #define is just a text substitution.  It can be anything, including a value, but if you use a symbol as a value, then you must define that value.

Quote
From: MPASM™ Assembler, User’s Guide ,DS33014L

EQU:
4.28 equ - DEFINE AN ASSEMBLER CONSTANT

#DEFINE:
4.18 #define - DEFINE A TEXT SUBSTITUTION LABEL

For example, this assembles fine with one error (noted):
abc  equ   0x33
def  equ time        ;error: "symbol (time) not previously defined"

     #define   ghi  hours
     #define   jkl  0x13 

But, if you then try this:
     movf    ghi,w  you get an error: "symbol not previously defined (hours)," but if you try
     movf    jkl,w  there is no error because jkl is define as a value




« Last Edit: July 13, 2018, 09:42:44 pm by jpanhalt »
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: Nothing more than a memory
« Reply #24 on: July 14, 2018, 11:29:54 am »
That is fantastic thank you both very much.

Is it better to put variables into linear memory?

Is flash program memory the same as program memory? Presumably this area is not used for variables or constants?
You can release yourself but the only way to go is down!
RJD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf