Thursday, November 9, 2023

PIC16F84A EEPROM Reading And Writing Example Using XC8

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.

PIC16F84A EEPROM Reading And Writing Example Using XC8
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,

  1. EEDATA - EEPROM Data Register
  2. EEADR   - EEPROM Address Register
  3. EECON1
  4. and EECON2.

EEPROM Control Regsiter 1 (EECON1) has some control bits to read, write, and status checking of EEPROM operations. 

PIC16F84A EEPROM Reading And Writing Example Using XC8
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,

  1. EEPROM_READ(address)
  2. 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.

  1.  
  2. /*
  3.  for 9600 baud rate
  4.  * 1/9600 = 104uS per bit
  5.  * we can use 102.5uS per bit or above
  6.  */
  7.  
  8. #include <xc.h>
  9.  
  10. // PIC16F84A Configuration Bit Settings
  11.  
  12. // CONFIG
  13. #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
  14. #pragma config WDTE = OFF // Watchdog Timer (WDT disabled)
  15. #pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled)
  16. #pragma config CP = OFF // Code Protection bit (Code protection disabled)
  17.  
  18. #define _XTAL_FREQ 4000000
  19. #define TX RA0
  20. #define RX RA1
  21.  
  22. void sendChar(char data){
  23. TX=0;
  24. __delay_us(100);
  25. for(int i=0;i<8;i++){
  26. TX=data&(1<<0);
  27. data>>=1;
  28. __delay_us(75);
  29. }
  30. TX=1;
  31. __delay_us(100);
  32. }
  33.  
  34. char myChar=0,temp=0;
  35. void receiveChar(void){
  36. if(RX==0){
  37. __delay_us(100);
  38.  
  39. for(char i=0;i<8;i++){
  40. __delay_us(60);
  41. if(RX==1) myChar|=(1<<i);
  42. else myChar&=~(1<<i);
  43. }
  44. __delay_us(100);
  45. }
  46. }
  47.  
  48. void sendText(char *text){
  49. while(*text) sendChar(*text++);
  50. }
  51.  
  52. void softUARTInit(void){
  53. PORTA=0x00;
  54. TRISA=0x02;
  55. PORTB=0;
  56. TRISB=0;
  57. TX=1;
  58. }
  59.  
  60. void main(){
  61.  
  62. softUARTInit();
  63. sendText("PIC16F84A Software UART Read EEPROM Write And Read\r\n");
  64. for(uint8_t i=0;i<43;i++) {EEPROM_WRITE(i,i+48);while(WR==1);}
  65. for(uint8_t i=0;i<43;i++) {sendChar(EEPROM_READ(i)); while(RD==1);}
  66. sendText("\r\n");
  67. while(1){
  68.  
  69. }
  70. }
  71.  

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.

  1. /*
  2.  for 9600 baud rate
  3.  * 1/9600 = 104uS per bit
  4.  * we can use 102.5uS per bit or above
  5.  */
  6.  
  7. #include <xc.h>
  8.  
  9. // PIC16F84A Configuration Bit Settings
  10.  
  11. // CONFIG
  12. #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
  13. #pragma config WDTE = OFF // Watchdog Timer (WDT disabled)
  14. #pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled)
  15. #pragma config CP = OFF // Code Protection bit (Code protection disabled)
  16.  
  17. #define _XTAL_FREQ 4000000
  18. #define TX RA0
  19. #define RX RA1
  20.  
  21. __EEPROM_DATA('H','E','L','L','O','S','I','R');
  22. __EEPROM_DATA('P','I','C','1','6','F','8','4');
  23. __EEPROM_DATA(' ','S','i','m','p','l','e',' ');
  24. __EEPROM_DATA('U','A','R','T',' ','P','r','o');
  25. __EEPROM_DATA('g','r','a','m','m','i','n','g');
  26. __EEPROM_DATA(' ','W','i','t','h',' ','M','P');
  27. __EEPROM_DATA('L','A','B','X',' ','I','D','E');
  28. __EEPROM_DATA(' ','X','C','8',' ','C',' ','.');
  29.  
  30. void sendChar(char data){
  31. TX=0;
  32. __delay_us(100);
  33. for(int i=0;i<8;i++){
  34. TX=data&(1<<0);
  35. data>>=1;
  36. __delay_us(75);
  37. }
  38. TX=1;
  39. __delay_us(100);
  40. }
  41.  
  42. char myChar=0,temp=0;
  43. void receiveChar(void){
  44. if(RX==0){
  45. __delay_us(100);
  46.  
  47. for(char i=0;i<8;i++){
  48. __delay_us(60);
  49. if(RX==1) myChar|=(1<<i);
  50. else myChar&=~(1<<i);
  51. }
  52. __delay_us(100);
  53. }
  54. }
  55. void sendText(char *text){
  56. while(*text) sendChar(*text++);
  57. }
  58.  
  59. void softUARTInit(void){
  60. PORTA=0x00;
  61. TRISA=0x02;
  62. PORTB=0;
  63. TRISB=0;
  64. TX=1;
  65. }
  66.  
  67. void main(){
  68.  
  69. softUARTInit();
  70. sendText("PIC16F84A Software UART Read EEPROM Example 1\r\n");
  71. for(uint8_t i=0;i<8;i++) sendChar(EEPROM_READ(i));
  72. sendText("\r\n");
  73. for(uint8_t i=8;i<64;i++) sendChar(EEPROM_READ(i));
  74. while(1){
  75.  
  76. }
  77. }
  78.  

Click here to download its source file.

No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)