Showing posts with label Memory. Show all posts
Showing posts with label Memory. Show all posts

Sunday, August 23, 2020

Using ATMega32 Internal EEPROM Memory

Overview

Beside program memory and data memory, the ATMega32 contains up to 1024 bytes of internal EEPROM for auxiliary storage. It can handle up to 100,000 Write/Erase cycles. However its access time is slower than SRAM. Each registers of EEPROM are 8-bit wide unlike the internal program memory that is 16-bit wide. Program memory space is quite larger than EEPROM memory space. In the case of the ATMega32 the program memory is 32K bytes.

It's important to store user's settings data in to this non-volatile memory to prevent data lost next time the MCU turns on, or power interruption. We can also store this type of data in internal program memory (Flash Memory).

Writing And Reading EEPROM Example

The AVR LibC contains the "eeprom.h" library allow us to read and write different kind of data types inside EEPROM such as byte, word, float, etc. Even it's 8-bit wide the library handle this task for the programmers. This library has the following routines,

  • eeprom_read_byte
  • eeprom_read_word
  • eeprom_read_dword
  • eeprom_read_float
  • eeprom_read_block

 

  • eeprom_write_byte
  • eeprom_write_word
  • eeprom_write_dword
  • eeprom_write_float
  • eeprom_write_block

and other update routine. For more detail you can see the header file.

For an introductory example, the program will write a set of data of 256 addresses, and read them back.

Using ATMega32 Internal EEPROM Memory
Writing and Reading EEPROM Example
I use AVR LibC in Microchip Studio.

  1. /*
  2.  * EepromEx1.c
  3.  *
  4.  * Created: 7/20/2023 6:53:22 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #include <avr/eeprom.h>
  11.  
  12. #define F_CPU 8000000UL
  13. #include <util/delay.h>
  14.  
  15.  
  16. int main(void)
  17. {
  18. DDRC = 0xFF;
  19. for (uint8_t i= 0;i<0xFF;i++)
  20. eeprom_write_byte(i,i);
  21. while (1)
  22. {
  23. for (uint8_t i = 0; i<0xFF; i++)
  24. {
  25. PORTC = eeprom_read_byte(i);
  26. _delay_ms(250);
  27. }
  28.  
  29. }
  30. }
  31.  
  32.  

Click here to download its zip file.

Using the EEMEM attribute

EEMEM attribute allow us to declare data on EEPROM space. We can read or write the data using its address. In the following example, I declare a data array on EEPROM first, and then I read those data back.

  1. /*
  2.  * EepromEx2.c
  3.  *
  4.  * Created: 7/20/2023 9:16:24 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define F_CPU 8000000UL
  11. #include <util/delay.h>
  12.  
  13. #include <avr/eeprom.h>
  14.  
  15. const uint8_t myData[] EEMEM = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  16.  
  17. int main(void)
  18. {
  19. DDRC=0xFF;
  20. while (1)
  21. {
  22. for (int i =0;i<sizeof(myData);i++)
  23. {
  24. char temp = &myData[i];
  25. PORTC=eeprom_read_byte(temp);
  26. _delay_ms(1000);
  27. }
  28.  
  29. }
  30. }
  31.  
  32.  

Schematic Diagram

Using ATMega32 Internal EEPROM Memory
Using the EEMEM attribute
 

Click here to download its zip file.

Here's another example. I store constant 7-Segment data in EEPROM. The program will read them back and show it on display.

  1. /*
  2.  * EepromEx3.c
  3.  *
  4.  * Created: 7/20/2023 10:17:26 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9. #include <avr/eeprom.h>
  10.  
  11. #define F_CPU 8000000UL
  12. #include <util/delay.h>
  13.  
  14. /*Declare EEPROM Storage*/
  15. const uint8_t cCathode[] EEMEM = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
  16. 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
  17. const uint8_t cAnode[] EEMEM = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,
  18. 0x90,0x88,0x83,0xC6,0xA1,
  19. 0x86,0x8E};
  20.  
  21. int main(void)
  22. {
  23. DDRC=0xFF;
  24. DDRD=0xFF;
  25. while (1)
  26. {
  27. for (int i=0;i<sizeof(cCathode);i++)
  28. {
  29. PORTD=eeprom_read_byte(&cCathode[i]);
  30. PORTC=eeprom_read_byte(&cAnode[i]);
  31. _delay_ms(500);
  32. }
  33. }
  34. }
  35.  
  36.  

 

 

Using ATMega32 Internal EEPROM Memory
Displaying 7-Segment Data From EEPROM

 Click here to download its zip file.

Reading/Writing With Switches and a 7-Segment Display

In this example I use two DIP switches, one for input address while another one for input data that will write data into EEPROM. Input data is between 0 and 0x0F.

Using ATMega32 Internal EEPROM Memory
Reading/Writing With Switches and a 7-Segment Display
One the SW2 push button is pressed, it will write data from input DSW2 DIP switch with a given address from DSW1 DIP switch.

With any input address change from DSW1, it will read the data from new given address.

  1. /*
  2.  * EepromEx4.c
  3.  *
  4.  * Created: 7/21/2023 9:21:18 AM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define F_CPU 8000000UL
  11. #include <util/delay.h>
  12.  
  13. #include <avr/eeprom.h>
  14.  
  15. #define Write (PIND&0x08)==0
  16. #define LED 7
  17.  
  18. /*Declare EEPROM Storage*/
  19. uint8_t Edata[256] EEMEM;
  20.  
  21. const uint8_t cAnode[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
  22. 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
  23.  
  24. int main(void)
  25. {
  26. uint8_t oldAddr=1,newAddr=0,segment=0,inputData;
  27. DDRA=0x00;
  28. PINA=0xFF;
  29. DDRC=0xFF;
  30. PORTC=0xFF;
  31. DDRD=0x07;
  32. PORTD=0xF8;
  33. while (1)
  34. {
  35. /*Check Address Change*/
  36. if (newAddr!=oldAddr)
  37. {
  38. segment = eeprom_read_byte(&Edata[newAddr]);
  39. oldAddr = newAddr;
  40. }
  41. PORTC = cAnode[segment];
  42. newAddr = PINA;
  43. if (Write)
  44. {
  45. PORTC&=~(1<<LED);
  46. inputData = (PIND&0xF0)>>4;
  47. eeprom_write_byte(&Edata[newAddr],inputData);
  48. while(Write);
  49. segment = eeprom_read_byte(&Edata[newAddr]);
  50. PORTC|=(1<<LED);
  51. }
  52. }
  53. }
  54.  
  55.  

Click here to download source file. 

The example above use the 7-Segment data that store in SRAM. We can also store and read it from EEPROM.

  1. /*
  2.  * EepromEx5.c
  3.  *
  4.  * Created: 7/21/2023 3:11:48 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define F_CPU 8000000UL
  11. #include <util/delay.h>
  12.  
  13. #include <avr/eeprom.h>
  14.  
  15. #define Write (PIND&0x08)==0
  16. #define LED 7
  17.  
  18. /*Declare EEPROM Storage*/
  19. uint8_t Edata[256] EEMEM;
  20.  
  21. uint8_t cAnode[] EEMEM = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
  22. 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
  23.  
  24. int main(void)
  25. {
  26. uint8_t oldAddr=1,newAddr=0,segment=0,inputData,DisplayData=0;
  27. DDRA=0x00;
  28. PINA=0xFF;
  29. DDRC=0xFF;
  30. PORTC=0xFF;
  31. DDRD=0x07;
  32. PORTD=0xF8;
  33. while (1)
  34. {
  35. /*Check Address Change*/
  36. if (newAddr!=oldAddr)
  37. {
  38. segment = eeprom_read_byte(&Edata[newAddr]);
  39. DisplayData = eeprom_read_byte(&cAnode[segment]);
  40. oldAddr = newAddr;
  41. }
  42. PORTC = DisplayData;
  43. newAddr = PINA;
  44. if (Write)
  45. {
  46. PORTC&=~(1<<LED);
  47. inputData = (PIND&0xF0)>>4;
  48. eeprom_write_byte(&Edata[newAddr],inputData);
  49. while(Write);
  50. segment = eeprom_read_byte(&Edata[newAddr]);
  51. DisplayData = eeprom_read_byte(&cAnode[segment]);
  52. PORTC|=(1<<LED);
  53. }
  54. }
  55. }
  56.  
  57.  
  58.  

Click here to download its source file.

Storing and Reading Data From Flash Memory of ATMega32

ATMega32 contains 32K bytes of internal Flash memory for program storage. The Flash is organized as 16K x 16 because all AVR instructions are 16 or 32 bits wide. For software security, the Flash Program memory space is divided into two sections, Boot Program section and Application Program section.

The Flash Memory has an endurance of at least 10,000 write/erase cycles. The ATMega32 Program Counter (PC) is 14-bit wide, thus addressing the 16K program memory locations. 

ATMega32 has 2K bytes of internal SRAM. It's far smaller than its internal Flash. For any situation that the user needs to store a large amount of constant data, it is effective to store and read those data from internal Flash. For example we need to store font data at the amount of 1K bytes. This example project uses a lot of internal SRAM since the program store font and graphic data in SRAM instead of Flash.

The AVR LibC "pgmspace.h" contains routine that declare data into Flash Memory, reading byte data from Flash Memory, etc.

Storing and Reading Data From Flash Memory of ATMega32
Program Simulation
In this example, we store 7-Segments display data in Flash memory. At run-time the program will read 7-Segment data from internal Flash. It will display on a single 7-Segment display connects to PORTC.

  1. /*
  2.  * Example_2.c
  3.  *
  4.  * Created: 7/19/2023 1:52:49 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9. #include <avr/pgmspace.h>
  10. #define F_CPU 8000000UL
  11. #include "util/delay.h"
  12.  
  13. /*Declare constant data that will store in program Flash Memory*/
  14. const char cCathode[] PROGMEM =
  15. {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
  16. const char cAnode[] PROGMEM =
  17. {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
  18.  
  19. int main(void)
  20. {
  21. DDRC = 0xFF;
  22. while (1)
  23. {
  24. for (char i=0;i<16;i++)
  25. {
  26. /*Read Flash Data and assign to PORTC*/
  27. PORTC = pgm_read_byte(&cCathode[i]);
  28. _delay_ms(500);
  29. }
  30. }
  31. }
  32.  
  33.  

 

Click here to download its zip file.