Cortex-M单片机下载数据到外部flash
2019-07-12 13:56发布
生成海报
主机环境:Windows 10 64bit开发环境:MDK 5.23目标板:LPC54114之前在NXP社区得到一块LPC54114的板卡,是由万利制作的,LPC54114是一款双核MCU,包含了一颗M4主核和一颗M0+从核,利用该板卡学习了一下双核MCU的开发流程,板卡中提供了一颗W25P80FLASH,之前拥有的板卡都没有挂外部FLASH,刚好之前利用LPC54608学习TouchGFX时可以把图片资源下载到外部FLASH中,因此借此机会来学习一下如何把数据下载到外部FLASH。平时烧录代码我们都是烧录到MCU内部的FLASH中,如下图:
可以看到下载的时片上256KB的FLASH,该算法文件是由DFP包提供的,具体可以在keil5的安装目录下找到,如下:
加载到内部FLASH的算法有了,但加载到外部FLASH的算法还没得。keil5中提供了LPC54608板卡的外部FLASH算法,LPC54114的外部FLASH算法就需要我们自己实现了,而且我们的板卡不是NXP官方的板卡,更不可能提供外部FLASH的加载算法了。。。进入到keil的FLASH目录,如下:
拷贝LPC5460x_MT25QL128文件夹到LPC54114_W25P80文件夹,并把其中有关信息全部替换成LPC54114相关信息。keil中提供了FlashOS.h头文件,定义了烧录到外部FLASH的相关接口,很简单,如下:
这就是本次我们需要实现的相关接口,修改的关键文件只有两个:FlashDev.c以及FlashPrg.c,首先看FlashDev.c文件,该文件定义了外部Flash的相关信息,经过简单修改就可以使用了,如下:[cpp] view plain copy- #ifdef W25P80
- struct FlashDevice const FlashDevice = {
- FLASH_DRV_VERS,
- "LPC54114 W25P80 SPI",
- EXTSPI,
- 0x10000000,
- 0x00100000,
- 256,
- 0,
- 0xFF,
- 300,
- 3000,
-
-
- 0x010000, 0x000000,
- SECTOR_END
- };
- #endif
我们只需要修改设备名字、设备类型、起始地址、大小、页大小、扇区大小等等,这些信息都可以在W25P80的手册中找到。其中设备的起始地址可以随便定义,但不要和内部FLASH地址冲突即可。这里定义的是0x10000000.FlashPrg.c文件是接口的实现文件,这里我把LPC54114SDK中的polling_flash下的驱动文件拿来直接使用了,即mx25r_flash.c/h文件,只需要在FlashPrg.c中简单调用即可,如下:[cpp] view plain copy-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include "..FlashOS.H" // FlashOS Structures
- #include "fsl_iocon.h"
- #include "fsl_spi.h"
- #include "mx25r_flash.h"
-
- #define SECTOR_ADDR 0
- #define SECTOR_SIZE 65536
- #define FLASH_SPI_SSEL 3
- #define EXAMPLE_SPI_MASTER SPI2
- #define EXAMPLE_SPI_MASTER_CLK_SRC kCLOCK_Flexcomm2
- #define EXAMPLE_SPI_MASTER_CLK_FREQ 12000000
- unsigned long base_adr;
- unsigned char chk_buf[256];
- struct mx25r_instance mx25r;
-
- void SPI_InitPins(void) {
-
- CLOCK_EnableClock(kCLOCK_Iocon);
-
-
- IOCON_PinMuxSet(IOCON, 0, 8, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN));
- IOCON_PinMuxSet(IOCON, 0, 9, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN));
- IOCON_PinMuxSet(IOCON, 0, 10, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN));
- IOCON_PinMuxSet(IOCON, 0, 2, (IOCON_FUNC2 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN));
- }
-
- int flash_transfer_cb(void *transfer_prv, uint8_t *tx_data, uint8_t *rx_data, size_t dataSize, bool eof)
- {
- spi_transfer_t xfer = {0};
- xfer.txData = tx_data;
- xfer.rxData = rx_data;
- xfer.dataSize = dataSize;
-
- if (eof)
- {
- xfer.configFlags |= kSPI_FrameAssert;
- }
- SPI_MasterTransferBlocking((SPI_Type *)transfer_prv, &xfer);
- return 0;
- }
-
- int flash_init(void)
- {
- spi_master_config_t masterConfig = {0};
- SPI_MasterGetDefaultConfig(&masterConfig);
- masterConfig.direction = kSPI_MsbFirst;
- masterConfig.polarity = kSPI_ClockPolarityActiveHigh;
- masterConfig.phase = kSPI_ClockPhaseFirstEdge;
- masterConfig.baudRate_Bps = 1000000;
- masterConfig.sselNum = (spi_ssel_t)FLASH_SPI_SSEL;
- SPI_MasterInit(EXAMPLE_SPI_MASTER, &masterConfig, EXAMPLE_SPI_MASTER_CLK_FREQ);
-
- mx25r_init(&mx25r, flash_transfer_cb, EXAMPLE_SPI_MASTER);
- return mx25r_err_ok;
- }
-
-
-
-
-
-
-
-
-
- int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
-
- SYSCON->FXCOMCLKSEL[2] = 0;
-
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮