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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

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

從零編寫STM32H7的MDK SPI FLASH下載算法

嵌入式應用研究院 ? 來源:AIoT開源項目分享 ? 2023-02-13 11:05 ? 次閱讀

Part1前言

當我們要下載編譯好的鏡像到Flash時,首先要做的一步就是選擇合適的Flash下載算法,而這個算法本身就是一個FLM文件:
ba495eb6-ab47-11ed-bfe3-dac502259ad0.png

代碼既可以下載到內(nèi)部flash,也可以下載到外部flash,或者一部分下載到內(nèi)部,一部分下載到外部。

Part2一、將代碼中的圖片資源下載到外部flash

在UI設計中往往需要大量的圖片和字體,圖片和字體資源在代碼中以靜態(tài)數(shù)組的形式存在,這些大數(shù)組在內(nèi)部flash中一般存放不下,所以需要把這些占用資源比較大的數(shù)組放在外部flash中,然后通過QSPI地址映射的方式訪問,或者通過SPI將flash中的資源分批讀取到RAM緩存中使用。

通過MDK打開分散加載文件,配置“ExtFlashSection”段:

;*************************************************************
;***Scatter-LoadingDescriptionFilegeneratedbyuVision***
;*************************************************************

LR_IROM10x080000000x00020000{;loadregionsize_region
ER_IROM10x080000000x00020000{;loadaddress=executionaddress
*.o(RESET,+First)
*(InRoot$$Sections)
.ANY(+RO)
.ANY(+XO)
}
RW_IRAM10x200000000x00020000{;RWdata
.ANY(+RW+ZI)
}
RW_IRAM20x240000000x00080000{
.ANY(+RW+ZI)
}
}

LR_EROM10x900000000x01000000{;loadregionsize_region
ER_EROM10x900000000x01000000{;loadaddress=executionaddress
*.o(ExtFlashSection)
*.o(FontFlashSection)
*.o(TextFlashSection)
}
}

添加LR_EROM1 段,起始地址為0x90000000 ,大小為0x01000000 。

在代碼中將圖片資源分配到ExtFlashSection段

#defineLOCATION_ATTRIBUTE(name)__attribute__((section(name)))__attribute__((aligned(4)))

KEEPexternconstunsignedcharimage_watch_seconds[]LOCATION_ATTRIBUTE("ExtFlashSection")=//4x202ARGB8888pixels.
{
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0xff,
0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0xff,
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0xff,
0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0xff,
0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0xff,
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0xff,
0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0xff,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,0xf8,0xfc,0xf8,0x00,
0xf8,0xfc,0xf8,0x00
};

編譯代碼

ba57c58c-ab47-11ed-bfe3-dac502259ad0.png

查看map文件,image_watch_seconds這個數(shù)組已經(jīng)被分配到了0X90138690這個地址了,這個地址正是LR_EROM1 所在的區(qū)間。

Part3二、MDK下載算法原理

1程序能夠通過下載算法下載到芯片的原理

通過MDK創(chuàng)建一批與地址信息無關(guān)的函數(shù),實現(xiàn)的功能主要有初始化,擦除,編程,讀取,校驗等,然后MDK調(diào)試下載階段,會將算法文件加載到芯片的內(nèi)部RAM里面(加載地址可以通過MDK設置),然后MDK通過與這個算法文件的交互,實現(xiàn)程序下載,調(diào)試階段數(shù)據(jù)讀取等操作。

2算法程序中擦除操作執(zhí)行流程

ba6f50da-ab47-11ed-bfe3-dac502259ad0.png

算法程序中擦除操作執(zhí)行流程

加載算法到芯片RAM。

執(zhí)行初始化函數(shù)Init。

執(zhí)行擦除操作,根據(jù)用戶的MDK配置,這里可以選擇整個芯片擦除或者扇區(qū)擦除。

執(zhí)行Uinit函數(shù)。

操作完畢。

3制作FLM文件步驟

ARM:CMSIS Pack文件夾(通常是C:KeilARMPackARMCMSIS version Device_Template_Flash)中的工程復制到一個新文件夾中,取消文件夾的只讀屬性,重命名項目文件NewDevice.uvprojx以表示新的flash 設備名稱,例如MyDevice.uvprojx。

打開工程,從工具欄中,使用下拉選擇目標來選擇處理器架構(gòu)。

打開對話框Project - Options for Target - Output并更改Name of Executable字段的內(nèi)容以表示設備,例如MyDevice。

調(diào)整文件FlashPrg中的編程算法。

調(diào)整文件FlashDev中的設備參數(shù)。

使用Project - Build Target生成新的 Flash 編程算法。

以上步驟是利用官方的工程模板修改代碼,這種方式網(wǎng)上已有很多教程(推薦使用這種方法),不再重復介紹,接下來介紹一種不使用模板工程制作的方法,目的是為了了解其實現(xiàn)原理。

Part4三、使用STM32CubeMX新建工程

4新建工程

硬件平臺: RT-Thread官方ART-PI H750開發(fā)版

軟件: STM32CubeMX,MDK

選擇MCU型號(STM32H750XBH6)

ba7f747e-ab47-11ed-bfe3-dac502259ad0.png

選擇MCU型號

配置SPI

baa37bb2-ab47-11ed-bfe3-dac502259ad0.png


配置SPI

配置UART

babdbb94-ab47-11ed-bfe3-dac502259ad0.png

配置UART

配置時鐘

bacf7ff0-ab47-11ed-bfe3-dac502259ad0.png

配置時鐘樹

設置調(diào)試接口

bae35e4e-ab47-11ed-bfe3-dac502259ad0.png

設置調(diào)試接口

設置工程并生成工程

baf613ae-ab47-11ed-bfe3-dac502259ad0.png

生成工程

52. 移植SFUD串行 Flash 通用驅(qū)動庫

SFUD 是什么

SFUD(https://github.com/armink/SFUD) 是一款開源的串行 SPI Flash 通用驅(qū)動庫。由于現(xiàn)有市面的串行 Flash 種類居多,各個 Flash 的規(guī)格及命令存在差異, SFUD 就是為了解決這些 Flash 的差異現(xiàn)狀而設計,讓我們的產(chǎn)品能夠支持不同品牌及規(guī)格的 Flash,提高了涉及到 Flash 功能的軟件的可重用性及可擴展性,同時也可以規(guī)避 Flash 缺貨或停產(chǎn)給產(chǎn)品所帶來的風險。

主要特點:支持 SPI/QSPI 接口、面向?qū)ο螅ㄍ瑫r支持多個 Flash 對象)、可靈活裁剪、擴展性強、支持 4 字節(jié)地址

資源占用

標準占用:RAM:0.2KB ROM:5.5KB

最小占用:RAM:0.1KB ROM:3.6KB

設計思路:

什么是 SFDP :它是 JEDEC (固態(tài)技術(shù)協(xié)會)制定的串行 Flash 功能的參數(shù)表標準,最新版 V1.6B (點擊這里查看)。該標準規(guī)定了,每個 Flash 中會存在一個參數(shù)表,該表中會存放 Flash 容量、寫粒度、擦除命令、地址模式等 Flash 規(guī)格參數(shù)。目前,除了部分廠家舊款 Flash 型號會不支持該標準,其他絕大多數(shù)新出廠的 Flash 均已支持 SFDP 標準。所以該庫在初始化時會優(yōu)先讀取 SFDP 表參數(shù)。

不支持 SFDP 怎么辦 :如果該 Flash 不支持 SFDP 標準,SFUD 會查詢配置文件 ( /sfud/inc/sfud_flash_def.h ) 中提供的 Flash 參數(shù)信息表 中是否支持該款 Flash。如果不支持,則可以在配置文件中添加該款 Flash 的參數(shù)信息。獲取到了 Flash 的規(guī)格參數(shù)后,就可以實現(xiàn)對 Flash 的全部操作。

移植SFUD

將下載到sfud源代碼放置在工程目錄中

bb0bb33a-ab47-11ed-bfe3-dac502259ad0.png

將sfud添加到工程目錄:

bb22a432-ab47-11ed-bfe3-dac502259ad0.png

修改sfud_port.c文件:

#include
#include
#include
#include"gpio.h"
#include"spi.h"

typedefstruct{
SPI_HandleTypeDef*spix;
GPIO_TypeDef*cs_gpiox;
uint16_tcs_gpio_pin;
}spi_user_data,*spi_user_data_t;

staticspi_user_dataspi1;
staticcharlog_buf[256];
voidsfud_log_debug(constchar*file,constlongline,constchar*format,...);
externintrt_vsnprintf(char*buf,intsize,constchar*fmt,va_listargs);
externintrt_kprintf(constchar*fmt,...);
staticvoidspi_lock(constsfud_spi*spi)
{

}

staticvoidspi_unlock(constsfud_spi*spi)
{

}
/*about100microseconddelay*/
staticvoiddelay_100us(void){
uint32_tdelay=2000;
while(delay--);
}
/**
*SPIwritedatathenreaddata
*/
staticsfud_errspi_write_read(constsfud_spi*spi,constuint8_t*write_buf,size_twrite_size,uint8_t*read_buf,
size_tread_size)
{
sfud_errresult=SFUD_SUCCESS;
/**
*addyourspiwriteandreadcode
*/
spi_user_data_tspi_dev=(spi_user_data_t)spi->user_data;

HAL_GPIO_WritePin(spi_dev->cs_gpiox,spi_dev->cs_gpio_pin,GPIO_PIN_RESET);
if(write_size){
HAL_SPI_Transmit(spi_dev->spix,(uint8_t*)write_buf,write_size,1);
}
if(read_size){
HAL_SPI_Receive(spi_dev->spix,read_buf,read_size,1);
}
exit:
HAL_GPIO_WritePin(spi_dev->cs_gpiox,spi_dev->cs_gpio_pin,GPIO_PIN_SET);
returnresult;
}

sfud_errsfud_spi_port_init(sfud_flash*flash)
{
sfud_errresult=SFUD_SUCCESS;

switch(flash->index){
caseSFUD_W25Q128_DEVICE_INDEX:{
spi1.spix=&hspi1;
spi1.cs_gpiox=GPIOA;
spi1.cs_gpio_pin=GPIO_PIN_4;
/*同步Flash移植所需的接口及數(shù)據(jù)*/
flash->spi.wr=spi_write_read;
flash->spi.lock=spi_lock;
flash->spi.unlock=spi_unlock;
flash->spi.user_data=&spi1;
/*about100microseconddelay*/
flash->retry.delay=delay_100us;
/*adout60secondstimeout*/
flash->retry.times=60*10000;

break;
}
}

returnresult;
}

voidsfud_log_debug(constchar*file,constlongline,constchar*format,...){
va_listargs;

/*argspointtothefirstvariableparameter*/
va_start(args,format);
rt_kprintf("[SFUD](%s:%ld)",file,line);
/*mustusevprintftoprint*/
rt_vsnprintf(log_buf,sizeof(log_buf),format,args);
rt_kprintf("%s
",log_buf);
va_end(args);
}

voidsfud_log_info(constchar*format,...){
va_listargs;

/*argspointtothefirstvariableparameter*/
va_start(args,format);
rt_kprintf("[SFUD]");
/*mustusevprintftoprint*/
rt_vsnprintf(log_buf,sizeof(log_buf),format,args);
rt_kprintf("%s
",log_buf);
va_end(args);
}

測試SFUD

在main.c中添加測試代碼:

/*USERCODEENDHeader*/
/*Includes------------------------------------------------------------------*/
#include"main.h"
#include"spi.h"
#include"usart.h"
#include"gpio.h"

/*Privatefunctionprototypes-----------------------------------------------*/
voidSystemClock_Config(void);
staticvoidMPU_Config(void);
/*USERCODEBEGINPFP*/
externintrt_kprintf(constchar*fmt,...);
#include"sfud.h"
/*USERCODEENDPFP*/

/*Privateusercode---------------------------------------------------------*/
/*USERCODEBEGIN0*/
#defineSFUD_DEMO_TEST_BUFFER_SIZE1024

staticuint8_tsfud_demo_test_buf[SFUD_DEMO_TEST_BUFFER_SIZE];
/**
*SFUDdemoforthefirstflashdevicetest.
*
*@paramaddrflashstartaddress
*@paramsizetestflashsize
*@paramsizetestflashdatabuffer
*/
staticvoidsfud_demo(uint32_taddr,size_tsize,uint8_t*data){
sfud_errresult=SFUD_SUCCESS;
constsfud_flash*flash=sfud_get_device_table()+0;
size_ti;
/*preparewritedata*/
for(i=0;iname,addr,
size);
}else{
rt_kprintf("Erasethe%sflashdatafailed.
",flash->name);
return;
}
/*writetest*/
result=sfud_write(flash,addr,size,data);
if(result==SFUD_SUCCESS){
rt_kprintf("Writethe%sflashdatafinish.Startfrom0x%08X,sizeis%d.
",flash->name,addr,
size);
}else{
rt_kprintf("Writethe%sflashdatafailed.
",flash->name);
return;
}
/*readtest*/
result=sfud_read(flash,addr,size,data);
if(result==SFUD_SUCCESS){
rt_kprintf("Readthe%sflashdatasuccess.Startfrom0x%08X,sizeis%d.Thedatais:
",flash->name,addr,
size);
rt_kprintf("Offset(h)000102030405060708090A0B0C0D0E0F
");
for(i=0;iname);
}
/*datacheck*/
for(i=0;iname);
break;
}
}
if(i==size){
rt_kprintf("The%sflashtestissuccess.
",flash->name);
}
}

/*USERCODEEND0*/

intmain(void)
{

/*MPUConfiguration--------------------------------------------------------*/
MPU_Config();

/*MCUConfiguration--------------------------------------------------------*/

/*Resetofallperipherals,InitializestheFlashinterfaceandtheSystick.*/
HAL_Init();

SystemClock_Config();

MX_GPIO_Init();
MX_SPI1_Init();
MX_UART4_Init();
/*USERCODEBEGIN2*/
if(sfud_init()==SFUD_SUCCESS){
sfud_demo(0,sizeof(sfud_demo_test_buf),sfud_demo_test_buf);
}

while(1)
{

}

}

#endif/*USE_FULL_ASSERT*/

運行如下:

bb3c7448-ab47-11ed-bfe3-dac502259ad0.png

63.制作下載算法

重新生成不帶main函數(shù)的工程

bb518982-ab47-11ed-bfe3-dac502259ad0.png

添加修改編程算法文件FlashPrg.c

模板工程里面提供了FlashOS.h和FlashPrg.c ,復制到此工程中,然后對FlashPrg.c 代碼進行填充。

#include"FlashOS.H"
#include"sfud.h"
#include"gpio.h"
#include"usart.h"
#include"spi.h"

staticuint32_tbase_adr;

/*
*InitializeFlashProgrammingFunctions
*Parameter:adr:DeviceBaseAddress
*clk:ClockFrequency(Hz)
*fnc:FunctionCode(1-Erase,2-Program,3-Verify)
*ReturnValue:0-OK,1-Failed
*/

#ifdefinedFLASH_MEM||definedFLASH_OTP
intInit(unsignedlongadr,unsignedlongclk,unsignedlongfnc)
{
MX_GPIO_Init();
MX_UART4_Init();
MX_SPI1_Init();
base_adr=adr;
if(sfud_init()==SFUD_SUCCESS){
return0;
}else{
return1;
}
}
#endif


/*
*De-InitializeFlashProgrammingFunctions
*Parameter:fnc:FunctionCode(1-Erase,2-Program,3-Verify)
*ReturnValue:0-OK,1-Failed
*/

#ifdefinedFLASH_MEM||definedFLASH_OTP
intUnInit(unsignedlongfnc)
{

return(0);
}
#endif

/*
*ErasecompleteFlashMemory
*ReturnValue:0-OK,1-Failed
*/

intEraseChip(void)
{
intresult=0;
constsfud_flash*flash=sfud_get_device_table();
/*AddyourCode*/
result=sfud_erase(flash,0,flash->chip.capacity);

if(result==SFUD_SUCCESS)
return0;
else
returnresult;//FinishedwithoutErrors
}

/*
*EraseSectorinFlashMemory
*Parameter:adr:SectorAddress
*ReturnValue:0-OK,1-Failed
*/

#ifdefFLASH_MEM
intEraseSector(unsignedlongadr)
{
intresult=0;
uint32_tblock_start;
constsfud_flash*flash;
flash=sfud_get_device_table();
block_start=adr-base_adr;
result=sfud_erase(flash,block_start,4096);

if(result==SFUD_SUCCESS)
return0;
else
returnresult;
}
#endif


/*
*ProgramPageinFlashMemory
*Parameter:adr:PageStartAddress
*sz:PageSize
*buf:PageData
*ReturnValue:0-OK,1-Failed
*/

#ifdefinedFLASH_MEM||definedFLASH_OTP
intProgramPage(unsignedlongblock_start,unsignedlongsize,unsignedchar*buffer)
{
constsfud_flash*flash=sfud_get_device_table()+0;
uint32_tstart_addr=block_start-base_adr;

if(sfud_write(flash,start_addr,size,buffer)==SFUD_SUCCESS)
return0;
else
return1;
}


#definePAGE_SIZE4096
uint8_taux_buf[PAGE_SIZE];
unsignedlongVerify(unsignedlongadr,unsignedlongsz,unsignedchar*buf)
{
inti;
constsfud_flash*flash=sfud_get_device_table();
sfud_read(flash,adr-base_adr,sz,aux_buf);

for(i=0;i

在工程中定義FLASH_MEM宏

bb607762-ab47-11ed-bfe3-dac502259ad0.png

添加修改配置文件FlashDev.c

模板工程里面提供了FlashDev.c ,復制到此工程中,然后對代碼進行修改。

#include"FlashOS.H"

#ifdefFLASH_MEM
structFlashDeviceconstFlashDevice={
FLASH_DRV_VERS,//DriverVersion,donotmodify!
"STM32H750-ARTPI",//DeviceName
EXTSPI,//DeviceType
0x90000000,//DeviceStartAddress
0x08000000,//DeviceSizeinBytes(128MB)
0x00001000,//ProgrammingPageSize4096Bytes
0x00,//Reserved,mustbe0
0xFF,//InitialContentofErasedMemory
10000,//ProgramPageTimeout100mSec
6000,//EraseSectorTimeout6000mSec

//SpecifySizeandAddressofSectors
0x1000,0x000000,//SectorSize4kB
SECTOR_END
};
#endif//FLASH_MEM

特別注意:"STM32H750-ARTPI"就是MDK的Option選項里面會識別出這個名字。0x90000000是MDK分散加載文件中定義的外部flash起始地址。

地址無關(guān)代碼實現(xiàn)

C和匯編的配置勾選上:


bb747ece-ab47-11ed-bfe3-dac502259ad0.pngbb90c69c-ab47-11ed-bfe3-dac502259ad0.png

ROPI地址無關(guān)實現(xiàn)

如果程序的所有只讀段都與位置無關(guān),則該程序為只讀位置無關(guān)(ROPI, Read-only position independence)。ROPI段通常是位置無關(guān)代碼(PIC,position-independent code),但可以是只讀數(shù)據(jù),也可以是PIC和只讀數(shù)據(jù)的組合。選擇“ ROPI”選項,可以避免用戶不得不將代碼加載到內(nèi)存中的特定位置。這對于以下例程特別有用:

(1)加載以響應運行事件。

(2)在不同情況下使用其他例程的不同組合加載到內(nèi)存中。

(3)在執(zhí)行期間映射到不同的地址。

RWPI數(shù)據(jù)無關(guān)實現(xiàn)使用Read-Write position independence同理,表示的可讀可寫數(shù)據(jù)段。使用RWPI編譯代碼,解決RW段即全局變量的加載。首先編譯的時候會為每一個全局變量生成一個相對于r9寄存器的偏移量,這個偏移量會在.text段中。

在加載elf階段,將RW段加載到RAM當中之后,需要將r9寄存器指向此片內(nèi)存的基地址,然后接下來就可以跳轉(zhuǎn)到加載的elf的代碼中去執(zhí)行,就可以實現(xiàn)全局變量的加載了。這也就是利用MDK的FLM文件生成通用flash驅(qū)動中提到的需要在編譯選項中添加-ffixed-r9的原因。

綜上所述,勾選ROPI和RWPI選項,可以實現(xiàn)elf文件的動態(tài)加載,還遺留的一個小問題是elf模塊如何調(diào)用系統(tǒng)函數(shù),這與此文無關(guān),留在以后再講。

特別注意:

由于模塊中不含中斷向量表,所以程序中不要開啟任何中斷。

startup_stm32h750xx.s不再需要參與編譯

bba03280-ab47-11ed-bfe3-dac502259ad0.png

修改分散加載文件

復制一份新的分散加載文件到工程目錄中,然后修改成如下代碼

bbaff440-ab47-11ed-bfe3-dac502259ad0.png


--diag_suppress L6305用于屏蔽沒有入口地址的警告信息。

;LinkerControlFile(scatter-loading)
;

PRG0PI;ProgrammingFunctions
{
PrgCode+0;Code
{
*(+RO)
}
PrgData+0;Data
{
*(+RW,+ZI)
}
}

DSCR+0;DeviceDescription
{
DevDscr+0
{
FlashDev.o
}
}

將程序可執(zhí)行文件axf修改為flm格式

通過這個cmd.exe /C copy "!L" "..@L.FLM"命令可以將生成的axf可執(zhí)行文件修改為flm。


bbcda490-ab47-11ed-bfe3-dac502259ad0.pngbbe256b0-ab47-11ed-bfe3-dac502259ad0.png


將生成的flm文件拷貝到...Keil_v5ARMFlash目錄,即可被MDK識別到。

DEMO下載地址:https://gitee.com/Aladdin-Wang/STM32H7_W25QXXX

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

    關(guān)注

    10

    文章

    1650

    瀏覽量

    149561
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4646

    瀏覽量

    93746
  • SPI
    SPI
    +關(guān)注

    關(guān)注

    17

    文章

    1731

    瀏覽量

    92898
  • MDK
    MDK
    +關(guān)注

    關(guān)注

    4

    文章

    209

    瀏覽量

    32260
  • 編寫
    +關(guān)注

    關(guān)注

    0

    文章

    29

    瀏覽量

    8528

原文標題:從零編寫STM32H7的MDK SPI FLASH下載算法

文章出處:【微信號:嵌入式應用研究院,微信公眾號:嵌入式應用研究院】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    MDK下載算法制作方法

    第36章 STM32F407的SPI 總線應用之SPI FlashMDK下載
    發(fā)表于 08-10 06:18

    講解STM32CubeProg下載算法制作方法

    第85章 STM32H7SPI 總線應用之SPI FlashSTM32CubeProg下載
    發(fā)表于 08-10 06:23

    STM32H7的內(nèi)部Flash和QSPI Flash混合執(zhí)行程序的優(yōu)勢

    第83章 STM32H7的內(nèi)部Flash和QSPI Flash都運行程序的混合方式(強烈推薦)本章節(jié)為大家講解內(nèi)部Flash和外部QSPI Flas
    發(fā)表于 08-18 06:57

    STM32H7教程】第19章 STM32H7的GPIO應用之按鍵FIFO

    STM32H7教程】第19章 STM32H7的GPIO應用之按鍵FIFO
    發(fā)表于 11-23 18:21 ?9次下載
    【<b class='flag-5'>STM32H7</b>教程】第19章 <b class='flag-5'>STM32H7</b>的GPIO應用之按鍵FIFO

    STM32H7學習之路繼續(xù)(stm32H7系列3) GPIO

    STM32H7學習之路繼續(xù)(stm32H7系列3) GPIO
    發(fā)表于 11-30 12:36 ?20次下載
    <b class='flag-5'>STM32H7</b>學習之路繼續(xù)(<b class='flag-5'>stm32H7</b>系列3)  GPIO

    STM32H7】第20章 ThreadX GUIX漢字顯示(QSPI Flash全字庫)

    STM32H7】第20章 ThreadX GUIX漢字顯示(QSPI Flash全字庫)
    發(fā)表于 12-02 09:36 ?14次下載
    【<b class='flag-5'>STM32H7</b>】第20章 ThreadX GUIX漢字顯示(QSPI <b class='flag-5'>Flash</b>全字庫)

    STM32H7教程】第21章 STM32H7的NVIC中斷分組和配置(重要)

    STM32H7教程】第21章 STM32H7的NVIC中斷分組和配置(重要)
    發(fā)表于 12-04 14:36 ?13次下載
    【<b class='flag-5'>STM32H7</b>教程】第21章 <b class='flag-5'>STM32H7</b>的NVIC中斷分組和配置(重要)

    "STM32H7學習繼續(xù)(STM32H7系列5)第十七章比較實用,以后寫程序的時候會用到"

    "STM32H7學習繼續(xù)(STM32H7系列5)第十七章比較實用,以后寫程序的時候會用到"
    發(fā)表于 12-05 11:21 ?9次下載
    "<b class='flag-5'>STM32H7</b>學習繼續(xù)(<b class='flag-5'>STM32H7</b>系列5)第十七章比較實用,以后寫程序的時候會用到"

    STM32H7教程】第8章 STM32H7的終極調(diào)試組件Event Recorder

    STM32H7教程】第8章 STM32H7的終極調(diào)試組件Event Recorder
    發(fā)表于 12-05 20:06 ?7次下載
    【<b class='flag-5'>STM32H7</b>教程】第8章 <b class='flag-5'>STM32H7</b>的終極調(diào)試組件Event Recorder

    STM32H7教程】第14章 STM32H7的電源,復位和時鐘系統(tǒng)

    STM32H7教程】第14章 STM32H7的電源,復位和時鐘系統(tǒng)
    發(fā)表于 12-09 11:21 ?36次下載
    【<b class='flag-5'>STM32H7</b>教程】第14章 <b class='flag-5'>STM32H7</b>的電源,復位和時鐘系統(tǒng)

    AN4936_STM32F7STM32H7的軟件移植

    AN4936_STM32F7STM32H7的軟件移植
    發(fā)表于 11-21 17:06 ?5次下載
    AN4936_<b class='flag-5'>從</b><b class='flag-5'>STM32F7</b>到<b class='flag-5'>STM32H7</b>的軟件移植

    PM0253_STM32F7STM32H7單片機編程手冊

    PM0253_STM32F7STM32H7單片機編程手冊
    發(fā)表于 11-24 08:29 ?18次下載
    PM0253_<b class='flag-5'>STM32F7</b>和 <b class='flag-5'>STM32H7</b>單片機編程手冊

    STM32H7技術(shù)詳解

    電子發(fā)燒友網(wǎng)站提供《STM32H7技術(shù)詳解.pdf》資料免費下載
    發(fā)表于 08-01 14:49 ?5次下載
    <b class='flag-5'>STM32H7</b>技術(shù)詳解

    不能連接上STM32H7芯片

    不能連接上STM32H7芯片
    的頭像 發(fā)表于 09-18 10:58 ?1632次閱讀
    不能連接上<b class='flag-5'>STM32H7</b>芯片

    STM32H7以太網(wǎng)的MMC中斷

    電子發(fā)燒友網(wǎng)站提供《STM32H7以太網(wǎng)的MMC中斷.pdf》資料免費下載
    發(fā)表于 09-20 09:11 ?0次下載
    <b class='flag-5'>STM32H7</b>以太網(wǎng)的MMC中斷