***************************************************
**** AVR internal EEPROM read and write examples ***
**** Compiler: WINAVR20050214 ***
**** ***
**** www.OurAVR.com 2005.9.24 ***
***********************************************/
/*
This program simply demonstrates how to use the EEPOM of ATMEGA16.
Introduction to EEPROM
. Write operation of EEPROM.
Read operation of EEPROM.
In order to simplify the program, various data are not output to the outside. It is recommended to use JTAG ICE hardware emulator when learning.
After opening the debug file to JTAG,
open the Debug -> JTAG ICE Options menu,
then click the Dbug page in JTAG ICE Properties and select the preserve eeprom option.
During each simulation and debugging, the EEPROM content is protected.
Otherwise, the EEPROM content will be erased according to the default settings.
Since EEPROM variables are defined, JTAG debugging will ask whether to initialize EEPROM, please select [No]
EEPROM data can also be viewed in view->memory, select Eeprom window
*/
#i nclude
#i nclude
////The clock is set to internal 1MHz, F_CPU=1000000 The clock frequency has little effect on the operation of the program
/*
GCCAVR (avr-libc) comes with EEPROM read and write functions.
The following lists some commonly used functions (prototypes)
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
Check whether EEPROM is ready. OK returns 1 (return EEWE bit)
#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
Wait for EEPROM operation to complete
extern uint8_t eeprom_read_byte (const uint8_t *addr);
Read a byte of 8-bit EEPROM data at the specified address
extern uint16_t eeprom_read_word (const uint16_t *addr);
Read a word of 16-bit EEPROM data at the specified address
extern void eeprom_read_block (void *buf, const void *addr, size_t n);
Read EEPROM data of a specified length starting from the specified address
extern void eeprom_write_byte (uint8_t *addr, uint8_t val);
Write a byte of 8-bit EEPROM data to the specified address
extern void eeprom_write_word (uint16_t *addr, uint16_t val);
write a word of 16-bit EEPROM data to the specified address
extern void eeprom_write_block (const void *buf, void *addr, size_t n);
write EEPROM data of a specified length starting from the specified address
But some AVRs are not supported. The original text is as follows:
\note This library will \e not work with the following devices since these
devices have the EEPROM IO ports at different locations:
- AT90CAN128
- ATmega48
- ATmega88
- ATmega165
- ATmega168
- ATmega169
- ATmega325
- ATmega3250 - ATmega645 - ATmega6450
* / /* There are two ways to operate EEPROM in the program . Method 1: directly specify the EEPROM address, that is, the address of the read and write functions is specified by yourself, which is used in applications that require a specific data arrangement format. Method 2: define the EEPROM area variable method first. In this way, the variable is in the EEPROM The specific address in the memory is automatically assigned by the compiler. Compared with method 1, the specific location of the data in the EEPROM is opaque. The initial value assigned to the EEPROM variable is assigned to the .eeprom segment during compilation. The avr-objcopy tool can be used to extract it from the .elf file and generate a file in ihex or binary format, so that it can be written to the device's EEPROM using a programmer or download cable. In fact, the MAKEFILE generated by MFILE in WINAVR has done all this for us. It will automatically generate a file with the suffix ".eep", usually in iHex format (this test found that the allocated address starts from 0x0000, so an EEPROM variable Evalvoid [16] was added)
If you use methods 1 and 2 at the same time, please pay attention to prevent address overlap. The address you specify should be selected at the end.
*/
//Global variables
unsigned char EDATA;
unsigned char ORGDATA【16】={0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
0x01,0x03,0x05,0x07,0x09,0x0B,0x0D,0x0F}; //Original data
unsigned char CMPDATA【16】; //Comparison data
// During simulation, monitor these global variables in the watch window.
//EEPROM variable definition
unsigned char Evalvoid【16】 __attribute__((section(".eeprom"))); //This is not used
unsigned char Eval【16】 __attribute__((section(".eeprom")));
int main(void)
{
eeprom_write_byte (0x40,0xA5); //Write data 0xA5 to address 0x40 of EEPROM
EDATA=eeprom_read_byte (0x40); //Read out and see if the data is correct?
//The above two sentences will have the following warnings when compiled, but you don't need to pay attention to them.
//EEPROM_main.c:103: warning: passing arg 1 of `eeprom_write_byte
' makes pointer from integer without a cast //EEPROM_main.c:104: warning: passing arg 1 of `eeprom_read_byte' makes pointer from integer without a cast
eeprom_write_block (&ORGDATA【0】, &Eval【0】, 16); //Block writing
//To see if the EEPROM data can be permanently saved after power failure, you can comment out the above program (not writing, just reading), then compile, burn, power off (for a while), power on, and debug.
eeprom_read_block (&CMPDATA【0】,&Eval【0】, 16); //Block reading, then see if the data is correct?
while (1);
}
/*
ATmega16 contains 512 bytes of EEPROM data storage.
It exists as an independent data space and can be read and written byte by byte.
The life of EEPROM is at least 100,000 erase cycles.
EEPROM access is determined by the address register EEAR, the data register EEDR and the control register EECR.
EEPROM data can also be solidified through ISP, JTAG and parallel cables .
Reading EEPROM data:
After the EEPROM address is set, EERE needs to be set to read the data into EEDR.
Reading EEPROM data requires an instruction and no waiting is required.
After reading EEPROM, the CPU must stop for 4 clock cycles before executing the next instruction.
Note: Users should check EEWE when reading EEPROM. If a write operation is in progress, the EEPROM cannot be read and the register EEAR cannot be changed.
Writing EEPROM data:
1 EEPROM write access time (self-timing time, programming time)
The self-timing function allows the user software to monitor when it can start writing the next byte. (Interrupt mode can be used)
The calibrated 1MHz on-chip oscillator is used for EEPROM timing, independent of the setting of the CKSEL fuse bit.
Changing the value of the OSCCAL register affects the frequency of the internal RC oscillator and thus the time to write to the EEPROM.
The EEPROM self-timing time is about 8.5 ms, which is 8448 cycles of the 1MHz on-chip oscillator.
Note: This time is hardware-timing, and the value is relatively safe. In fact, the actual writing time is not as long as 8.5mS, and it is related to the voltage, but the chip does not provide other methods to detect the completion of programming.
This problem is manifested in the old version of the AT90S series. Because there is no self-timing, the value is set too short, and ATMEL has been complained to the head, haha! Reference: Improvements in the writing of EEPROM timing
in the document "Replacing AT90S8535 with ATmega8535" The time to write EEPROM in AT90S8535 depends on the supply voltage, usually 2.5ms@VCC=5V, 4ms@VCC=2.7V. The time to write EEPROM in ATmega8535 is 8448 calibrated RC oscillator cycles (regardless of the clock source and frequency of the system clock). Assuming a calibrated RC oscillator of 1.0MHz, the typical write time is 8.4ms, independent of VCC. 2 To prevent unintentional EEPROM write operations, a specific write sequence needs to be executed (if you use the compiler's built-in function, you don't have to worry about it yourself) . The write sequence is as follows (the order of steps 3 and 4 is not important): 1. Wait for the EEWE bit to become zero 2. Wait for the SPMEN bit in the SPMCSR to become zero 3. Write the new EEPROM address to EEAR (optional) 4. Write the new EEPROM data to EEDR (optional) 5. Write "1" to EEMWE in the EECR register and clear EEWE at the same time 6. Within 4 cycles of setting EEMWE, EEWE is cleared by hardware after the write access time is passed after setting EEWE. The user can use this bit to determine whether the write sequence has been completed. After EEWE is set, the CPU will stop for two clock cycles before running the next instruction. Note:
1: The EEPROM cannot be programmed while the CPU is writing to the Flash memory.
The software must check whether the Flash write operation has been completed before starting the EEPROM write operation
. Step (2) is only useful if the software contains a bootloader and allows the CPU to program the Flash.
If the CPU will never write to the Flash, step (2) can be omitted.
2: If an interrupt occurs between steps 5 and 6, the write operation will fail.
This is because the EEPROM write enable operation will time out.
If an interrupt to an EEPROM operation interrupts another EEPROM operation, the EEAR or EEDR registers may be modified, causing the EEPROM operation to fail.
It is recommended to turn off the global interrupt flag I at this time.
After the write access time, EEWE is cleared by hardware. The user can use this bit to determine whether the write timing has been completed.
After EEWE is set, the CPU will stop for two clock cycles before running the next instruction. If
the EEPROM write operation
is in progress when the program executes the power-down instruction, the EEPROM write operation will continue and be completed before the specified write access time.
However, after the write operation is completed, the oscillator will continue to run, and the microcontroller is not in a complete power-down mode. Therefore, the EEPROM write operation should be terminated before the power-down instruction is executed.
Prevent EEPROM data loss
If the power supply voltage is too low, the CPU and EEPROM may not work properly, causing the EEPROM data to be destroyed (lost).
** This situation will also be encountered when using independent EEPROM devices. Therefore, the same protection scheme needs to be used.
There are two possibilities for EEPROM data corruption due to low voltage:
one is that the voltage is lower than the minimum voltage required for EEPROM write operation;
the other is that the CPU itself can no longer work properly.
The problem of EEPROM data corruption can be solved by the following method:
Keep the AVR RESET signal low when the voltage is too low.
This can be achieved by enabling the chip's power-down detection circuit BOD. If the BOD level cannot meet the requirements, an external reset circuit can be used.
If a reset occurs during the write operation, the write operation will still end normally as long as the voltage is high enough.
(EEPROM can also perform write operations at a low voltage of 2V - there are AVR chips that can work at 1.8V)
Misunderstanding of power-off detection BOD
The BOD (Brown-out Detection) circuit built into the AVR is used to generate a reset signal when the voltage is too low (lower than the set value) to prevent the CPU from accidentally operating.
The protection of the EEPROM is to keep the RESET signal low when the voltage is too low, preventing the CPU from accidentally operating and erroneously modifying the contents of the EEPROM
. The power-off detection function we understand refers to a function with predictive function that can be processed by software.
For example, if the user wants to transfer the SRAM data to the EEPROM when the power is off, a feasible method is to
connect an external voltage comparator (VCC=5.0V, BOD=2.7V) that flips at 4.5V, and connect the output to the external interrupt pin (or other interrupt).
Once the voltage is lower than 4.5V, the interrupt is triggered immediately, and the data is written to the EEPROM in the interrupt service program for protection.
Note: It takes up to 8mS to write a byte of EEPROM, so do not write too much data, and the power supply filter capacitor should also be larger
*/
Keywords:AVR
Reference address:AVR internal EEPROM read and write example
**** AVR internal EEPROM read and write examples ***
**** Compiler: WINAVR20050214 ***
**** ***
**** www.OurAVR.com 2005.9.24 ***
***********************************************/
/*
This program simply demonstrates how to use the EEPOM of ATMEGA16.
Introduction to EEPROM
. Write operation of EEPROM.
Read operation of EEPROM.
In order to simplify the program, various data are not output to the outside. It is recommended to use JTAG ICE hardware emulator when learning.
After opening the debug file to JTAG,
open the Debug -> JTAG ICE Options menu,
then click the Dbug page in JTAG ICE Properties and select the preserve eeprom option.
During each simulation and debugging, the EEPROM content is protected.
Otherwise, the EEPROM content will be erased according to the default settings.
Since EEPROM variables are defined, JTAG debugging will ask whether to initialize EEPROM, please select [No]
EEPROM data can also be viewed in view->memory, select Eeprom window
*/
#i nclude
#i nclude
////The clock is set to internal 1MHz, F_CPU=1000000 The clock frequency has little effect on the operation of the program
/*
GCCAVR (avr-libc) comes with EEPROM read and write functions.
The following lists some commonly used functions (prototypes)
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
Check whether EEPROM is ready. OK returns 1 (return EEWE bit)
#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
Wait for EEPROM operation to complete
extern uint8_t eeprom_read_byte (const uint8_t *addr);
Read a byte of 8-bit EEPROM data at the specified address
extern uint16_t eeprom_read_word (const uint16_t *addr);
Read a word of 16-bit EEPROM data at the specified address
extern void eeprom_read_block (void *buf, const void *addr, size_t n);
Read EEPROM data of a specified length starting from the specified address
extern void eeprom_write_byte (uint8_t *addr, uint8_t val);
Write a byte of 8-bit EEPROM data to the specified address
extern void eeprom_write_word (uint16_t *addr, uint16_t val);
write a word of 16-bit EEPROM data to the specified address
extern void eeprom_write_block (const void *buf, void *addr, size_t n);
write EEPROM data of a specified length starting from the specified address
But some AVRs are not supported. The original text is as follows:
\note This library will \e not work with the following devices since these
devices have the EEPROM IO ports at different locations:
- AT90CAN128
- ATmega48
- ATmega88
- ATmega165
- ATmega168
- ATmega169
- ATmega325
- ATmega3250 - ATmega645 - ATmega6450
* / /* There are two ways to operate EEPROM in the program . Method 1: directly specify the EEPROM address, that is, the address of the read and write functions is specified by yourself, which is used in applications that require a specific data arrangement format. Method 2: define the EEPROM area variable method first. In this way, the variable is in the EEPROM The specific address in the memory is automatically assigned by the compiler. Compared with method 1, the specific location of the data in the EEPROM is opaque. The initial value assigned to the EEPROM variable is assigned to the .eeprom segment during compilation. The avr-objcopy tool can be used to extract it from the .elf file and generate a file in ihex or binary format, so that it can be written to the device's EEPROM using a programmer or download cable. In fact, the MAKEFILE generated by MFILE in WINAVR has done all this for us. It will automatically generate a file with the suffix ".eep", usually in iHex format (this test found that the allocated address starts from 0x0000, so an EEPROM variable Evalvoid [16] was added)
If you use methods 1 and 2 at the same time, please pay attention to prevent address overlap. The address you specify should be selected at the end.
*/
//Global variables
unsigned char EDATA;
unsigned char ORGDATA【16】={0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
0x01,0x03,0x05,0x07,0x09,0x0B,0x0D,0x0F}; //Original data
unsigned char CMPDATA【16】; //Comparison data
// During simulation, monitor these global variables in the watch window.
//EEPROM variable definition
unsigned char Evalvoid【16】 __attribute__((section(".eeprom"))); //This is not used
unsigned char Eval【16】 __attribute__((section(".eeprom")));
int main(void)
{
eeprom_write_byte (0x40,0xA5); //Write data 0xA5 to address 0x40 of EEPROM
EDATA=eeprom_read_byte (0x40); //Read out and see if the data is correct?
//The above two sentences will have the following warnings when compiled, but you don't need to pay attention to them.
//EEPROM_main.c:103: warning: passing arg 1 of `eeprom_write_byte
' makes pointer from integer without a cast //EEPROM_main.c:104: warning: passing arg 1 of `eeprom_read_byte' makes pointer from integer without a cast
eeprom_write_block (&ORGDATA【0】, &Eval【0】, 16); //Block writing
//To see if the EEPROM data can be permanently saved after power failure, you can comment out the above program (not writing, just reading), then compile, burn, power off (for a while), power on, and debug.
eeprom_read_block (&CMPDATA【0】,&Eval【0】, 16); //Block reading, then see if the data is correct?
while (1);
}
/*
ATmega16 contains 512 bytes of EEPROM data storage.
It exists as an independent data space and can be read and written byte by byte.
The life of EEPROM is at least 100,000 erase cycles.
EEPROM access is determined by the address register EEAR, the data register EEDR and the control register EECR.
EEPROM data can also be solidified through ISP, JTAG and parallel cables .
Reading EEPROM data:
After the EEPROM address is set, EERE needs to be set to read the data into EEDR.
Reading EEPROM data requires an instruction and no waiting is required.
After reading EEPROM, the CPU must stop for 4 clock cycles before executing the next instruction.
Note: Users should check EEWE when reading EEPROM. If a write operation is in progress, the EEPROM cannot be read and the register EEAR cannot be changed.
Writing EEPROM data:
1 EEPROM write access time (self-timing time, programming time)
The self-timing function allows the user software to monitor when it can start writing the next byte. (Interrupt mode can be used)
The calibrated 1MHz on-chip oscillator is used for EEPROM timing, independent of the setting of the CKSEL fuse bit.
Changing the value of the OSCCAL register affects the frequency of the internal RC oscillator and thus the time to write to the EEPROM.
The EEPROM self-timing time is about 8.5 ms, which is 8448 cycles of the 1MHz on-chip oscillator.
Note: This time is hardware-timing, and the value is relatively safe. In fact, the actual writing time is not as long as 8.5mS, and it is related to the voltage, but the chip does not provide other methods to detect the completion of programming.
This problem is manifested in the old version of the AT90S series. Because there is no self-timing, the value is set too short, and ATMEL has been complained to the head, haha! Reference: Improvements in the writing of EEPROM timing
in the document "Replacing AT90S8535 with ATmega8535" The time to write EEPROM in AT90S8535 depends on the supply voltage, usually 2.5ms@VCC=5V, 4ms@VCC=2.7V. The time to write EEPROM in ATmega8535 is 8448 calibrated RC oscillator cycles (regardless of the clock source and frequency of the system clock). Assuming a calibrated RC oscillator of 1.0MHz, the typical write time is 8.4ms, independent of VCC. 2 To prevent unintentional EEPROM write operations, a specific write sequence needs to be executed (if you use the compiler's built-in function, you don't have to worry about it yourself) . The write sequence is as follows (the order of steps 3 and 4 is not important): 1. Wait for the EEWE bit to become zero 2. Wait for the SPMEN bit in the SPMCSR to become zero 3. Write the new EEPROM address to EEAR (optional) 4. Write the new EEPROM data to EEDR (optional) 5. Write "1" to EEMWE in the EECR register and clear EEWE at the same time 6. Within 4 cycles of setting EEMWE, EEWE is cleared by hardware after the write access time is passed after setting EEWE. The user can use this bit to determine whether the write sequence has been completed. After EEWE is set, the CPU will stop for two clock cycles before running the next instruction. Note:
1: The EEPROM cannot be programmed while the CPU is writing to the Flash memory.
The software must check whether the Flash write operation has been completed before starting the EEPROM write operation
. Step (2) is only useful if the software contains a bootloader and allows the CPU to program the Flash.
If the CPU will never write to the Flash, step (2) can be omitted.
2: If an interrupt occurs between steps 5 and 6, the write operation will fail.
This is because the EEPROM write enable operation will time out.
If an interrupt to an EEPROM operation interrupts another EEPROM operation, the EEAR or EEDR registers may be modified, causing the EEPROM operation to fail.
It is recommended to turn off the global interrupt flag I at this time.
After the write access time, EEWE is cleared by hardware. The user can use this bit to determine whether the write timing has been completed.
After EEWE is set, the CPU will stop for two clock cycles before running the next instruction. If
the EEPROM write operation
is in progress when the program executes the power-down instruction, the EEPROM write operation will continue and be completed before the specified write access time.
However, after the write operation is completed, the oscillator will continue to run, and the microcontroller is not in a complete power-down mode. Therefore, the EEPROM write operation should be terminated before the power-down instruction is executed.
Prevent EEPROM data loss
If the power supply voltage is too low, the CPU and EEPROM may not work properly, causing the EEPROM data to be destroyed (lost).
** This situation will also be encountered when using independent EEPROM devices. Therefore, the same protection scheme needs to be used.
There are two possibilities for EEPROM data corruption due to low voltage:
one is that the voltage is lower than the minimum voltage required for EEPROM write operation;
the other is that the CPU itself can no longer work properly.
The problem of EEPROM data corruption can be solved by the following method:
Keep the AVR RESET signal low when the voltage is too low.
This can be achieved by enabling the chip's power-down detection circuit BOD. If the BOD level cannot meet the requirements, an external reset circuit can be used.
If a reset occurs during the write operation, the write operation will still end normally as long as the voltage is high enough.
(EEPROM can also perform write operations at a low voltage of 2V - there are AVR chips that can work at 1.8V)
Misunderstanding of power-off detection BOD
The BOD (Brown-out Detection) circuit built into the AVR is used to generate a reset signal when the voltage is too low (lower than the set value) to prevent the CPU from accidentally operating.
The protection of the EEPROM is to keep the RESET signal low when the voltage is too low, preventing the CPU from accidentally operating and erroneously modifying the contents of the EEPROM
. The power-off detection function we understand refers to a function with predictive function that can be processed by software.
For example, if the user wants to transfer the SRAM data to the EEPROM when the power is off, a feasible method is to
connect an external voltage comparator (VCC=5.0V, BOD=2.7V) that flips at 4.5V, and connect the output to the external interrupt pin (or other interrupt).
Once the voltage is lower than 4.5V, the interrupt is triggered immediately, and the data is written to the EEPROM in the interrupt service program for protection.
Note: It takes up to 8mS to write a byte of EEPROM, so do not write too much data, and the power supply filter capacitor should also be larger
*/
Previous article:Working principle of AVR timer (counter)
Next article:AVR MCU Getting Started Series (17) AVR IO Input Matrix Key Scanning Program
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
MoreDaily News
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
Guess you like
- 【Ufan Learning】Learning Part 2: "Basic Routine 1 - Three-color LED Control"
- 【ESP32-C3-DevKitM-1】+ Write a placeholder first, and use it after the Micropython firmware library of ESP32-C3 is released
- STM32L051's ADC conversion is inaccurate after wakeup
- A post-00s college student made his own rocket, and millions of netizens watched, with the comments full of high energy!
- TI uses AEC-Q100 Grade-0 digital isolators to overcome high temperature isolation design
- DC-DC output voltage error
- 【GD32E503 Review】 UART Communication Experiment
- DM8148 hardware introduction and MCFW software architecture description
- Huawei architect explains: HarmonyOS low-latency and high-reliability message transmission principle
- MSP430 MCU simulation example 20 based on Proteus - Timer A generates two PWM channels