PIC16F84A contains 68 bytes of EEPROM non-volatile memory. It's useful for storing some setting parameters when the MCU is powered off. EEPROM has a slower access time than SRAM and Flash memory. But it has a higher endurance compares to Flash memory. We can erase or write EEPROM up to 10 million times.
|  | 
| Running Program | 
Using a low level Assembly language or C programming language without EEPROM library, we can access to this memory via these four SRFs,
- EEDATA - EEPROM Data Register
- EEADR - EEPROM Address Register
- EECON1
- and EECON2.
EEPROM Control Regsiter 1 (EECON1) has some control bits to read, write, and status checking of EEPROM operations.
|  | 
| EECON1 Register | 
Using XC8 we can use all of these registers to read or write to EEPROM. However XC8 compiler has a built-in EEPROM library that's very easy to use. To read or write EEPROM, we only need these functions,
- EEPROM_READ(address)
- EEPROM_WRITE(address, data) .
We just include the "xc.h" header file to call these functions.
Example #1 : EEPROM Writing And Reading 
In this example, the program write a set of ASCII characters to EEPROM starting from address 0. Then the controller read them back, and they will be shown on virtual terminal. I use software UART (bit banging) to process serial data.
/*
for 9600 baud rate
* 1/9600 = 104uS per bit
* we can use 102.5uS per bit or above
*/
#include <xc.h>
// PIC16F84A Configuration Bit Settings
// CONFIG
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled)
#pragma config CP = OFF // Code Protection bit (Code protection disabled)
#define _XTAL_FREQ 4000000
#define TX RA0
#define RX RA1
void sendChar(char data){
TX=0;
__delay_us(100);
for(int i=0;i<8;i++){
TX=data&(1<<0);
data>>=1;
__delay_us(75);
}
TX=1;
__delay_us(100);
}
char myChar=0,temp=0;
void receiveChar(void){
if(RX==0){
__delay_us(100);
for(char i=0;i<8;i++){
__delay_us(60);
if(RX==1) myChar|=(1<<i);
else myChar&=~(1<<i);
}
__delay_us(100);
}
}
void sendText(char *text){
while(*text) sendChar(*text++);
}
void softUARTInit(void){
PORTA=0x00;
TRISA=0x02;
PORTB=0;
TRISB=0;
TX=1;
}
void main(){
softUARTInit();
sendText("PIC16F84A Software UART Read EEPROM Write And Read\r\n");
for(uint8_t i=0;i<43;i++) {EEPROM_WRITE(i,i+48);while(WR==1);}
for(uint8_t i=0;i<43;i++) {sendChar(EEPROM_READ(i)); while(RD==1);}
sendText("\r\n");
while(1){
}
}
Click here to download this example.
Example #2: Initializing EEPROM Data
Without using the EEPROM_WRITE function, we can initialize the EEPROM space. We use the __EEPROM_DATA() macro. The input is an 8 parameters. Each parameters are the 1 byte EEPROM data. For example,
__EEPROM_DATA('H','E','L','L','O','S','I','R'); .
In this example, I initialize some ASCII characters on EEPROM space. Then the program read them back before they are sent over the software UART terminal.
/*
for 9600 baud rate
* 1/9600 = 104uS per bit
* we can use 102.5uS per bit or above
*/
#include <xc.h>
// PIC16F84A Configuration Bit Settings
// CONFIG
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled)
#pragma config CP = OFF // Code Protection bit (Code protection disabled)
#define _XTAL_FREQ 4000000
#define TX RA0
#define RX RA1
__EEPROM_DATA('H','E','L','L','O','S','I','R');
__EEPROM_DATA('P','I','C','1','6','F','8','4');
__EEPROM_DATA(' ','S','i','m','p','l','e',' ');
__EEPROM_DATA('U','A','R','T',' ','P','r','o');
__EEPROM_DATA('g','r','a','m','m','i','n','g');
__EEPROM_DATA(' ','W','i','t','h',' ','M','P');
__EEPROM_DATA('L','A','B','X',' ','I','D','E');
__EEPROM_DATA(' ','X','C','8',' ','C',' ','.');
void sendChar(char data){
TX=0;
__delay_us(100);
for(int i=0;i<8;i++){
TX=data&(1<<0);
data>>=1;
__delay_us(75);
}
TX=1;
__delay_us(100);
}
char myChar=0,temp=0;
void receiveChar(void){
if(RX==0){
__delay_us(100);
for(char i=0;i<8;i++){
__delay_us(60);
if(RX==1) myChar|=(1<<i);
else myChar&=~(1<<i);
}
__delay_us(100);
}
}
void sendText(char *text){
while(*text) sendChar(*text++);
}
void softUARTInit(void){
PORTA=0x00;
TRISA=0x02;
PORTB=0;
TRISB=0;
TX=1;
}
void main(){
softUARTInit();
sendText("PIC16F84A Software UART Read EEPROM Example 1\r\n");
for(uint8_t i=0;i<8;i++) sendChar(EEPROM_READ(i));
sendText("\r\n");
for(uint8_t i=8;i<64;i++) sendChar(EEPROM_READ(i));
while(1){
}
}
Click here to download its source file.
 
No comments:
Post a Comment