Method for programming the on-chip flash of LPC2000 series microcontrollers[Copy link]
Each VIC channel supports software interrupts and hardware interrupts, that is, each interrupt can be generated by software or hardware interrupts, and the software interrupt and the hardware interrupt on the corresponding channel are logically "OR" related. Software interrupts can be generated by setting the corresponding bit of the VICSoftInt register, and can also be cleared by setting the corresponding bit of the VICSoftIntClear register. LPC2000 has three types of interrupts: FIQ, vector IRQ and non-vector IRQ. The LPC2000 series can set the above 32 interrupt sources to any of these three types of interrupts by setting the two types of registers VICIntSelect and VICVectCntlx (x=0, 1, ..., 15). Among them, the fast interrupt request FIQ has the highest priority. It is recommended to assign only one interrupt request to FIQ to reduce the delay of the intermediate handler. Of course, VIC supports multiple FIQ interrupts. Vector IRQ has medium priority. This level can assign up to 16 of the 32 requests. Any of the 32 requests can be assigned to any of the 16 vector IRQ slots. Slot 0 has the highest priority, while slot 15 has the lowest priority. Non-vector IRQ has the lowest priority. How to initialize an interrupt source as one of the three types of interrupts Assign 32 interrupt requests as FIQ or IRQ (including vector IRQ and non-vector IRQ) through the VICIntSelect interrupt selection register; select one of the 32 interrupt requests as a vector IRQ and set this interrupt request to IRQ slotx (x corresponds to x in VICVectCntlx) through VICVectCntlx (x=0, 1, ..., 15). If an interrupt source is set as IRQ but is not enabled through VICVectCntlx, the interrupt source will be defaulted to a non-vector IRQ. The interrupt processing process is as follows: Initialization: Set the interrupt source to one of the three interrupt sources, set the interrupt address, enable the interrupt, and then run the user program normally; When an IRQ interrupt occurs, VIC will set the VICVectAddr register to the address of the corresponding interrupt service program according to the interrupt source, switch the processor working mode to IRQ mode, and jump to the IRQ interrupt entry 0x00000018; Use "LDR PC, [PC, #-0xFF0]" at 0x00000018 in the exception interrupt vector table to make the program jump to the address saved in the memory (0x00000018+8-0x00000FF0=0xFFFFF030). 0xFFFFF030 is the VICVectAddr register address. That is to say: through this instruction, the program jumps to the address of the interrupt service program pointed to by the VICVectAddr register; The interrupt service program performs the corresponding interrupt processing and clears the interrupt. It is recommended to define the interrupt service program with the __irq keyword; After the interrupt service is completed, you can return to the original break point. When returning, the processor working mode must be switched at the same time. Note: Before exiting the interrupt, be sure to write 0 to the VICVectAddr register to notify VIC that the interrupt has ended; it is recommended to define the interrupt service program with the __irq keyword, so that the function will automatically switch the processor working mode, but the function cannot return parameters or values. IRQ interrupt There are two types of IRQ interrupts: vectored IRQ and non-vectored IRQ interrupts. When an IRQ interrupt occurs: If it is a vectored IRQ interrupt, since VIC has previously loaded the IRQ service program address VICVectAddrx (x=0, 1, ..., 15) of the highest priority request into VICVectAddr, the program jumps into the interrupt service program to continue execution. If it is a non-vectored IRQ interrupt, VIC provides a default service program address VICDefVectAddr. The IRQ interrupt entry program can obtain the address by reading the vector address register VICVectAddr of VIC, and then jump to the corresponding service program to continue execution. The default service program is shared by all non-vectored IRQs. The default service program can read the IRQ status register to determine which IRQ is activated. Working principle of lpc2000 Embedded processor is the core part of embedded system hardware. Philips has launched more than ten high-performance and low-power LPC2000 series microcontrollers based on ARM7 to meet the growing needs of the embedded market. The LPC2000 series microprocessor operates at a frequency of 60MHz and adopts a 32-bit RISC based on the ARMTDMI core. LPC2000 has a wide range of peripheral interfaces, including UART, SPI, I2C, CAN, ADC, PWM, RTC, etc. This series of microcontrollers LPC2114/2124/2119/2129/2194, LPC2210/2212/2214, LPC2290 /2292/2294 use the on-chip memory loading module to achieve "zero wait access" high-speed flash memory function, which improves the efficiency of instruction execution. It provides enhanced communication functions and on-chip code protection mechanism on the basis of high performance and low power consumption. With a wide range of built-in serial communication interfaces, they are also very suitable for communication gateways, protocol converters, embedded soft modems, etc. The 6-channel PWM is more suitable for complex motor control applications. The LPC2000 series microcontrollers can achieve zero-wait access to high-speed flash memory, which is mainly due to the on-chip memory acceleration module. Figure 2 is a block diagram of the memory acceleration module. The 128-bit wide flash array interfaces with the processor through a separate local bus and can provide four 32-bit instructions to the ARM core per cycle. This allows the MCU to execute instructions directly from the flash memory without going through a wait state, thereby eliminating the waiting time when reading from the general flash memory. In order to solve the waiting time caused by the change of instruction sequence and the different processing of instructions and data, the module implements the joint work of three functional blocks: pre-fetch buffer, data bypass to avoid data read/write disrupting the address sequence, and jump tracking buffer, and uses two groups of 128-bit wide memories for parallel access to eliminate delays. The role of the memory acceleration module depends on the size of the system clock. The access time of the LPC2000 series on-chip flash memory is 50nS. For applications with a system clock of no more than 20MHZ, the contents of the flash memory can be read out within 1 cycle, and there is no need to use the memory acceleration module. The higher the clock frequency, the greater the impact on system performance when executing code directly from the flash memory. At this time, enabling the memory acceleration module can achieve a nearly 4-fold acceleration, truly achieving zero-wait high-speed flash memory. Since the LPC2000 can execute instructions directly from the flash memory, there is no need to transfer the code to the SRAM during the boot process. This not only saves the time-consuming and energy-consuming system startup steps, but also saves expensive SRAM. Programming of the on-chip flash memory can be achieved in several ways: through the built-in serial JTAG interface, through the serial port for in-system programming (ISP), or through in-application programming (IAP). Vectored Interrupt Controller The vectored interrupt controller of the LPC2000 series can support up to 32 interrupt requests, which can be programmed into three categories as needed: FIQ, vector IRQ, and non-vector IRQ. Fast interrupt requests (FIQ) have the highest priority. Vectored IRQs have medium priority. This level can allocate 16 of the 32 requests. Non-vectored IRQsThe lowest priority. This programmable allocation mechanism means that the interrupt priorities of different peripherals can be dynamically allocated and adjusted. For any vector interrupt, once a request is issued, the CPU can read the VIC and jump to the entry address of the corresponding interrupt service routine in one cycle, which minimizes the interrupt latency. Methods for programming the on-chip flash of the lpc2000 series microcontrollers 1. Introduction to LPC2000 Flash The flash memory system contains 16 sectors of 128kB flash devices and 17 sectors of 256kB flash devices. The flash memory starts at address 0 and increases upward. The flash boot loader also provides ISP and IAP programming interfaces for the on-chip flash memory. The IAP, ISP and RealMonitor programs are all located in the boot sector. The boot sector exists in all devices. ISP and IAP commands do not allow write/erase/run operations on the boot sector. Only 120kB Flash in the 128kB Flash device is available for user programs. The device contains a total of 256kB of Flash, of which 248kB is available for user programs. The Boot Block is usually located at the top of the on-chip Flash memory. In 128kB Flash, it is the 16th sector (the corresponding sector number is 15), and in 256kB Flash, it is the 18th sector (the corresponding sector number is 17). The Flash memory sectors occupied by the Boot Block cannot be used to store user data. The LPC2000 series provides In-Application Programming (IAP), where the end-user code directly executes In-Application Programming (IAP) to erase and program the on-chip Flash memory. Falsh can be erased and written 10,000 times, and the programming time for a 512-byte row is 1ms. The erase time for a single sector or the entire chip is 400ms. The Flash memory cannot be accessed during a write or erase operation. The IAP command for performing Flash write/erase operations uses the top 32 bytes of the on-chip RAM. If IAP programming is allowed in the application, the user program should not use this space. Many 8-bit microcontrollers have the concept of pages, which is the smallest unit of Flash programming. The content of a page can be erased and programmed at a time. Since a page contains fewer bytes, it is very flexible to use Flash as EEPROM in this case. However, the LPC2000 series does not have the concept of pages. It only has the smallest Flash programming unit, the sector, which means that even if the user only wants to modify one byte, he needs to erase 8K of Flash first. The process of using Flash as EEPROM is actually the process of reading, modifying and writing Flash. 2. Write data to Flash Flash must follow the process of selecting sectors, erasing, selecting sectors, and writing. When it comes to program writing, the following codes must be included in sequence: SelSector (1, 1); // Select sector 1 EraseSector (1, 1); // Erase sector 1 SelSector (1, 1); // Select sector 1 for (i=0; i<512; i++) source[i]=0x41; RamToFlash (0x00002000, (uint32)source, 512); // Write data to sector 1 The following points need to be noted when applying: 1) If the sector is not selected before writing, it cannot be written correctly. 2) If it is not erased before writing, the writing is incorrect. 3) At least 512 bytes should be written, and the number of bytes written should be 512 or 1024 or 4096 or 8192. 4) Flash cannot be accessed during erasing, which is why IAP needs to disable interrupts. Disabling interrupts can be achieved with the following statement: __asm{MSR CPSR_c, #0xdf}, and correspondingly, enabling interrupts can be achieved with the following statement: __asm{MSR CPSR_c, #0x5f}. In addition, people often ask how to define a constant value at a specific address in Flash. I think this function is not very practical, because the minimum unit of each erase is 8K. It is better to write data directly to an address in Flash. This address is in an empty sector, and both reading and writing use this address as the base address. Since the compiled code is close to the bottom, you can check the amount of compiled code and then select the upper address as the variable area. If you really want to define the array at a specific location in Flash, it seems that you can use scattered loading. 3. Read data from Flash Reading data from Flash is relatively simple. You can define a pointer variable that points to a specific Flash address. For example, it can be written as follows: uint32 i; uint8 * p; p= (uint8 *) 0x1C000; for (i=0; i<400; i++) { Puthexbyte (* (p++)); } 4. Flash encryption Code read protection This is a feature of Bootloader revision 1.61. Code read protection is enabled by writing 0x87654321 (2271560481 in decimal) to Flash address 0x1FC (user Flash sector 0). Address 0x1FC is used to allow some space to be reserved for the fiq exception handler. When code read protection is enabled on the JTAG debug port, external memory boot and the following ISP commands are disabled: l Read memory l Write RAM l Run l Copy RAM contents to Flash The above ISP commands terminate with CODE_READ_PROTECTION_ENABLED. When code read protection is enabled, the ISP erase command only allows erasing the contents of the user sector. This restriction does not exist when code read protection is disabled. IAP commands are not affected by code read protection. RelInFlash using the project template is automatically encrypted. 5. Things to note when using project templates When using ZLG's project templates, you need to pay attention to the following points: Methods for programming the on-chip flash of the lpc2000 series microcontrollers 1) Modify the stack and in STARTUP.The initialization stack in the S file is StackUsr-20*4 2) Set the compilation parameter -apcs/intervork. It is important to modify the Language Settings/ARM C Compiler/ATPS. At the beginning, I accidentally selected the ARM Assembler language setting. As a result, when I ran the program, I wrote the Flash incorrectly. You should choose the right language setting. 3) Variable definition. Since at least 512 bytes are written at a time, the variables related to read and write operations are best defined as uint32 type. A mistake I made was to define the variable as uint8 type, as follows: uint8 i; for (i = 0; i < 512; i ++) source = 0x41; RamToFlash (0x00002000, (uint32) source, 512); // Write data to sector 1 The result is predictable. It keeps running in the for loop and cannot jump out. This gives us the illusion that IAP is not easy to use.