What is a memory chip and how to program microcircuits. How to clear EEPROM (Non-volatile memory) Using eeprom memory

Last time, when I wrote my “detailed answer to the question” about how to backup the firmware from Mega, they reproached me for not mentioning the EEPROM backup. That time I didn’t do it consciously, because... I rightly judged that there is no need to complicate everything at the stage of the initial “approach to the projectile.” The fact is that it is not obvious to everyone that the EEPROM is not flashed when compiling and uploading the firmware from Arduino IDE. That is, this means that absolutely nothing is uploaded to the EEPROM when the firmware is uploaded from the IDE. And manipulations with EEPROM (if its use is enabled in the firmware at all) are performed at a completely different level. And therefore, to backup bare firmware without fine adjustments, which POSSIBLY (only perhaps) can be stored in EEPROM, it was quite enough to save only the bare firmware. But since the question has arisen, why not “chew” it. Let's go through it in order. What is EEPROM and why talk about it?
EEPROM - (Electrically Erasable Programmable Read-Only Memory) area of ​​​​non-volatile memory of the microcontroller into which information can be written and read. It is often used to store program settings that may change during operation and must be stored when the power is turned off.

How does a 3D printer use EEPROM?
Let's look at Marlin as an example. In Marlin Firmware out of the box, EEPROM is not used. The configurator parameters (Configuration.h), which include the ability to use it, are commented out by default.

#define EEPROM_SETTINGS
#define EEPROM_CHITCHAT

If the use of EEPROM is enabled, the printer can store and use the following settings (specified from the bourgeoisie):

  • Number of steps per millimeter
  • Maximum/minimum feed speed [mm/s]
  • Maximum acceleration [mm/s^2]
  • Acceleration
  • Acceleration during retract
  • PID Settings
  • Home position offset
  • Minimum feed speed during movement [mm/s]
  • Minimum section time [ms]
  • Maximum speed jump X-Y axes[mm/s]
  • Maximum speed jump in Z axis [mm/s]
You can edit these settings using the printer screen and controls. When using EEPROM is enabled, the menu should display the following items:
  • Store memory
  • Load memory
  • Restore Failsafe
You can also use GCode to work directly (via Pronterface).
  • M500 Saves the current settings in EEPROM until the next startup or command M501.
  • M501 Reads settings from EEPROM.
  • M502 Resets the settings to the default values ​​specified in Configurations.h. If you execute M500 after it, the default values ​​will be entered into the EEPROM.
  • M503 Displays the current settings - ""Those recorded in the EEPROM.""
You can read about EEPROM in Repitier firmware.

How to read and write data to EEPROM?
Similar to the method described in the firmware backup method using the key -U. Only in this case, after it there will be a pointer indicating that the EEPROM needs to be read.

avrdude.exe -p atmega2560 -c wiring -PCOM5 -b115200 -Ueeprom:r:"printer_eeprom".eep:i

This command reads the EEPROM data into the file "printer_eeprom.eep". If successful, you will see something like the following on the screen.

Recording is also not complicated and is performed by a similar command, which differs only in that in the key -U It's not "r", but "w".

avrdude.exe -p atmega2560 -c wiring -PCOM5 -b115200 -Ueeprom:w:"printer_eeprom".eep:i

If successful, you will see something like the following message on the screen.

How and why to erase EEPROM?
To begin with, “why do this?” You need to erase the EEPROM if the previous firmware also used it, and there could be garbage left in the memory. Somewhere I have already come across people with problems that after switching from one firmware to another (from Marlin to Repitier EMNIP), their printer began to behave, so to speak, “creatively”. This is due to the fact that different firmware stores their data under different addresses. And when you try to read data from the wrong address, pandemonium begins.
You can erase EEPROM only programmatically from the firmware, but to do this you will have to temporarily upload a special sketch to the controller. You can read more about this in the official Arduino documentation.
If the EEPROM is erased not in Arduino board, and in some abstract controller, the sketch code will need to be changed taking into account the size of the EEPROM in a specific controller on the board. To do this, you will need to change the ending condition in the "For" loop. For example, for ATmega328, which has 1kb EEPROM memory, the cycle will look like this:
Conclusion.
I've been rambling for quite some time, but what's all this for? In order to bring to the conclusion that when backing up the firmware, the EEPROM can also be saved, but only if you need the settings saved in it. If you are ready to sacrifice them, then forget about it. Also, if you change one firmware to another, or switch from a version to another, do not be lazy to clear the EEPROM before uploading new firmware. Well, at the same time we learned a lot of new things.

Our furnace controller is almost ready - however, for now it remains a “goldfish” controller that remembers all settings only five minutes before the first power off. To remember our settings, the value of the set temperature and calibration points even after turning off the power, you need to use non-volatile memory - EEPROM.
Our friends have written very well about working with EEPROM.

The main thing we need to know is that EEPROM memory It is better to consider it not as “just memory”, but as a separate internal device in the chip.
EEPROM separate address space, which has nothing to do with the processor address space (FLASH and SRAM); in order to access data at a specific address in non-volatile memory, you need to execute a certain sequence actions using a number of registers (address registers EEARH and EEARL, data register EEDR and control register EECR).
According to the datasheet, to write a byte to a specific address in EEPROM, you need to do the following:

  1. wait for the EEPROM to be ready to write data (the EEPE bit of the EECR register is reset);
  2. wait for the end of writing to FLASH memory (resetting the SELFPRGEN bit of the SPMCSR register) - this must be done if the bootloader is present in the program;
  3. write down new address to the EEAR register (if necessary);
  4. write a data byte to the EEDR register (if necessary);
  5. set the EEMPE bit of the EECR register to one;
  6. within four clock cycles after setting the EEMPE flag, we write a logical one to the EEPE bit of the EECR register.

The processor then skips 2 clock cycles before executing the next instruction.
The second point must be performed if there is a bootloader in the program - the fact is that writing to EEPROM cannot be performed simultaneously with writing to FLASH memory, so before writing to EEPROM you need to make sure that programming of FLASH memory is completed; if the microcontroller does not have a bootloader, then it never changes the contents of FLASH memory (remember that avr has a Harvard architecture: program memory (FLASH) and data memory (SRAM) are separated).
The duration of the recording cycle depends on the frequency of the internal RC oscillator of the chip, supply voltage and temperature; usually for ATmega48x/88x/168x models this is 3.4 ms (!), for some older models – 8.5 ms (!!!).
In addition, when writing to EEPROM, problems may arise with calling interrupts during the execution of the sequence of actions above - so it is better to disable interrupts while writing to EEPROM.
Reading non-volatile memory is a little simpler:

  1. wait for the EEPROM to be ready to read data (the EEWE bit of the EECR register is reset);
  2. write the address to the EEAR register;
  3. set the EERE bit of the EECR register to one;
  4. we read data from the EEDR register (in fact, when the requested data is moved to the data register, it happens hard reset bit EERE; but there is no need to monitor the state of this bit, since the read operation from EEPROM is always performed in one clock cycle).

After setting a bit in EERE to one, the processor skips 4 clock cycles before executing the next instruction.
As we see, working with non-volatile memory– the process is time-consuming; if we often write and read data from EEPROM, the program may begin to slow down.

However, we are writing a program in the IAR environment, and we are lucky: all the work with reading and writing from EEPROM will be done by the development environment - iar has the “__eeprom” modifier, which creates variables in non-volatile memory - and then we will just need to read from “ constant" variables to "current" (when initializing the controller), or write from "current" variables to "constant" - that is, when the current value changes, the value of the variable in non-volatile memory must also be changed.
The new variables will look like this:

Eeprom uint16_t EEP_MinTemperature;

A couple more general words: and although we do not assume pointers to eeprom variables, we need to remember that eeprom is a separate address space, and in order to create a pointer to eeprom (and the compiler allows us to do this), we must indicate that this is a pointer to an address in eeprom:

Uint16_t __eeprom *EEP_MinTemperatureAdr;

Let's return to the stove controller and EEPROM. In our case, there is no EEPROM virtual machine, of course, is not expected; Moreover, it’s worth considering whether a separate library is needed to work with non-volatile memory - they are too “scattered” across the recording program important settings; if you try to make a separate library, you will have to make cross-references: in the library for EEPROM, connect the libraries of the ADC, heating element, and global settings; and in these peripheral libraries, connecting the EEPROM library is not a very good approach.
Another option is to add an eeprom variable to each library where you need to save settings, and save the corresponding settings directly in virtual machines. We will implement this option.
First, let's list what variables we need to save in EEPROM:

  1. calibration points
  2. values ​​of the maximum-minimum set temperature and temperature setting step
  3. set temperature value
  4. PID controller coefficients

We do not save the value of the kitchen timer - we will assume that the user must set the stove timer each time after turning off the power.
All these settings are set by the user by turning the encoder and then briefly pressing the user button. At the same time, we remember that the number of EEPROM read-write cycles is still limited, so do not overwrite the same information again (for example, if the user selected the same value of some setting as it was). Therefore, before each change to the __eeprom variable, we check whether it needs to be rewritten:

//if the value has changed, overwrite it in non-volatile memory if (ADCTemperature.atMinTemperatureValue != (uint16_t)VMEncoderCounter.ecntValue) ( ​​ADCTemperature.atMinTemperatureValue = (uint16_t)VMEncoderCounter.ecntValue; EEP_MinTemperature = ADCTemperature.atMinTemperatureV alue;)

Reading settings from EEPROM is also simple - when initializing the “current” settings, we simply read the value from non-volatile memory:

ADCTemperature.atMinTemperatureValue = EEP_MinTemperature;

In order for our device to have some settings in the EEPROM from the very beginning, the project for the first boot can be compiled with these variables initialized:

Eeprom uint16_t EEP_MinTemperature = 20; ... //array for storing calibration points in non-volatile memory __eeprom TCalibrationData EEP_CalibrationData = ((20, 1300), (300, 4092));

In this case, the compiler initializes __eeprom variables before starting work with the main function. To get a file with non-volatile memory (.eep), you need to go into the following settings:
Project->Options..->Linker->Extra Options
If the “Use command line options” checkbox is not checked, check it and add the line
-Ointel-standard,(XDATA)=.eep
First we compile the project with initialized variables, save the eep file separately; then we remove initialization when creating variables.

That's all - our stove is ready!

Arduino is a whole family various devices for creating electronic projects. Microcontrollers are very convenient to use and are easy to learn even for a beginner. Each microcontroller consists of a board, programs for operation, and memory. This article will look at the non-volatile memory used in Arduino.

Description of EEPROM memory

Arduino provides its users with three types of built-in device memory: stationary RAM (random access memory or SRAM - static random access memory) - necessary for recording and storing data during use; flash cards – for saving already recorded patterns; – for storage and subsequent use of data.

All data on RAM is erased as soon as the device is rebooted or the power is turned off. The second two save all information before overwriting and allow you to retrieve it if necessary. Flash drives are quite common nowadays. It is worth considering EEPROM memory in more detail.

The abbreviation stands for Electrically Erasable Programmable Read-Only Memory and translated into Russian literally means electrically erasable programmable read-only memory. The manufacturer guarantees the safety of information for several decades after the last power outage (usually a period of 20 years is given, depending on the rate at which the device’s charge decreases).

However, you need to know that the ability to rewrite to a device is limited and is no more than 100,000 times. Therefore, it is recommended to be careful and attentive to the data entered and not to overwrite it again.

The amount of memory, in comparison with modern media, is very small and varies for different microcontrollers. For example, for:

  • ATmega328 – 1kB
  • ATmega168 and ATmega8 – 512 bytes,
  • and ATmega1280 – 4 kB.

It’s designed this way because each microcontroller is designed for a specific volume of tasks, has a different number of pins for connection, and accordingly, a different amount of memory is required. Moreover, this amount is sufficient for commonly created projects.

Writing to EEPROM requires a significant amount of time - approx. 3 ms. If the power is turned off while recording, the data will not be saved at all or may be recorded incorrectly. It is always necessary to additionally check the entered information to avoid failures during operation. Reading data is much faster, and the memory resource is not reduced.

Library

Working with EEPROM memory is carried out using a library that was specially created for Arduino. The main ones are the ability to write and read data. activated by command #include EEPROM.h.

  • For records– EEPROM.write(address, data);
  • For reading– EEPROM.read(address).

In these sketches: address – an argument with the data of the cell where the data of the second argument data is entered; when reading, one argument is used, address, which indicates where the information should be read from.

Function Purpose
read(address) reads 1 byte from EEPROM; address – address from which data is read (cell starting from 0);
write(address, value) writes value (1 byte, number from 0 to 255) to memory at address;
update(address, value) replaces value at address if its old contents are different from the new ones;
get(address, data) reads data of the specified type from memory at address;
put(address, data) writes data of the specified type into memory at address;
EEPROM allows you to use the "EEPROM" identifier as an array to write data to and read from memory.

Writing Integers

Writing integers to non-volatile EEPROM memory is quite simple. Entering numbers occurs when the function is launched EEPROM.write(). The required data is indicated in brackets. In this case, numbers from 0 to 255 and numbers over 255 are written differently. The first ones are entered simply - their volume takes 1 byte, that is, one cell. To write the latter, you must use the operators highByte() for the highest byte and lowByte() for the lowest byte.

The number is divided into bytes and written separately in cells. For example, the number 789 will be written in two cells: the first will contain the factor 3, and the second will contain the missing value. The result is the required value:

3 * 256 + 21 = 789

For « reunion" large integer applies word function(): int val = word(hi, low). You need to read that the maximum integer for recording is 65536 (that is, 2 to the power of 16). In cells that have not yet had other entries, the monitor will display the numbers 255 in each.

Writing floating point numbers and strings

Floating point and string numbers are a form of writing real numbers where they are represented by a mantissa and an exponent. Such numbers are written to non-volatile EEPROM memory by activating the function EEPROM.put(), reading, respectively, – EEPROM.get().

When programming, floating point numeric values ​​are designated as float; it is worth noting that this is not a command, but a number. Char type (character type) – used to represent strings. The process of writing numbers on the monitor is started using setup(), reading - using loop().

During the process, the values ​​ovf, which means “overfilled,” and nan, which means “missing,” may appear on the monitor screen numeric value" This means that the information written to the cell cannot be reproduced as a floating point number. This situation will not arise if you know reliably in which cell what type of information is recorded.

Examples of projects and sketches

Example No. 1

The sketch will write up to 16 characters from the serial port and output 16 characters from the EEPROM in a loop. Thanks to this, data is written to EEPROM and the contents of non-volatile memory are monitored.

// check the operation of EEPROM #include int i, d; void setup() ( Serial.begin(9600); // initialize the port, speed 9600 ) void loop() ( // read EEPROM and output 16 data to the serial port Serial.println(); Serial.print("EEPROM= " ); i= 0; while(i< 16) { Serial.print((char)EEPROM.read(i)); i++; } // проверка есть ли данные для записи if (Serial.available() != 0) { delay(50); // ожидание окончания приема данных // запись в EEPROM i= 0; while(i < 20) { d= Serial.read(); if (d == -1) d= " "; // если символы закончились, заполнение пробелами EEPROM.write(i, (byte)d); // запись EEPROM i++; } } delay(500); }

Example No. 2

For a better understanding, we can create a small sketch that will help in understanding how to work with non-volatile memory. We count all the cells of this memory. If the cell is not empty - output to the serial port. Then fill the cells with spaces. Then we enter the text through the serial port monitor. We write it to EEPROM, and read it the next time it is turned on.

#include int address = 0; // eeprom address int read_value = 0; // data read from eeprom char serial_in_data; // serial port data int led = 6; // line 6 for LED int i; void setup() ( pinMode(led, OUTPUT); // line 6 is configured as output Serial.begin(9600); // baud rate on serial port 9600 Serial.println(); Serial.println("PREVIOUS TEXT IN EEPROM: -"); for(address = 0; address< 1024; address ++) // считываем всю память EEPROM { read_value = EEPROM.read(address); Serial.write(read_value); } Serial.println(); Serial.println("WRITE THE NEW TEXT: "); for(address = 0; address < 1024; address ++) // заполняем всю память EEPROM пробелами EEPROM.write(address, " "); for(address = 0; address < 1024;) // записываем пришедшие с последовательного порта данные в память EEPROM { if(Serial.available()) { serial_in_data = Serial.read(); Serial.write(serial_in_data); EEPROM.write(address, serial_in_data); address ++; digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); } } } void loop() { //---- мигаем светодиодом каждую секунду -----// digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); }

Example No. 3

Writes two integers to memory, reads them from EEPROM and outputs them to the serial port. Numbers from 0 to 255 occupy 1 byte of memory, using the function EEPROM.write() are written to the desired cell. For numbers greater than 255, they must be divided into bytes using highByte() And lowByte() and write each byte into its own cell. The maximum number in this case is 65536 (or 2 16).

#include // connect the EEPROM library void setup() ( int smallNum = 123; // integer from 0 to 255 EEPROM.write(0, smallNum); // write a number to cell 0 int bigNum = 789; // split the number > 255 by 2 bytes (max. 65536) byte hi = highByte(bigNum); // high byte byte low = lowByte(bigNum); // low byte EEPROM.write(1, hi); // write high byte of EEPROM to cell 1 .write(2, low); // write the low byte to cell 2 Serial.begin(9600); // initialize the serial port ) void loop() ( for (int addr=0; addr<1024; addr++) { // для всех ячеек памяти (для Arduino UNO 1024) byte val = EEPROM.read(addr); // считываем 1 байт по адресу ячейки Serial.print(addr); // выводим адрес в послед. порт Serial.print("\t"); // табуляция Serial.println(val); // выводим значение в послед. порт } delay(60000); // задержка 1 мин }

Example No. 4

Writing floating point numbers and strings - method EEPROM.put(). Reading – EEPROM.get().

#include // connect the library void setup() ( int addr = 0; // address float f = 3.1415926f; // floating point number (float type) EEPROM.put(addr, f); // write the number f to address addr addr += sizeof(float); // calculate the next free memory cell char name = "Hello, SolTau.ru!"; // create an array of characters EEPROM.put(addr, name); // write the array to EEPROM Serial.begin (9600); // initializing the serial port ) void loop() ( for (int addr=0; addr<1024; addr++) { // для всех ячеек памяти (1024Б=1кБ) Serial.print(addr); // выводим адрес в послед. порт Serial.print("\t"); // табуляция float f; // переменная для хранения значений типа float EEPROM.get(addr, f); // получаем значение типа float по адресу addr Serial.print(f, 5); // выводим с точностью 5 знаков после запятой Serial.print("\t"); // табуляция char c; // переменная для хранения массива из 20 символов EEPROM.get(addr, c); // считываем массив символов по адресу addr Serial.println(c); // выводим массив в порт } delay(60000); // ждём 1 минуту }

Example No. 5

Using EEPROM as an array.

#include void setup() ( EEPROM = 11; // write the 1st cell EEPROM = 121; // write the 2nd cell EEPROM = 141; // write the 3rd cell EEPROM = 236; // write the 4th cell Serial .begin(9600); ) void loop() ( for (int addr=0; addr<1024; addr++) { Serial.print(addr); Serial.print("\t"); int n = EEPROM; // считываем ячейку по адресу addr Serial.println(n); // выводим в порт } delay(60000); }

Working with EEPROM

As mentioned earlier, EEPROM memory is limited. To extend the service life of non-volatile memory, instead of the write() function, it is better to use the update function. In this case, rewriting is carried out only for those cells where the value differs from the newly written one.

Another useful function of the microcontroller memory in question is the ability to use byte storage cells as parts of an integral EEPROM array. In any format of use, it is necessary to constantly monitor the integrity of the recorded data.

Such memory on Arduino standardly stores the most important things for the operation of the controller and device. For example, if a temperature controller is created on such a basis and the initial data turns out to be erroneous, the device will operate “inadequately” to the existing conditions - it will greatly underestimate or overestimate the temperature.

There are several situations where the EEPROM contains incorrect data:

  1. Upon initial activation, there were no entries yet.
  2. During an uncontrolled power outage, some or all of the data will not be recorded or will be recorded incorrectly.
  3. After completion of possible data rewrite cycles.

To avoid unpleasant consequences, the device can be programmed for several action options: apply emergency code data, turn off the system completely, signal a malfunction, use a previously created copy, or others.

To control the integrity of information, a system control code is used. It is created based on the original data recording and, when verified, it recalculates the data. If the result is different, it is an error. The most common version of such a check is a checksum - a simple mathematical operation is performed to add all cell values.

Experienced programmers add an additional "exclusive OR" to this code, such as E5h. If all values ​​are equal to zero, and the system mistakenly reset the original data, this trick will reveal the error.

These are the basic principles of working with non-volatile EEPROM memory for Arduino microcontrollers. For certain projects it is worth using only this type of memory. It has both its advantages and disadvantages. To master writing and reading methods, it is better to start with simple tasks.

All microcontrollers of the Mega family include non-volatile memory ( EEPROM memory). The volume of this memory ranges from 512 bytes in ATmega8x models to 4 KB in older models. EEPROM memory is located in its own address space and, like RAM, is organized linearly. To work with EEPROM The memory uses three I/O registers: an address register, a data register, and a control register.

Address register

Address register EEPROM memory EEAR (EEPROM Address Register) physically located in two RVV EEARH:EEARL, located along
addresses $1F ($3F) and $1E ($3E), respectively. This register is loaded with the address of the cell that will be accessed. The address register is both writable and readable. At the same time, in the register EEARH only the least significant bits are used (the number of bits involved depends on the volume EEPROM memory). Unused register bits EEARH are read-only and contain "0".

Data register

Data register EEPROM memory EEDR (EEPROM Data Register) located at $1D ($3D). When writing to this register, data is loaded that should be placed in EEPROM, and when reading, the data read from EEPROM.

Control register

Control register EEPROM memory EECR (EEPROM Control Register) located at $1C ($3C). This register is used for
access control EEPROM memory. Its description is shown in the table below:

Discharge Name Description
7..4 - not used, read as "0"
3 EERIE Enable interrupt from EEPROM. This bit controls the generation of an interrupt that occurs when the EEPROM write cycle is completed. If this bit is set to "1", interrupts are enabled (if the I flag of the register
SREG is also set to "1"). When the EEWE bit is cleared (see further in
table) the interrupt is generated constantly
2 EEMWE Controlling write permission in EEPROM. The state of this bit determines the operation of the EEWE write enable flag. If this bit is set to “1”, then when writing to the EEWE bit “1”, data is written to the EEPROM. Otherwise, setting EEWE to "1" has no effect. After software installation, the EEMWE bit is reset by hardware via
4 machine cycles
1 EEWE Allow writing to EEPROM. When this bit is set to “1”, data is written to EEPROM (if EEMWE is equal to “1”)
0 EERE Read permission from EEPROM. After setting this bit to “1”, data is read from the EEPROM. Upon completion of reading, this bit is reset by hardware

To write one byte to EEPROM you need:

1. Wait until the EEPROM is ready to write data (wait until the EEWE flag of the EECR register is reset).

2. Wait for the completion of writing to the FLASH program memory (wait until the SPMEN flag of the SPMCR register is reset).

3. Load the data byte into the EEDR register and the required address into the EEAR register (if necessary).

4. Set the EEMWE flag of the EECR register to “1”.

5. Write log to the EEWE bit of the EECR register. "1" for 4 machine cycles. After installing this bit, the processor
skips 2 machine cycles before executing the next instruction.

To read one byte from EEPROM you need:

1. Check the state of the EEWE flag. The fact is that while a write operation is being performed in EEPROM memory (EEWE flag is set), neither reading EEPROM memory nor changing the address register can be performed.

2. Load the required address into the EEAR register.

3. Set the EERE bit of the EECR register to “1”.

When the requested data is placed in the EEDR data register, a hardware reset of this bit will occur. However, it is not necessary to monitor the state of the EERE bit to determine when a read operation is completed, since a read operation from EEPROM is always completed in one machine cycle. In addition, after setting the EERE bit to "1", the processor skips 4 machine cycles before starting the next instruction.

The AVR Studio GCC environment has a standard library for working with EEPROM, which is enabled by connecting the file . The main functions are eeprom_read_byte(), eeprom_write_byte(), eeprom_read_word(), eeprom_write_word(). For example, let's write a program for a mini-counter from 0 to 9, where when you press one button, a value will be added, and another button will store this value in memory. The Atmega8 microcontroller operates from an internal clock generator with a frequency of 8 MHz. A single-digit seven-segment indicator with a common anode is connected to port B through current-limiting resistors R1-R7, the common anode is connected to the power supply plus. The diagram is shown below:

First, we connect the libraries necessary for operation, including EEPROM. Define variables. The variable "s" stores the value for display on the indicator; when you press the SB1 button, this value increases by one, but not more than 10. The eeprom_var variable will interact with the EEPROM. When the power is turned on, the EEPROM is read, the read data is assigned to the variable “s”, based on this, a certain number is displayed on the indicator. When you press SB2, the data from the variable “s” is written to the EEPROM, and the indicator blinks once.

#include #include #include #define d0 ~(0x3F) // 0 #define d1 ~(0x06) // 1 #define d2 ~(0x5B) // 2 #define d3 ~(0x4F) // 3 #define d4 ~(0x66) // 4 #define d5 ~(0x6D) // 5 #define d6 ~(0x7D) // 6 #define d7 ~(0x07) // 7 #define d8 ~(0x7F) // 8 #define d9 ~(0x6F) // 9 unsigned char s; unsigned char eeprom_var EEMEM; // define a variable in EEPROM int main (void) ( DDRB = 0xFF; // Port B to output PORTB = 0xFF; DDRD = 0x00; // Port D to input PORTD = 0xFF; // Turn on pull-up resistors s = eeprom_read_byte(&eeprom_var ); // read a byte from EEPROM and put it in "s" while(1) ( if((PIND&(1<< PD0)) == 0) // если кнопка SB1 нажата { while((PIND&(1 << PD0)) == 0){} // ждем отпускания кнопки s++; // увеличиваем "s" на единицу _delay_ms(200); } if(s == 10) // Когда дойдет до 10 обнуляем "s" { s = 0; } if((PIND&(1 << PD1)) == 0) // если кнопка SB2 нажата { while((PIND&(1 << PD1)) == 0){} // ждем отпускания кнопки DDRB = 0xFF; // мигаем индикатором _delay_ms(200); DDRB = 0x00; _delay_ms(200); DDRB = 0xFF; eeprom_write_byte(&eeprom_var, s); // записываем "s" в EEPROM _delay_ms(200); } if(s==0) // Выводим цифры на индикатор PORTB = d0; if(s==1) PORTB = d1; if(s==2) PORTB = d2; if(s==3) PORTB = d3; if(s==4) PORTB = d4; if(s==5) PORTB = d5; if(s==6) PORTB = d6; if(s==7) PORTB = d7; if(s==8) PORTB = d8; if(s==9) PORTB = d9; } }

Comments

0 AntonChip 05/02/2013 22:15

I quote Max:

Maybe I'm confusing something, but if you have an indicator with OA, then one resistor on the 5V line is enough. Why install current-limiting resistors after the element that they are supposed to protect from high current??


Just imagine what will happen if one segment of the indicator closes with this and another resistor connection scheme.

0 AntonChip 05/15/2013 11:16

I quote gydok:

How to write a two-dimensional array to eeprom?


Code:
#include // Include the library

EEMEM unsigned char colors=((1, 2, 3), // Declare an array in EEPROM
{4, 5, 6}};

eeprom_write_byte(&colors, 1); // Write array elements to EEPROM
eeprom_write_byte(&colors, 2);
eeprom_write_byte(&colors, 3);
eeprom_write_byte(&colors, 4);
eeprom_write_byte(&colors, 5);
eeprom_write_byte(&colors, 6);

unsigned char temp;
temp = eeprom_read_byte(&colors); // Extract array element from EEPROM, 2nd row(), 1st column(), i.e. number 4

Resetting EEPROM memory

The example loops through all memory cells and writes zeros to them.

// Connecting the library to work with EEPROM. #include "EEPROM.h" void setup() ( // Go through all cells (bytes) and write zeros to them. for (int i = 0; i< EEPROM.length(); i++) EEPROM.update(i, 0); } void loop() { // Пустой цикл... }


Factory reset

If you want to return the memory to factory settings, you need to replace 0 with 255, i.e. write not zeros, but the number 255. Thus, in the future, using the isNaN() function, it is possible to check whether the write to the EEPROM memory was made or not.

// Connecting the library to work with EEPROM. #include "EEPROM.h" void setup() ( // Go through all cells (bytes) and write numbers 255 in them. for (int i = 0; i< EEPROM.length(); i++) EEPROM.update(i, 255); } void loop() { // Пустой цикл... }

Tell us about us

Message

If you have experience working with Arduino and actually have time for creativity, we invite everyone to become authors of articles published on our portal. These can be either lessons or stories about your experiments with Arduino. Description of various sensors and modules. Tips and instructions for beginners. Write and post your articles on