chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于MM32實(shí)現(xiàn)NOR FLASH運(yùn)行應(yīng)用程序的過程解析

Q4MP_gh_c472c21 ? 來(lái)源:21ic論壇 ? 作者:xld0932 ? 2022-03-31 13:52 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

在項(xiàng)目開發(fā)之初,我們會(huì)根據(jù)設(shè)計(jì)需求來(lái)選擇符合要求的芯片。其中,RAM決定了程序運(yùn)行時(shí)的內(nèi)存大小,ROM決定了應(yīng)用程序的存儲(chǔ)空間大小。但對(duì)于應(yīng)用功能特別大的項(xiàng)目,MCU內(nèi)部的FLASH(ROM)存儲(chǔ)空間就無(wú)法滿足要求了。這個(gè)時(shí)候就需要外擴(kuò)程序存儲(chǔ)空間,而NOR FLASH就是其中一種解決方案。

文結(jié)合涉及到的技術(shù)點(diǎn)一一做了詳細(xì)介紹和說(shuō)明,包含如下四大內(nèi)容:

1. KEIL下載程序配置及說(shuō)明2. MM32實(shí)現(xiàn)跳轉(zhuǎn)到NOR FLASH運(yùn)行程序3. 基于MM32的NOR FLASH下載算法實(shí)現(xiàn)4. MM32實(shí)現(xiàn)NOR FLASH應(yīng)用程序編程,下載程序并運(yùn)行

一、KEIL下載程序配置及說(shuō)明

通過對(duì)項(xiàng)目工程的配置,在KEIL在編譯完工程后,會(huì)生成相應(yīng)的HEX或BIN格式的程序燒錄文件,點(diǎn)擊Download下載按鍵后,會(huì)將燒錄文件燒錄到芯片中。

點(diǎn)擊Option for Target魔術(shù)棒按鍵,在彈出的Option for Target窗口中的Output選項(xiàng)卡中設(shè)置生成程序燒錄文件名,并勾選Create HEX file選項(xiàng),如下圖所示:

2316602c-b0b4-11ec-aa7f-dac502259ad0.png

如果需要同時(shí)再生成BIN格式的程序燒錄文件,我們可以在User選項(xiàng)卡中進(jìn)行如下圖的配置:

232ff0d2-b0b4-11ec-aa7f-dac502259ad0.png

接著,在Debug選項(xiàng)卡中選擇相應(yīng)的調(diào)試下載工具。

2351db2a-b0b4-11ec-aa7f-dac502259ad0.png

在Utilities選項(xiàng)卡中配置下載設(shè)置(使用與Debug相同的工具進(jìn)行下載程序),如下圖所示:

23676e4a-b0b4-11ec-aa7f-dac502259ad0.png

另外Utilities選項(xiàng)卡中,點(diǎn)擊Settings按鍵,在彈出的窗口中Flash Download選項(xiàng)卡中進(jìn)行如下配置:

237ea4de-b0b4-11ec-aa7f-dac502259ad0.png

下載功能設(shè)置:包括擦出選擇、編程、校驗(yàn)和下載完成后復(fù)位芯片并運(yùn)行應(yīng)用程序。

編程(下載)算法選擇:一般在創(chuàng)建工程選擇相應(yīng)的芯片后,這邊的下載算法就默認(rèn)了,如果沒有我們可以點(diǎn)擊ADD按鍵添加相對(duì)應(yīng)的下載算法;下載算法列舉了描述、設(shè)備存儲(chǔ)空間大小、設(shè)備類型以及地址區(qū)間范圍。

編程(下載)算法在RAM中的位置:這個(gè)一般是默認(rèn)的,START表示芯片RAM的起始地址,這個(gè)是由芯片決定的;SIZE表示最大支持的編程(下載)算法的程序空間大小,這個(gè)可以修改,但不得小于下載算法程序大小。

待這些都配置完成后,我們編譯工程代碼,無(wú)錯(cuò)誤警告后,點(diǎn)擊Download下載按鍵,即可下載應(yīng)用程序到芯片中。

那么,在點(diǎn)擊了Download按鍵后,那KEIL是如何將燒錄程序下載到芯片中去的呢?

簡(jiǎn)單來(lái)說(shuō),就是KEIL軟件根據(jù)配置將編程(下載)算法加載到芯片指定的RAM空間去(這個(gè)空間就是上述的以START作為起始地址,SIZE大小的RAM空間),并運(yùn)行下載算法,對(duì)下載文件進(jìn)行解析,將需要寫入的數(shù)據(jù)通過下載算法寫到指定的存儲(chǔ)地址上,完成上述編程的過程。

二、MM32實(shí)現(xiàn)跳轉(zhuǎn)到NOR FLASH運(yùn)行程序

MM32F3270系列MCU支持存儲(chǔ)控制器FSMC功能,可配置的靜態(tài)存儲(chǔ)器包括SRAM、NOR FLASH;另外還支持80806800接口,可以應(yīng)用到LCD顯示上。

NOR FLASH之所以可以運(yùn)行程序,主要是因?yàn)槠鋬?nèi)部地址/數(shù)據(jù)線是分開的,支持字節(jié)訪問,符合CPU指令譯碼執(zhí)行的要求(NOR FLASH上儲(chǔ)存了指令代碼,MCU給NOR FLASH一個(gè)地址,NOR FLASH就向MCU返回相應(yīng)地址上的數(shù)據(jù),讓MCU執(zhí)行,中間不需要額外的處理操作)。

那通過上述的描述,使用MM32實(shí)現(xiàn)跳轉(zhuǎn)到NOR FLASH運(yùn)行程序,我們就只需要在基于MM32內(nèi)部FLASH運(yùn)行的基礎(chǔ)上實(shí)現(xiàn)NOR FLASH與MCU之間的FSMC初始化配置,以及程序跳轉(zhuǎn)這兩個(gè)操作步驟,具體參考代碼如下所示:

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_InitTypeDef              FSMC_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***/


程序跳轉(zhuǎn)代碼:

/*******************************************************************************
 * @file    main.c
 * @author  King
 * @version V1.00
 * @date    25-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_t  JumpAddress  =  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工程的相關(guān)配置:

2394b882-b0b4-11ec-aa7f-dac502259ad0.png

23a9d4ce-b0b4-11ec-aa7f-dac502259ad0.png

三、基于MM32的NOR FLASH下載算法實(shí)現(xiàn)

在能夠成功跳轉(zhuǎn)到NOR FLASH運(yùn)行程序后,我們就需要將應(yīng)用程序下載到NOR FLASH就可以了。

結(jié)合第一小結(jié),一般MCU自帶的下載算法只是將程序下載到自身內(nèi)部的FLASH存儲(chǔ)空間,如果需要將程序下載到外擴(kuò)的NOR FLASH,我們可以使用燒錄工具,將程序燒錄進(jìn)NOR FLASH。但在開發(fā)調(diào)試過程中,這顯然不太方便,所以我們就需要自行編寫下載算法,來(lái)實(shí)現(xiàn)MM32與NOR FLASH之間的程序編程。

應(yīng)該怎么去編寫這個(gè)下載算法呢?

首先,在KEIL的安裝路徑下:C:Keil_v5ARMFlash有一個(gè)_Template的下載算法工程模板,我們將其直接拷貝一份,重命名為MM32F3270_NOR_FLM;打開KEIL工程,里面主要有兩個(gè)文件FlashDev.c和FlashPrg.c

FlashDev.c主要是用來(lái)描述存儲(chǔ)特性的,包括Device Name、Device Type、Device Start Address、Device Size in Bytes等等,這些特性的值,我們可以根據(jù)NOR FLASH的特性值來(lái)填寫,編程超時(shí)時(shí)間和擦出超時(shí)時(shí)間可以盡量長(zhǎng)一些,做些冗余,具體參考如下所示:

23c3372a-b0b4-11ec-aa7f-dac502259ad0.png

FlashPrg.c就是用來(lái)實(shí)現(xiàn)編程下載算法的接口函數(shù),其中有些函數(shù)是必須實(shí)現(xiàn)的,有些函數(shù)則是可選擇的,如下所示:

23d64586-b0b4-11ec-aa7f-dac502259ad0.png

我們需要實(shí)現(xiàn)的就是通過對(duì)這些函數(shù)的補(bǔ)充實(shí)現(xiàn),來(lái)達(dá)到NOR FLASH的讀寫操作,實(shí)現(xiàn)將程序下載到NOR FLASH。

在第一小節(jié),我們知道下載算法是需要先加載到RAM中運(yùn)行,再去進(jìn)行編程操作的,對(duì)于這個(gè)加載到RAM空間的下載算法程序空間大小其實(shí)是有大小限制有,根據(jù)每個(gè)芯片的RAM大小而定,但最大也不能超過0x10000。

所以,我們?cè)趯?shí)現(xiàn)自己定義的下載算法的時(shí)候就尤其需要注意,盡量的不去使用庫(kù)函數(shù),以使用寄存器或者是直接操作芯片內(nèi)部地址最佳,這樣可以最大程序的節(jié)省程序空間。

不過,這也會(huì)使代碼的閱讀理解變得有些困難。因?yàn)橄螺d算法運(yùn)行的程序不能夠?qū)崿F(xiàn)的在線調(diào)試,所以對(duì)于NOR FLASH操作的這些函數(shù)功能,最好在其它工程上先進(jìn)行驗(yàn)證,確認(rèn)功能正常后,再移植到下載算法的工程當(dāng)中來(lái)。

接下來(lái),就是點(diǎn)擊KEIL工程魔術(shù)棒按鍵對(duì)工程進(jìn)行設(shè)置。在Target選項(xiàng)卡中選擇芯片型號(hào)為MM32F3277G9P,在C/C++選項(xiàng)卡中根據(jù)需要進(jìn)行宏定義(因?yàn)檫@個(gè)下載算法,支持多個(gè)NOR FLASH,所以我這邊有相應(yīng)的宏定義),在添加好NOR FLASH的相關(guān)函數(shù),并補(bǔ)全接口函數(shù)后,進(jìn)行編譯。

此時(shí)工程目錄中就會(huì)生成一個(gè)FLM文件(因?yàn)樵赨ser選項(xiàng)卡中有一個(gè)命令:cmd.exe /C copy "Objects\%L" ".@L.FLM",它會(huì)將編譯后的文件轉(zhuǎn)換成FLM格式)

24023376-b0b4-11ec-aa7f-dac502259ad0.png

241b757a-b0b4-11ec-aa7f-dac502259ad0.png

242d48ea-b0b4-11ec-aa7f-dac502259ad0.png

我們將這個(gè)生成的FLM下載算法文件拷貝到C:Keil_v5ARMFlash目錄下,在后面工程使用到的時(shí)候就可以添加進(jìn)來(lái)了。

四、MM32實(shí)現(xiàn)NOR FLASH應(yīng)用程序編程,下載程序并運(yùn)行

對(duì)于運(yùn)行在NOR FLASH中的MM32程序來(lái)說(shuō),程序編寫并沒有特殊的要求,唯一不同的就是對(duì)于KEIL工程的設(shè)置。例程中,我們只實(shí)現(xiàn)了LED燈的閃爍功能,功能比較簡(jiǎn)單。對(duì)于KEIL工程的設(shè)置,如下圖所示:

將默認(rèn)的程序空間和程序啟動(dòng)空間設(shè)置為NOR FLASH的起始地址作為開始:

2446c48c-b0b4-11ec-aa7f-dac502259ad0.png

根據(jù)DEBUG調(diào)試工具進(jìn)行對(duì)應(yīng)的選擇:

246206ac-b0b4-11ec-aa7f-dac502259ad0.png

下載工具與調(diào)試工具相同:

2475f14e-b0b4-11ec-aa7f-dac502259ad0.png

將編程(下載)算法選擇為第三小節(jié)生成的FLM算法,在添加進(jìn)來(lái)的時(shí)候,就會(huì)自動(dòng)顯示相應(yīng)的描述信息:

248dbd1a-b0b4-11ec-aa7f-dac502259ad0.png

這樣配置完成后,編譯后點(diǎn)擊下載按鍵,程序就被下載到NOR FLASH外部存儲(chǔ)空間了。因?yàn)楣催x了RESET AND RUN,下載完成后會(huì)復(fù)位MCU,此時(shí)MCU FLASH中已經(jīng)存在了跳轉(zhuǎn)程序,這個(gè)時(shí)候就會(huì)跳轉(zhuǎn)到NOR FLASH執(zhí)行LED閃爍程序。此時(shí)LED燈若能夠正常運(yùn)行,就說(shuō)明程序功能已經(jīng)正常運(yùn)行了。

另外,有些小伙伴可能會(huì)問,在Option for Target窗口Utilities選項(xiàng)卡中,有看到Init File會(huì)配置一個(gè)INI文件,我上述的工程配置中卻沒有,這是怎么回事呢?

這邊的INI文件包含的是對(duì)MCU內(nèi)部地址配置相應(yīng)參數(shù)值的數(shù)據(jù),是在下載程序前先對(duì)MCU進(jìn)行設(shè)置的操作。一般看到的就是對(duì)MCU與NOR FLASH的FSMC相關(guān)寄存器進(jìn)行配置,好讓下載算法能夠正常的去操作NOR FLASH。但我的配置截圖中卻沒有,是因?yàn)樵趯?shí)現(xiàn)下載算法時(shí)的INIT函數(shù),已經(jīng)實(shí)現(xiàn)了對(duì)FSMC的初始化配置,所以在INIT FILE的位置就不需要再重復(fù)操作了。

五、后續(xù)

有了這個(gè)下載算法,我們可以將部分程序或數(shù)據(jù)指令到外部存儲(chǔ)空間;如果當(dāng)我們通過LCD顯示圖片數(shù)據(jù)時(shí),圖片數(shù)據(jù)是一個(gè)很大的數(shù)組,我們就可以將這些數(shù)據(jù)指定到NOR FLASH中,而應(yīng)用程序還是在MCU內(nèi)部的FLASH中運(yùn)行,操作如下圖所示:

芯片有兩個(gè)ROM空間,但默認(rèn)的和啟動(dòng)的為MCU內(nèi)部FLASH:

24a402aa-b0b4-11ec-aa7f-dac502259ad0.png

下載算法有兩個(gè),這兩個(gè)的地址是不一樣的,一個(gè)是MCU內(nèi)部FLASH,一個(gè)是外擴(kuò)的NOR FLASH:

24b9eeb2-b0b4-11ec-aa7f-dac502259ad0.png

將程序指定到NOR FLASH的方法,右擊.C文件,選擇Options for File”IMAGE1.c”...

24d3db6a-b0b4-11ec-aa7f-dac502259ad0.png

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

24e85c0c-b0b4-11ec-aa7f-dac502259ad0.png

然后在程序中再調(diào)用IMAGE1.c文件中的數(shù)據(jù),這樣在編譯后下載程序的時(shí)候,會(huì)先下載程序到MCU的FLASH,再下載圖片數(shù)據(jù)到MCU擴(kuò)展的NOR FLASH。

24fbc9f4-b0b4-11ec-aa7f-dac502259ad0.png

本文中的硬件是基本神舟III開發(fā)板實(shí)現(xiàn)的,MCU使用的是靈動(dòng)微電子的MM32F3277G9P,NOR FLASH使用的是M29W128FH。

至此分享就結(jié)束了,希望能對(duì)各位小伙伴有所幫助!另外,如果有需要查看原圖和代碼的小伙伴,請(qǐng)點(diǎn)擊底部“閱讀原文”進(jìn)行下載。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 芯片
    +關(guān)注

    關(guān)注

    462

    文章

    53559

    瀏覽量

    459328
  • 應(yīng)用程序
    +關(guān)注

    關(guān)注

    38

    文章

    3342

    瀏覽量

    59935
  • 存儲(chǔ)空間
    +關(guān)注

    關(guān)注

    0

    文章

    55

    瀏覽量

    10991
  • MM32
    +關(guān)注

    關(guān)注

    1

    文章

    108

    瀏覽量

    1318

原文標(biāo)題:實(shí)戰(zhàn)!基于MM32實(shí)現(xiàn)NOR FLASH運(yùn)行應(yīng)用程序的過程解析

文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    3D NOR FLASH技術(shù)、AI服務(wù)器動(dòng)能,多家廠商預(yù)估2026全年上漲

    電子發(fā)燒友網(wǎng)報(bào)道(文/黃晶晶)繼DRAM和NAND的價(jià)格不斷上漲之后,日前NOR Flash也出現(xiàn)了驚人的高達(dá)30%漲幅。NOR Flash在AI服務(wù)器、手機(jī)、平板電腦、可穿戴等領(lǐng)域呈
    的頭像 發(fā)表于 11-17 07:53 ?9061次閱讀
    3D <b class='flag-5'>NOR</b> <b class='flag-5'>FLASH</b>技術(shù)、AI服務(wù)器動(dòng)能,多家廠商預(yù)估2026全年上漲

    NOR Flash到NAND Flash和SD NAND,從底層結(jié)構(gòu)到應(yīng)用差異

    在嵌入式系統(tǒng)開發(fā)中,“存儲(chǔ)選型”是經(jīng)常會(huì)遇到的問題,特別是許多曾長(zhǎng)期使用 NOR   Flash 的工程師,在切換到 NAND Flash 時(shí)常常感到疑惑:   為什么 NAND Flash
    發(fā)表于 12-08 17:54

    FLASH中的代碼是如何得到運(yùn)行的呢

    以ARM為例: ARM-cortex-M3/4的單片機(jī)(比如STM32 等):該類單片機(jī)的代碼在nor flash中,cortex內(nèi)核可以直接運(yùn)行,不需要將代碼加載到ram中運(yùn)行
    發(fā)表于 12-04 08:06

    高性能SPI NOR FLASH芯片ZB25VQ系列推薦

    在嵌入式系統(tǒng)、物聯(lián)網(wǎng)設(shè)備及各類存儲(chǔ)應(yīng)用中,SPI NOR FLASH芯片因其接口簡(jiǎn)單、功耗低、讀寫速度快等特點(diǎn),成為代碼存儲(chǔ)與數(shù)據(jù)緩存的常見選擇。SPI NOR FLASH是一種基于S
    的頭像 發(fā)表于 12-01 14:52 ?204次閱讀

    華邦高性能NOR Flash用于學(xué)習(xí)平板

    華邦電子(Winbond)的NOR Flash以其卓越性能成為學(xué)習(xí)平板理想的存儲(chǔ)解決方案。其芯片內(nèi)執(zhí)行(XIP)特性可實(shí)現(xiàn)系統(tǒng)秒級(jí)快速啟動(dòng),高可靠性確保固件和核心代碼安全,低功耗特性則有效延長(zhǎng)設(shè)備續(xù)航,為流暢穩(wěn)定的學(xué)習(xí)體驗(yàn)奠定堅(jiān)
    的頭像 發(fā)表于 11-10 09:48 ?282次閱讀
    華邦高性能<b class='flag-5'>NOR</b> <b class='flag-5'>Flash</b>用于學(xué)習(xí)平板

    博雅NOR Flash 液晶電視核心存儲(chǔ)方案優(yōu)選?

    博雅BOYA BY25Q32BSSIG是一款32Mbit SPI NOR Flash芯片,支持133MHz高速讀取與XIP技術(shù),能顯著提升液晶電視的啟動(dòng)速度與系統(tǒng)響應(yīng)。其工業(yè)級(jí)溫度范圍與低功耗特性保障了電視在長(zhǎng)期高溫環(huán)境下的穩(wěn)定運(yùn)行
    的頭像 發(fā)表于 10-31 09:16 ?166次閱讀
    博雅<b class='flag-5'>NOR</b> <b class='flag-5'>Flash</b> 液晶電視核心存儲(chǔ)方案優(yōu)選?

    博雅NOR FLASH XIP技術(shù)實(shí)現(xiàn)電力儀表毫秒級(jí)快速啟動(dòng)?

    博雅128Mbit NOR Flash BY25Q128ESSIG為智能電力儀表提供高可靠存儲(chǔ)方案,133MHz讀取速度與-40℃~105℃寬溫保障數(shù)據(jù)實(shí)時(shí)性與穩(wěn)定性。
    的頭像 發(fā)表于 09-08 09:55 ?720次閱讀
    博雅<b class='flag-5'>NOR</b> <b class='flag-5'>FLASH</b> XIP技術(shù)<b class='flag-5'>實(shí)現(xiàn)</b>電力儀表毫秒級(jí)快速啟動(dòng)?

    SPI NOR FLASH是什么,與SPI NAND Flash的區(qū)別

    存儲(chǔ)一位數(shù)據(jù) (0或1) ,可以直接尋址,尋址速度非???。SPI NOR FLASH支持全雙工、單工以及半雙工傳輸方式,被廣泛應(yīng)用于嵌入式系統(tǒng)中,如Bootloader、操作系統(tǒng)內(nèi)核等程序的存儲(chǔ)。由于它的讀寫速度和尋址方式類似于
    的頭像 發(fā)表于 08-21 09:26 ?1131次閱讀

    華邦電子W25Q-RV系列NOR Flash的四大本領(lǐng)

    在汽車、物聯(lián)網(wǎng)和工業(yè)自動(dòng)化等應(yīng)用場(chǎng)景中,存儲(chǔ)器是否能夠穩(wěn)定運(yùn)行直接影響產(chǎn)品的可靠性。華邦推出的 W25Q-RV 系列 NOR Flash,成功通過 105°C 的工業(yè)級(jí)高溫循環(huán)測(cè)試和儲(chǔ)能測(cè)試,以超越 JEDEC 標(biāo)準(zhǔn)的性能,在嚴(yán)
    的頭像 發(fā)表于 08-16 17:14 ?1364次閱讀

    嵌入式系統(tǒng)中,FLASH 中的程序代碼必須搬到 RAM 中運(yùn)行嗎?

    嵌入式系統(tǒng)里,FLASH 中的程序代碼并非必須搬到 RAM 中運(yùn)行,這得由硬件配置、實(shí)際性能需求和應(yīng)用場(chǎng)景共同決定。就像很多低端單片機(jī),無(wú)論是依賴片內(nèi) Flash 還是外掛的 SPI
    的頭像 發(fā)表于 08-06 10:19 ?1144次閱讀
    嵌入式系統(tǒng)中,<b class='flag-5'>FLASH</b> 中的<b class='flag-5'>程序</b>代碼必須搬到 RAM 中<b class='flag-5'>運(yùn)行</b>嗎?

    普冉NOR FLASH助力IPC攝像頭高效運(yùn)行

    Puya 普冉 64 Mbit NOR Flash P25Q64SH-SUH 以寬壓、高速 SPI、毫秒級(jí)擦寫和低功耗特性,為 IPC 攝像頭提供固件、配置與算法的可靠存儲(chǔ)。適用于安防監(jiān)控、智能家居及電池供電場(chǎng)景,助力終端小型化、低功耗與持續(xù)在線。
    的頭像 發(fā)表于 08-01 10:05 ?693次閱讀
    普冉<b class='flag-5'>NOR</b> <b class='flag-5'>FLASH</b>助力IPC攝像頭高效<b class='flag-5'>運(yùn)行</b>

    如何將Flash刷寫程序放到SRAM中運(yùn)行?

    客戶要求Flash driver不能存儲(chǔ)在Flash中,需要在升級(jí)的時(shí)候,由CAN FBL發(fā)送到SRAM中,再運(yùn)行SRAM中的Flash driver 我應(yīng)該如何
    發(fā)表于 07-15 07:22

    MCU片上Flash

    保留能力,支持多次擦寫操作,是MCU程序存儲(chǔ)的核心介質(zhì)。 主要類型? NOR Flash?:支持隨機(jī)訪問,可直接運(yùn)行代碼,適用于實(shí)時(shí)性要求高的場(chǎng)景。 NAND
    的頭像 發(fā)表于 05-06 14:26 ?868次閱讀

    在OpenVINO?中運(yùn)行應(yīng)用程序失敗怎么解決?

    嘗試在 OpenVINO? 中運(yùn)行我的推理應(yīng)用程序失敗,并出現(xiàn)以下錯(cuò)誤: RuntimeError: Check \'false\' failed at src/core/src/runtime/ov_tensor.cpp:67: Dims and format are
    發(fā)表于 03-05 10:29

    羅徹斯特電子為傳統(tǒng)應(yīng)用提供卓越的內(nèi)存支持 為并行NOR Flash提供持續(xù)供貨支持

    為并行NOR Flash提供持續(xù)供貨支持 憑借羅徹斯特電子的生產(chǎn)能力,能夠持續(xù)供應(yīng)并行NOR Flash。不論是傳統(tǒng)還是成熟產(chǎn)品對(duì)于此類產(chǎn)品都有持續(xù)需求。通過戰(zhàn)略性安排,羅徹斯特電子購(gòu)
    發(fā)表于 12-17 10:33 ?484次閱讀