1. 程式人生 > 其它 >基於MM32實現NOR FLASH執行應用程式的過程解析

基於MM32實現NOR FLASH執行應用程式的過程解析

在專案開發之初,我們會根據設計需求來選擇符合要求的晶片,其中RAM決定程式執行時的記憶體大小、ROM決定了應用程式的儲存空間大小;但就些應用功能特別大的專案,MCU內部的FLASH(ROM)儲存空間無法滿足要求,這個時候就需要外擴程式儲存空間,NOR FLASH就是其中一種解決方案;本文結合涉及到的技術點一一做了介紹說明,包含如下的內容:
1、KEIL下載程式配置及說明
2、MM32實現跳轉到NOR FLASH執行程式
3、基於MM32的NOR FLASH下載演算法實現
4、MM32實現NOR FLASH應用程式程式設計,下載程式並執行

KEIL下載程式配置及說明

通過對專案工程的配置,在KEIL在編譯完工程後,會生成相應的HEX或BIN格式的程式燒錄檔案,點選Download下載按鍵後,會將燒錄檔案燒錄到晶片中:
點選Option for Target魔術棒按鍵,在彈出的Option for Target視窗中的Output選項卡中設定生成程式燒錄檔名,並勾選Create HEX file選項:


如果需要同時再生成BIN格式的程式燒錄檔案,我們可以在User選項卡中進行如下圖的配置:


接著在Debug選項卡中選擇相應的除錯下載工具:


在Utilities選項卡中配置下載設定(使用與Debug相同的工具進行下載程式)如下圖所示:


另外Utilities選項卡中,點選Settings按鍵,在彈出的視窗中Flash Download選項卡中進行如下配置:


下載功能設定:包括了擦出選擇、程式設計、校驗和下載完成後復位晶片並執行應用程式;
程式設計(下載)演算法選擇:一般在建立工程選擇相應的晶片後,這邊的下載演算法就默認了,如果沒有我們可以點選ADD按鍵新增相對應的下載演算法;下載演算法列舉了描述、裝置儲存空間大小、裝置型別以及地址區間範圍;
程式設計(下載)演算法在RAM中的位置:這個一般是預設的,START表示晶片RAM的起始地址,這個是由晶片決定的;SIZE表示最大支援的程式設計(下載)演算法的程式空間大小,這個可以修改,但不得小於下載演算法程式大小;

待這些都配置完成後,我們編譯工程程式碼,無錯誤警告後,點選Download下載按鍵,即可下載應用程式到晶片中;

那在點選了Download按鍵後,那KEIL是如何將燒錄程式下載到晶片中去的呢?

簡單的說就是KEIL軟體根據配置將程式設計(下載)演算法載入到晶片指定的RAM空間去(這個空間就是上述的以START作為起始地址,SIZE大小的RAM空間),並執行下載演算法,對下載檔案進行解析,將需要寫入的資料通過下載演算法寫到指定的儲存地址上,完成上述程式設計的過程。

MM32實現跳轉到NOR FLASH執行程式

MM32F3270系列MCU支援儲存控制器FSMC功能,可配置的靜態儲存器包括SRAM、NOR FLASH;另外還支援8080\6800介面,可以應用到LCD顯示上;

NOR FLASH之所以可以執行程式,主要是因為其內部地址/資料線是分開的,支援位元組訪問,符合CPU指令譯碼執行的要求(NOR FLASH上儲存了指令程式碼,MCU給NOR FLASH一個地址,NOR FLASH就向MCU返回相應地址上的資料,讓MCU執行,中間不需要額外的處理操作)。

那通過上述的描述,使用MM32實現跳轉到NOR FLASH執行程式,我們就只需要在基於MM32內部FLASH執行的基礎上實現NOR FLASH與MCU之間的FSMC初始化配置,以及程式跳轉這兩個操作步驟,具體參考程式碼如下所示:

FSMC初始化配置:
複製
/*******************************************************************************

* [url=home.php?mod=space&uid=288409]@file[/url]NOR.c

* [url=home.php?mod=space&uid=187600]@author[/url]King

* [url=home.php?mod=space&uid=895143]@version[/url] V1.00

* [url=home.php?mod=space&uid=212281]@date[/url]25-Jan-2021

* [url=home.php?mod=space&uid=247401]@brief[/url]......

*******************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/

#define __NOR_C__

/* Includes ------------------------------------------------------------------*/

#include "NOR.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

/* Exported variables --------------------------------------------------------*/

/* Exported function prototypes ----------------------------------------------*/

/*******************************************************************************

* @brief

* @param

* @retval

* [url=home.php?mod=space&uid=93590]@Attention[/url]

*******************************************************************************/

void NOR_InitGPIO(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE |

RCC_AHBPeriph_GPIOF | RCC_AHBPeriph_GPIOG , ENABLE);

GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_12);/* FSMC_D0*/

GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_12);/* FSMC_D1*/

GPIO_PinAFConfig(GPIOD, GPIO_PinSource0,GPIO_AF_12);/* FSMC_D2*/

GPIO_PinAFConfig(GPIOD, GPIO_PinSource1,GPIO_AF_12);/* FSMC_D3*/

GPIO_PinAFConfig(GPIOE, GPIO_PinSource7,GPIO_AF_12);/* FSMC_D4*/

GPIO_PinAFConfig(GPIOE, GPIO_PinSource8,GPIO_AF_12);/* FSMC_D5*/

GPIO_PinAFConfig(GPIOE, GPIO_PinSource9,GPIO_AF_12);/* FSMC_D6*/

GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_12);/* FSMC_D7*/

GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_12);/* FSMC_D8*/

GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_12);/* FSMC_D9*/

GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_12);/* FSMC_D10 */

GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_12);/* FSMC_D11 */

GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_12);/* FSMC_D12 */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource8,GPIO_AF_12);/* FSMC_D13 */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource9,GPIO_AF_12);/* FSMC_D14 */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_12);/* FSMC_D15 */

GPIO_PinAFConfig(GPIOF, GPIO_PinSource0,GPIO_AF_12);/* FSMC_A0*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource1,GPIO_AF_12);/* FSMC_A1*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource2,GPIO_AF_12);/* FSMC_A2*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource3,GPIO_AF_12);/* FSMC_A3*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource4,GPIO_AF_12);/* FSMC_A4*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource5,GPIO_AF_12);/* FSMC_A5*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource12, GPIO_AF_12);/* FSMC_A6*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource13, GPIO_AF_12);/* FSMC_A7*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource14, GPIO_AF_12);/* FSMC_A8*/

GPIO_PinAFConfig(GPIOF, GPIO_PinSource15, GPIO_AF_12);/* FSMC_A9*/

GPIO_PinAFConfig(GPIOG, GPIO_PinSource0,GPIO_AF_12);/* FSMC_A10 */

GPIO_PinAFConfig(GPIOG, GPIO_PinSource1,GPIO_AF_12);/* FSMC_A11 */

GPIO_PinAFConfig(GPIOG, GPIO_PinSource2,GPIO_AF_12);/* FSMC_A12 */

GPIO_PinAFConfig(GPIOG, GPIO_PinSource3,GPIO_AF_12);/* FSMC_A13 */

GPIO_PinAFConfig(GPIOG, GPIO_PinSource4,GPIO_AF_12);/* FSMC_A14 */

GPIO_PinAFConfig(GPIOG, GPIO_PinSource5,GPIO_AF_12);/* FSMC_A15 */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_12);/* FSMC_A16 */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_12);/* FSMC_A17 */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_12);/* FSMC_A18 */

GPIO_PinAFConfig(GPIOE, GPIO_PinSource3,GPIO_AF_12);/* FSMC_A19 */

GPIO_PinAFConfig(GPIOE, GPIO_PinSource4,GPIO_AF_12);/* FSMC_A20 */

GPIO_PinAFConfig(GPIOE, GPIO_PinSource5,GPIO_AF_12);/* FSMC_A21 */

GPIO_PinAFConfig(GPIOE, GPIO_PinSource6,GPIO_AF_12);/* FSMC_A22 */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource4,GPIO_AF_12);/* FSMC_NOE*/

GPIO_PinAFConfig(GPIOD, GPIO_PinSource5,GPIO_AF_12);/* FSMC_NWE*/

GPIO_PinAFConfig(GPIOD, GPIO_PinSource6,GPIO_AF_12);/* FSMC_NWAIT*/

GPIO_PinAFConfig(GPIOG, GPIO_PinSource9,GPIO_AF_12);/* FSMC_NE2*/

/* D00 - D01 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_14 | GPIO_Pin_15;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/* D02 - D03 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0 | GPIO_Pin_1;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/* D04 - D12 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_7| GPIO_Pin_8| GPIO_Pin_9|

GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 |

GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOE, &GPIO_InitStructure);

/* D13 - D15 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/* A00 - A05 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |

GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOF, &GPIO_InitStructure);

/* A06 - A09 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_12 | GPIO_Pin_13 |

GPIO_Pin_14 | GPIO_Pin_15;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOF, &GPIO_InitStructure);

/* A10 - A15 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |

GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOG, &GPIO_InitStructure);

/* A16 - A18 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/* A19 - A22 */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_3 | GPIO_Pin_4 |

GPIO_Pin_5 | GPIO_Pin_6;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOE, &GPIO_InitStructure);

/* NOE(PD4) NWE(PD5) configuration */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/* NWAIT(PD6) configuration */

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_6;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/* NE2(PG9) configuration */

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOG, &GPIO_InitStructure);

}

/*******************************************************************************

* @brief

* @param

* @retval

* @attention

*******************************************************************************/

void NOR_InitFSMC(void)

{

FSMC_InitTypeDefFSMC_InitStructure;

FSMC_NORSRAM_Bank_InitTypeDef FSMC_BankInitStructure;

RCC_AHB3PeriphClockCmd(RCC_AHB3ENR_FSMC, ENABLE);

FSMC_NORSRAM_BankStructInit(&FSMC_BankInitStructure);

FSMC_BankInitStructure.FSMC_SMReadPipe= 0;

FSMC_BankInitStructure.FSMC_ReadyMode= 0;

FSMC_BankInitStructure.FSMC_WritePeriod= 5;/* W:WE Pulse Width: [0, 63] */

FSMC_BankInitStructure.FSMC_WriteHoldTime= 3;/* W:Address/Data Hold Time : [0,3] */

FSMC_BankInitStructure.FSMC_AddrSetTime= 3;/* W:Address Setup Time: [0,3] */

FSMC_BankInitStructure.FSMC_ReadPeriod= 8;/* R:Read Cycle Time: [0, 63] */

FSMC_BankInitStructure.FSMC_DataWidth= FSMC_DataWidth_16bits;

FSMC_NORSRAM_Bank_Init(&FSMC_BankInitStructure, FSMC_NORSRAM_BANK1);

FSMC_NORSRAMStructInit(&FSMC_InitStructure);

FSMC_InitStructure.FSMC_Mode= FSMC_Mode_NorFlash;

FSMC_InitStructure.FSMC_TimingRegSelect= FSMC_TimingRegSelect_1;

FSMC_InitStructure.FSMC_MemSize= FSMC_MemSize_64MB;

FSMC_InitStructure.FSMC_MemType= FSMC_MemType_FLASH;

FSMC_InitStructure.FSMC_AddrDataMode= FSMC_AddrDataDeMUX;

FSMC_NORSRAMInit(&FSMC_InitStructure);

}

/*******************************************************************************

* @brief

* @param

* @retval

* @attention

*******************************************************************************/

void NOR_Init(void)

{

NOR_InitGPIO();

NOR_InitFSMC();

}

/******************* (C) COPYRIGHT 2022 *************************END OF FILE***/


程式跳轉程式碼:
複製
/*******************************************************************************

* @filemain.c

* @authorKing

* @version V1.00

* @date25-Jan-2021

* @brief......

*******************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/

#define __MAIN_C__

/* Includes ------------------------------------------------------------------*/

#include "main.h"

/* Private typedef -----------------------------------------------------------*/

typedef void (*pFunction)(void);

/* Private define ------------------------------------------------------------*/

#define ApplicationAddress((uint32_t)0x64000000)

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

uint32_tJumpAddress=0;

pFunction JumpToApplication;

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

/* Exported variables --------------------------------------------------------*/

/* Exported function prototypes ----------------------------------------------*/

/*******************************************************************************

* @brief

* @param

* @retval

* @attention

*******************************************************************************/

int main(void)

{

NOR_Init();

/* Jump to code loaded in NOR memory and execute it ***********************/

JumpAddress = *(volatile uint32_t *)(ApplicationAddress + 4);

JumpToApplication = (pFunction)JumpAddress;

/* Initialize user application's Stack Pointer */

__set_MSP(*(volatile uint32_t *)ApplicationAddress);

JumpToApplication();

while(1);

}

/******************* (C) COPYRIGHT 2022 *************************END OF FILE***/


KEIL工程的相關配置:


基於MM32的NOR FLASH下載演算法實現

在能夠成功跳轉到NOR FLASH執行程式後,我們就需要將應用程式下載到NOR FLASH就可以了;結合第一小結,一般MCU自帶的下載演算法只是將程式下載到自身內部的FLASH儲存空間,如果需要將程式下載到外擴的NOR FLASH,我們可以使用燒錄工具,將程式燒錄進NOR FLASH,但在開發除錯過程中,這顯然不太方便,所以我們就需要自行編寫下載演算法,來實現MM32與NOR FLASH之間的程式程式設計。

怎麼去編寫這個下載演算法呢?

在KEIL的安裝路徑下:C:\Keil_v5\ARM\Flash有一個_Template的下載演算法工程模板,我們將其直接拷貝一份,重新命名為MM32F3270_NOR_FLM;開啟KEIL工程,裡面主要有兩個檔案FlashDev.c和FlashPrg.c

FlashDev.c主要是用來描述儲存特性的,包括Device Name、Device Type、Device Start Address、Device Size in Bytes等等,這些特性的值,我們可以根據NOR FLASH的特性值來填寫,程式設計超時時間和擦出超時時間可以儘量長一些,做些冗餘;具體參考如下所示:


FlashPrg.c就是用來實現程式設計下載演算法的介面函式,其中有些函式是必須實現的,有些函式則是可選擇的,如下所示:


我們需要實現的就是通過對這些函式的補充實現,來達到NOR FLASH的讀寫操作,實現將程式下載到NOR FLASH;在第一小節,我們知道下載演算法是需要先載入到RAM中執行,再去進行程式設計操作的,對於這個載入到RAM空間的下載演算法程式空間大小其實是有大小限制有,根據每個晶片的RAM大小而定,但最大也不能超過0x10000,所以我們實現自己定義的下載演算法的時候,就尤其需要注意;儘量的不去使用庫函式,以使用暫存器或者是直接操作晶片內部地址最佳,這樣可以最大程式的節省程式空間;但同時帶來的就是程式碼的閱讀理解變得有些困難;

因為下載演算法執行的程式不能夠實現的線上除錯,所以對於NOR FLASH操作的這些函式功能,最好在其它工程上先進行驗證,確認功能正常後,再移植到下載演算法的工程當中來。

接下來就是點選KEIL工程魔術棒按鍵對工程進行設定,在Target選項卡中選擇晶片型號為MM32F3277G9P,在C/C++選項卡中根據需要進行巨集定義(因為這個下載演算法,支援多個NOR FLASH,所以我這邊有相應的巨集定義),在新增好NOR FLASH的相關函式,並補全介面函式後,進行編譯,此時工程目錄中就會生成一個FLM檔案(因為在User選項卡中有一個命令:cmd.exe /C copy "Objects\%L" ".\@L.FLM",它會將編譯後的檔案轉換成FLM格式)


我們將這個生成的FLM下載演算法檔案拷貝到C:\Keil_v5\ARM\Flash目錄下,在後面工程使用到的時候就可以新增進來了。

MM32實現NOR FLASH應用程式程式設計,下載程式並執行

對於執行在NOR FLASH中的MM32程式來說,程式編寫並沒有特殊的要求,唯一不同的就是對於KEIL工程的設定;例程中我們只實現了LED燈的閃爍功能,功能比較簡單;對於KEIL工程的設定如下圖所示:

將預設的程式空間和程式啟動空間設定為NOR FLASH的起始地址作為開始:


根據DEBUG除錯工具進行對應的選擇:


下載工具與除錯工具相同:


將程式設計(下載)演算法選擇為第三小節生成的FLM演算法,在新增進來的時候,就會自動顯示相應的描述資訊:


這樣配置完成後,編譯後點擊下載按鍵,程式就被下載到NOR FLASH外部儲存空間了,因為勾選了RESET AND RUN,下載完成後會復位MCU,此時MCU FLASH中已經存在了跳轉程式,這個時候就會跳轉到NOR FLASH執行LED閃爍程式;此時LED燈若能夠正常執行,就說明程式功能已經正常運行了。

另外有些小夥伴會問,在Option for Target視窗Utilities選項卡中,有看到Init File會配置一個INI檔案,我上述的工程配置中卻沒有,這是怎麼回事呢?

這邊的INI檔案包含的是對MCU內部地址配置相應引數值的資料,是在下載程式前先對MCU進行設定的操作;一般看到的就是對MCU與NOR FLASH的FSMC相關暫存器進行配置,好讓下載演算法能夠正常的去操作NOR FLASH;但我的配置截圖中卻沒有,是因為在實現下載演算法時的INIT函式,已經實現了對FSMC的初始化配置,所以在INIT FILE的位置就不需要再重複操作了。

後續:

有了這個下載演算法,我們可以將部分程式或資料指令到外部儲存空間;如果當我們通過LCD顯示圖片資料時,圖片資料是一個很大的陣列,我們就可以將這些資料指定到NOR FLASH中,而應用程式還是在MCU內部的FLASH中執行,操作如下所示:

晶片有兩個ROM空間,但預設的和啟動的為MCU內部FLASH:


下載演算法有兩個,這兩個的地址是不一樣的,一個是MCU內部FLASH,一個是外擴的NOR FLASH:


將程式指定到NOR FLASH的方法,右擊.C檔案,選擇Options for File ”IMAGE1.c”...


在彈出的視窗中將CODE/CONST指令到ROM1,如下圖所示:


然後在程式中再呼叫IMAGE1.c檔案中的資料,這樣在編譯後下載程式的時候,會先下載程式到MCU的FLASH,再下載圖片資料到MCU擴充套件的NOR FLASH:


硬體是基本神舟III開發板實現的,MCU使用靈動微電子的MM32F3277G9P,NOR FLASH使用M29W128FH,至此分享就結束了,希望對各位小夥伴有所幫助!
---------------------
作者:xld0932
連結:https://bbs.21ic.com/icview-3197118-1-1.html
來源:21ic.com
此文章已獲得原創/原創獎標籤,著作權歸21ic所有,任何人未經允許禁止轉載。