| « Weak Pull up Resistors. | Accelerate » |
One of the most key features of any electronic system is how memory is organized. This includes how much Ram and Rom, how they are subdivided and how to access the memory. Every series of PIC is different and every PIC has different amounts of memory. It is your job to understand how memory is mapped in your system and to use if efficiently.
A memory system defines a system, it is the one thing that makes it unique and when you master it, you master a system. This has two effects, it makes a system hard to master, and it makes other systems easier to use. Every system from X86 to PowerPC to our PICs are essentially the same thing, ROM to store program data, RAM to store variables and running code and a processor to crunch data. No matter what, a processor might have different instructions, but it still is a beast that doesn’t change too much. ROM and RAM define a system; every system is going to use it differently. The logic rarely changes system to system however the code can do a complete 360 depending on what system you use just because of how memory is mapped.
First let’s define a few things:
RAM (Random Access Memory): This is the place where your variables reside (General Purpose Registers), and how you access special function registers. When you setup a Cblock or set a variable to an address, this is where it’s going. RAM is super fast but very limited, and everything is stored temporarily. RAM is merely to hold values that are important to current operation.
ROM (Read-Only Memory): ROM is like your hard disk, its where all permanent data is stored, like your program. This is marginally slower but not too slow. Unlike your hard disk, this ROM is super fast since it’s on die. When you program your code onto a PIC this is where it goes.
Since a lot of this blog focuses on the PIC16F690 I am going to be going over the memory architecture of it.
Everything on memory organization can be found in the section 2.0 Memory Organization:
http://ww1.microchip.com/downloads/en/DeviceDoc/41262E.pdf
The first section goes over a few things you should know:
The RAM is partitioned into 4 banks (0-3). Depending on the data you’re addressing depends on which bank you need to access. In each bank you’ll find a mirage of General Purpose Registers, used for storing program variables, and Special Function Registers, used for controlling the microcontroller. The next few tables’ show where these SFR reside and what banks they’re located in. The rest is just trivial stuff we’ve gone over before.
Likewise how the RAM is partitioned so is the ROM. The ROM is compromised by Program Memory and Data Memory. Program memory is reserved for your program (however on PIC18’s and above you can write to it and use it for data). Data memory is used exclusively for storing data. On the PIC16F690 it is 256 Bytes. Writing and controlling this DATA ROM is not as straight forward as controlling a GPR.
The PIC has a built in EEPROM control module which you use to read and write to EEPROM.
The EEPROM Control Module:
This module is fairly simple and allows you to store program variables in hard data for later use. 256 Bytes doesn’t sound like much but it does come in handy.
The Registers:
EECON1: Control register.
EECON2: Non implemented register used in writing data (see below)
EEDAT: This is the register that holds the data to be written or has been read.
EEDATH: Some memory is larger than 8 bits so this is the High portion of the register that contains the MSB of a non 8-bit number.
EEADR: This is the register that holds the memory address of the a data to be read or written
EEADRH: The high register for EEADR for non 8-bit addresses.
The Sequence:
Write (Data memory only):
Configure EEPROM for write
Set the address to be written to EEADR and EEADRH
Set the data in the data registers
Initiate a write sequence and wait.
Read (Data and program memory):
Configure EEPROM for read
Set the address to be read to EEADR and EEADRH
Initiate a read sequence and wait.
Data will be in the data register.
The sequence is pretty straightforward, the only tough part is the control so lets go over EECON1.
EECON1: EEPROM control register
Bit 7: EEPGD – 1: Access Program Memory 0: Acess Data memory
Bit 6-4: Unimplemented
Bit 3: WRERR – 1: There was a write error 0: Write operation completed
Bit 2: WREN – 1: Allows write to EEPROM 0: Write is not allowed
Bit 1: WR – 1: Initiates a write 0: Write is complete
Bit 0: RD – 1: Initiates a Read 0: Read is complete.
As you can see, this module is pretty simple a sample read code will be something of the sort:
clrf EECON1 ;Read Data memory, do not allow writes movlw 0x00 movwf EEADR movwf EEADRH ;Clear address location start at 00 bsf EECON1,0 ;Initiate read btfsc EECON1,0 ;Wait till clear goto $-1 movfw EEDAT ;Move read data to where-ever movwf DAT
Reading from EEPROM will be very similar to the above routine just make sure you're in the right banks for each register (EECON1 and EEDAT/EEADR aren't in the same bank)
Writing to the EEPROM isn't exactly as intuitive as reading but is still pretty easy:
Just like above, you set up the EECON1 register for whatever you're doing and move the data you want to write into EEDAT and the address you want to in EEADR and EEADRH. After you do that, you initiate a write sequence such as the following:
WRITE: bsf STATUS,RP0 movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR btfsc EECON1,WR goto $-1 bcf STATUS,RP0 return
Now, to write to data EEPROM you must write 0x55 then 0xAA to EECON2 (one after another) and then set the WR bit on EECON1.
This sequence is what is required by Microchip in their data sheet.
Other thank that, EEPROM control is fairly straight forward and is very powerful.
Good luck and any questions/concerns please feel free to send me an EMAIL.