花了接近30个小时,网上资料聊聊无几,从如何用Keil下载NOR Flash,到如何执行,怎么让SDRAM用起来,一步一步,坑很多,但是都过去了.首先给个下载地址好了:LPC1788空白工程
先一步一步说说,首先就是初始化EMC[SDRAM+NOR],如果不会?那其实就是初始化各种IO,配置时序,还是不会吗?那算了,下面好像对你没什么意义了,我先发一下我的配置:
LPC_SC->PCONP |= (1 << 11); LPC_SC->EMCDLYCTL = 0x00101010; LPC_EMC->Control = 1; LPC_EMC->DynamicReadConfig = 1; LPC_EMC->DynamicRasCas0 = 0x00000303; LPC_EMC->DynamicRP = 0x00000002; LPC_EMC->DynamicRAS = 0x00000005; LPC_EMC->DynamicSREX = 0x00000009; LPC_EMC->DynamicAPR = 0x00000001; LPC_EMC->DynamicDAL = 0x00000005; LPC_EMC->DynamicWR = 0x00000002; LPC_EMC->DynamicRC = 0x00000007; LPC_EMC->DynamicRFC = 0x00000008; LPC_EMC->DynamicXSR = 0x00000009; LPC_EMC->DynamicRRD = 0x00000001; LPC_EMC->DynamicMRD = 0x00000003; LPC_EMC->DynamicConfig0 = 0x0000680; LPC_EMC->DynamicControl = 0x0183; for(i = 200 * 30; i; i--); LPC_EMC->DynamicControl = 0x0103; LPC_EMC->DynamicRefresh = 2; for(i = 256; i; --i); LPC_EMC->DynamicRefresh = 0x0000003A; LPC_EMC->DynamicControl = 0x00000083; i = *((volatile uint32_t *)(0xA0000000 | (0x33 << 12))); LPC_EMC->DynamicControl = 0x0000; LPC_EMC->DynamicConfig0 |= (1 << 19); LPC_EMC->StaticConfig1 = 0x00000081; LPC_EMC->StaticWaitWen1 = 0x01; LPC_EMC->StaticWaitOen1 = 0x01; LPC_EMC->StaticWaitRd1 = 0x1f; LPC_EMC->StaticWaitPage1 = 0x1f; LPC_EMC->StaticWaitWr1 = 0x1f; LPC_EMC->StaticWaitTurn1 = 0x0f;
CPU运行在120MHz,我的SDRAM型号是W9825G6JH[32MB],我的NOR Flash型号是SST39VF3201B[4MB].然后点开Target Options:
然后填写ROM,RAM大小:
当然,如果你愿意分区的话,你甚至可以拆开几个段来写.而且一般代码都在外部的话,可以默认ROM在外部,IROM是非默认的.另外所谓分段加载的SCT文件,不需要,我们每个文件自己定义~
然后需要编写Flash的算法,找来找去,就一个近似NOR的,拿来就改.切换到目录C:Keil_v5ARMFlashM29W640F,因为这个NOR时序跟我的还一样呢,于是打开FlashDev.c,加内容:
#ifdef SST39VF3201B struct FlashDevice const FlashDevice = { FLASH_DRV_VERS, // Driver Version, do not modify! "SST39VF3201B Flash", // Device Na me EXT16BIT, // Device Type 0x90000000, // Device Start Address 0x00400000, // Device Size in Bytes (4MB) 1024, // Programming Page Size 0, // Reserved, must be 0 0xFF, // Initial Content of Erased Memory 100, // Program Page Timeout 100 mSec 3000, // Erase Sector Timeout 3000 mSec // Specify Size and Address of Sectors 0x01000, 0x000000, // Sector Size 8kB ( 8 Sectors) SECTOR_END }; #endif
然后,打开选择编译,生成目标FLM文件,你需要这个工程么,给你提供下载好了.M29W640F
找到刚才工程生成的FLM文件[FLM文件也提供下载:SST39VF3201B],然后别忘了给自己仿真器多加点目标RAM[用的是目标芯片SRAM].
然而还不能下载,别急,因为你下载啊,需要一定的配置,比如说... 你还得先初始化总线,才能烧写对吧.所以我新建了一个文件叫SST39VF1601.ini啊,里面的内容,就是初始化了~
FUNC void PinSel(int p1, int n1, int f1) { _WDWORD(0x4002C000 + (p1 * 32 + n1) * 4, 0x8 | f1); } FUNC void InitNORFlash(void) { int i; PinSel(2,16,1); PinSel(2,17,1); PinSel(2,18,1); PinSel(2,20,1); PinSel(2,24,1); PinSel(2,28,1); PinSel(2,29,1); PinSel(2,30,1); PinSel(2,31,1); for(i = 0; i < 32; i++) PinSel(3,i,1); for(i = 0; i < 21; i++) PinSel(4,i,1); PinSel(4,24,1); PinSel(4,25,1); PinSel(4,30,1); PinSel(4,31,1); /* PCONP |= 1 << 11 */ _WDWORD(0x400FC0C4, 0x04288FDE); // Power On EMC /* EMCCONTROL |= 1 */ _WDWORD(0x2009C000, 0x00000001); // Enable EMC /* EMCDLYCTL */ _WDWORD(0x400FC1DC, 0x00081818); // Config data read delay /* EMCCONFIG */ _WDWORD(0x2009C008, 0x00000000); // Little endian mode /* STATICCONFIG1 */ _WDWORD(0x2009C220, 0x00000081); // 16bit data width // Disable asynchronous page mode // Read when active bits are low // No extend wait /* STATICWAITWEN1 */ _WDWORD(0x2009C224, 0x00000001); // WaitWEn /* STATICWAITOEN1 */ _WDWORD(0x2009C228, 0x00000001); // WaitOEn /* STATICWAITRD1 */ _WDWORD(0x2009C22C, 0x0000001F); // WaitRd /* STATICWAITPAGE1 */ _WDWORD(0x2009C230, 0x0000001F); // WaitPage /* STATICWAITWR1 */ _WDWORD(0x2009C234, 0x0000001F); // WaitWr /* STATICWAITTURN1 */ _WDWORD(0x2009C238, 0x0000000F); // WaitTurn _sleep_(100); }
对了,这不是C函数,只是语法有点相近.然后再新一个文件JLink_Flash.ini啊,内容:
INCLUDE SST39VF1601.ini InitNORFlash(); // Initialize memory
现在,Jlink 烧写片外Flash已经没压力,然而我要测试一下,所以新建了一个文件,内容如下:
#include#include "LPC177x_8x.h" #include "SDRAM_TB.h" uint32_t SDRAM_TB_RAM_A[0x400000]; uint32_t SDRAM_TB_RAM_B[0x400000]; void SDRAM_TB_RAM_FUNC(void){ uint32_t i; for(i = 0;i<0x400000;i++){ SDRAM_TB_RAM_A[i] = SDRAM_TB_RAM_B[i]; } for(i = 0;i<0x400000;i++){ if(SDRAM_TB_RAM_A[i] == SDRAM_TB_RAM_B[i]){ SDRAM_TB_RAM_B[i]++; }else{ while(1); } } }
然后右击这个文件,编辑属性,指定所用RAM和ROM的位置:
执行,爽吧:
另外发现了没,片外RAM根本没初始化数值哦~ 对了EMC,总线配置了这么多,是不是还差个NAND,NAND可以干嘛,当然是... 存图片啊,字库啊.因为我板子上还有一块K9F1G08U0C-PCB0,我擦,如果字库在这儿,然后XIP NOR执行,片内还有,我究竟什么时候才用的完这些资源啊.
配置NAND就简单了,初始化EMC时候多初始化一下,就OK了.
LPC_EMC->Config = 0x00000000; LPC_EMC->StaticConfig2 = 0x00000080; LPC_EMC->StaticWaitWen2 = 0x0; LPC_EMC->StaticWaitRd2 = 0x2; LPC_EMC->StaticWaitPage2 = 0x0; LPC_EMC->StaticWaitWr2 = 0x0; LPC_EMC->StaticWaitTurn2 = 0x0; *NandFlash_CLE = NandFlash_RESET;
但是,我想详细就下回分解..
老师好,咨询一下,我现在用的是LPC1788+SST39VF3201 需要把字库的BIN文件存储到SST39VF3201内,通过jflash进行烧写,但是无法直接写,那个算法文件该怎么写啊,还有写好了算法文件该怎么通过jflash添加进去呢?
@大白菜 算法文件Keil目录里也有参考.如果只是偶尔做,你可以在软件上做一个接口,比如串口接收,然后发送过去.