Keywordcode
co
2. IAR for AVR (excerpt)
Specific operation methods of common types of FLASH
(1) FLASH area data storage.
Use the keyword __flash to control storage. The effect of writing the __flash keyword before and after the data type is the same
__flash unsigned char a; // define a variable to be stored in the flash space
unsigned char __flash a; // the effect is the same as above
__flash unsigned char p[]; // define an array to be stored in the flash space
The read operation of the variable in the flash space is the same as the operation method of the SRAM data space. The compiler will automatically use
LPM and ELPM instructions to operate.
Example:
#i nclude
__flash unsigned char p[];
__flash unsigned char a;
void main(void)
{PORTB=p[1];// read the operation of flash array variables
PORTB=a;// read the operation of flash variables
}
Since the flash space is read-only in normal programs, variables without values are meaningless. To define constants in the flash space, just assign initial values to the variables. Since the addresses of constants in the flash space are randomly assigned, the constant values can be read by reading the variables.
IAR-AVR - C Compiler Brief Guide
__flash unsigned char a="9";// define a constant to be stored in the flash space.
__flash unsigned char p[]={1, 2, 3, 4, 5, 6, 7, 8};
// define a group of constants to be stored in the flash space.
Example:
#i nclude
__flash unsigned char p[]={1,2,3,4,5,6,7,8};
__flash unsigned char a="9";
void main(void)
{
PORTB="a";//read flash space value 9
PORTC="p"[0]; //read flash space value
}
(2) Flash space absolute address positioning:
__flash unsigned char a @ 0x8; // define variables and store them in flash space 0X08 unit __flash unsigned char p[] @ 0x22 // define arrays and store them in flash space, starting at address 0X22 unit
__flash unsigned char a @ 0x08=9; // define constants and store them in flash space 0X08 unit
__flash unsigned char p[] @ 0x22={1, 2, 3, 4, 5, 6, 7, 8};
// define a group of constants and store them in EEPROM space starting at address 0X22 unit
Since the addresses of constants in flash space are already allocated, variables and addresses can be used to read flash space values.
(3) Pointer operations related to __flash. The __flash keyword controls the storage and type of the pointer.
SRAM pointer to flash space (control type attribute)
unsigned char __flash * p; //Defines a pointer to the flash space address, 8 bits.
unsigned int __flash * p; //Defines a pointer to the flash space address, 16 bits.
unsigned int __farflash * p; //Defines a pointer to the flash space address, 24 bits.
unsigned int __hugeflash * p; //Defines a pointer to the flash space address, 24 bits.
unsigned char __flash * p; //Defines a pointer to the flash space address, the pointer itself is stored in SRAM. The value of P represents a certain address in the flash space. *p indicates the content stored in the address unit of the flash space. Example: Assume p=10, indicating the flash space address is 10 units, and the content of flash space 10 units is read using *p.
Example:
#include
char __flash t @ 0x10 ;
char __flash *p ;
void main(void)
{
PORTB=*p; //Read the value of flash space 10 unit
PORTB=*(p+3); //Read the value of flash space 0x13 unit
}
Pointer data stored in flash space
Just like the data stored in flash space, it controls the storage attribute
__flash unsigned char * p; //Define the pointer pointing to the SARMM space address, and the pointer itself is stored in flash.
The __flash definition for control data and pointer storage must be a global variable, and the control type attribute (it seems only the pointer) can be a local variable
.
__flash unsigned char p; //control storage
void main(void)
{
unsigned char __flash * t; //control attribute
PORTB=p;
PORTB=*t;
}
(4) The __root keyword ensures that unused functions or variables can also be included in the target code.
The data defined in the __flash space will automatically generate code and embed it into the flash code when the program is compiled. For data that is not used by the program but requires compilation (for example, you can embed your version number, time, etc. in the code), the keyword __root must be added to restrict it.
Example:
#include
__root __flash unsigned char p @ 0x10 =0x56;
void main(void)
{}
The program does not use the P variable, but the compilation will also generate this code.
:020000020000FC
:1000000016C018951895189518951895189518955F
:10001000569518951895189518951895189518953A
:1000200018951895189508 9500008895FECF0FE94A
:100030000DBF00E00EBFC0E8D0E003D0F4DFF4DF76
:06004000F3CF01E008957A
:0400000300000000F9
:00000001FF
(5) Flash operation macro function: Detailed description in comp_a90.h intrinsics.h header file. Flash space has read-only performance under normal circumstances. For reading flash data, the compiler will automatically compile the corresponding LPM and ELPM instructions. However, there is no corresponding C instruction for the self-programming write command SPM of flash space. The detailed self-programming method is not explained here, but only the read and write functions of flash are explained.
Read the flash space address data directly in the program: include the intrinsics.h header file
__load_program_memory(const unsigned char __flash *); //64K space
//Read data from the specified flash space address. This function is detailed in the intrinsics.h header file.
Its simplified writing _LPM(ADDR) is in the comp_a90.h file. Note that the Z in the assembly instruction LPM Rd, Z is a pointer. So use (const unsigned char __flash *) to force conversion to a pointer to the flash space address. Therefore, the correct way to write this macro function should be as follows:
__load_program_memory((const unsigned char __flash *)ADDR);
Example:
#i nclude
#include
void main(void)
{PORTB=__load_program_memory((const unsigned char __flash *)0x12);
}
This function is not easy to write. It is simplified in the comp_a90.h file:
#define _LPM(ADDR) __load_program_memory (ADDR) is a little more convenient. It is more convenient to change it to
#define _LPM(ADDR) __load_program_memory ((const unsigned char
__flash *)ADDR). You can use the data directly.
Example:
#i nclude
#include
#include
void main(void)
{
PORTB=__LPM(0x12); // Read data from the specified flash space address unit 0x12
}
__extended_load_program_memory(const unsigned char __farflash *);
//128K space_ELPM(ADDR); //128K space
Refer to the above understanding and modification to make writing simpler.
(6) Self-programming function:
_SPM_GET_LOCKBITS();//Read lock bit
_SPM_GET_FUSEBITS();//Read fuse bit
_SPM_ERASE(Addr);//16-bit page erase
_SPM_FILLTEMP(Addr,Word);//16-bit page buffer
_SPM_PAGEWRITE(Addr;)//16-bit page write
_SPM_24_ERASE(Addr); //24-bit page erase
_SPM_24_FILLTEMP(Addr,
_SPM_24_PAGEWRITE(Addr) //24-bit page write
3. AVR GCC for AVR
AVR has three types of memory: FLASH, SRAM and EEPROM. AVR-GCC puts program code in FLASH and data in SRAM.
(1) Program memory
If you want to put data (such as constants, strings, etc.) in FLASH, the user needs to specify the data type __attribute__((progmem)). For ease of use, AVR-GCC defines some more intuitive symbols, as shown in the following table. Included in the header file pgmspace.h
#include
Type definition
prog_void void __attribute__((progmem))
prog_char char __attribute__((progmem))
prog_int int __attribute__((progmem))
prog_long long __attribute__((progmem))
prog_long_long long long __attribute__((progmem))
PGM_P const prog_char *
PGM_VOID_P prog_void cons t *
example code
const char NumberCode[12] PROGMEM ={'K','e','y', ' ' , ' ' , ' ' ,'N','u','m','b','e', 'r'};
PGM_P pstr="NumberCode"; //The data type of FLASH memory is char, pstr is a pointer to FLASH, and its value is 16 bits
pgm_read_byte(pstr++) //Read data in FLASH, pstr content is FLASH 16 address The
provided library functions are:
1. __elpm_inline
Usage: uint8_t __elpm_inline(uint32_t addr);
Description: Execute ELPM instruction to get data from FLASH. The parameter is a 32-bit address and returns an 8-bit data.
2. __lpm_inline
Usage: uint8_t __elpm_inline(uint16_t addr);
Description: Execute LPM instruction to get data from FLASH. The parameter is a 16-bit address and returns an 8-bit data.
3. memcpy_P
Usage: void* memcpy_P(void* dst, PGM_VOID_P src, size_t n);
Description: A special version of memcpy. Complete the task of getting n bytes from FLASH.
4. PRG_RDB
Usage: uint8_t PGR_RDB(uint16_t addr);
Description: This function simply calls __lpm_inline
5. PSTR
Usage: PSTR(s);
Description: The parameter is a string. The function is to put it in FLASH and return the address.
6. strcmp_P
Usage: int strcmp(char const*, PGM_P);
Description: The function is similar to strcmp(). The second parameter points to the string in program memory.
7. strcpy_P
Usage: char* strcpy_P(char*, PGM_P);
Description: The function is similar to strcpy(). The second parameter points to the string in program memory.
8. strlen_P
Usage: size_t strlen_P(PGM_P);
Description: The function is similar to strlen(). The second parameter points to the string in program memory.
9. strncmp_P
Usage: size_t strncmp_P(char const*, PGM_P, size_t);
Description: The function is similar to strncmp(). The second parameter points to the string in the program memory.
10. strncpy_P
Usage: size_t strncpy_P(char*, PGM_P, size_t);
Description: The function is similar to strncpy(). The second parameter points to the string in the program memory.
(2) EEPROM
There is EEPROM inside AVR, but the address space is different from that of SRAM. It must be accessed through I/O registers. EEPROM API encapsulates these functions and provides users with a high-level interface. When using it, include eeprom.h. An example of defining EEPROM data in a program is as follows:
static uint8_t variable_x __attribute__((section(".eeprom"))) = 0;
Different AVR devices have different numbers of EEPROMs. The linker will allocate memory space for different devices.
1. eeprom_is_ready
Usage: int eeprom_is_ready(void);
Description: This function is used to indicate whether the EEPROM can be accessed. If the EEPROM is performing a write operation, it cannot be accessed within 4ms. This function queries the corresponding status bit to indicate whether the EEPROM can be accessed now.
2. eeprom_rb
Usage: uint8_t eeprom_rb(uint16_t addr);
Description: Read a byte of content from the EEPROM. The parameter addr is used to indicate the address to be read. _EEGET(addr) calls this function.
3. Eeprom_read_block
Usage: void eeprom_read_block(void* buf, uint16_t addr, size_t n);
Description: Read the contents of a block of EEROM. The parameter addr is the starting address, and n indicates the number of bytes to be read. The data is read into the buf of the SRAM.
4. eeprom_rw
Usage: unint16_t eeprom_rw(uint16_t addr);
Description: Read a 16-bit data from the EEPROM. The low byte is the low 8 bits, and the high byte is the high 8 bits. The parameter addr is the address.
5. eeprom_wb
Usage: void eeprom_wb(uint16_t addr, uint8_t val);
Description: Write the 8-bit data val to the EEPROM memory at address addr. _EEPUT(addr, val) calls this function.
Previous article:ICCAVR bit operation macro definition
Next article:Some opinions on AVR microcontroller bit operation
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- 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
- Molex leverages SAP solutions to drive smart supply chain collaboration
- Pickering Launches New Future-Proof PXIe Single-Slot Controller for High-Performance Test and Measurement Applications
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- ASML predicts that its revenue in 2030 will exceed 457 billion yuan! Gross profit margin 56-60%
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- MSP430F5529 general I/O port settings
- 5 production processes that must be considered before PCB layout
- Selling Zedboard Zynq7020 development board
- I have to say that the old technology I have been exposed to since 2008 was still blocked at that time.
- Calibration of medical devices
- Doesn't high input impedance mean high loss? Why does sampling require high input impedance? Low output impedance, such as running...
- How to set the prohibited routing area when AD wiring
- [Mill Edge AI Computing Box FZ5 Review] Object Detection Demo
- What serial port is UART?
- Read the good book "Operational Amplifier Parameter Analysis and LTspice Application Simulation" 01 LTspice Installation and Example Run