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