STM32利用DMA 和FSMC驱动ISSI 25616 外部SRAM 成功
扫描二维码
随时随地手机看文章
去年把STM32的DMA试了一下,好像用过了M2M模式,测试时从STM32 自带的FLASH to RAM,使用的32bit宽度数据,测试成功,然后又用了DMA给DAC送数据,产生方波,三角波,正弦波等。
用过DMA后就用了FSMC驱动9325TFT,由于当时不知道液晶上标的引脚有错误,一直不成功,郁闷好久,最后才知道,参考了一下网上的程序,成功用了CPU 加FSMC驱动了TFT,不用IO口模拟。
既然TFT驱动成功了,然后我就很想用FSMC总线驱动板子上的ISSI 25616 的512Kb外部SRAM,但是经过我的很多尝试,都是失败的,找了很多原因都不行,一直不能理解,而且很郁闷。这个学期开学,换了一个板子,一下就成功了,可能以前的硬件有点问题吧,只能这样说吧。
既然DMA和FSMC都成功了,我原来也就想到既然TFT也是利用FSMC映射到STM32寻址的4G空间,那么按理说也可以用DMA的M2M进行数据传输,我把液晶映射到的地址是0x68000000,但是我试了很久都是不行的,找了好久资料,好像有人说成功,可以的,我就一直郁闷,但是直到今天终于成功了。
这次测试的不是TFT,因为我的板子上这时没有TFT,就用外部SRAM进行了测试了。外部SRAM用FSMC总线成功了,想提高速度,节约CPU时间,让其处理其他事情。昨晚从四点多一直调到了十点多,没有成功,而且把我气个半死,越来越变态的问题都发生了,比如FLASH to RAM 16bit DMA失败,FLASH的数组居然存储到0x00000020,而且完全错误,简直是变态,本来就该0x08000000以上的地址,JLINK错误,MDK 自动关掉,那六个多小时把我快整疯了。今天决定弄不好不吃饭,仔细对比由于是我地址宏定义写错了,还有一个地方赋值错了,我一直没有发现,因为很像。
好了就好,好了就好……
贴上我的部分关健代码,但是百度空间不会高亮编程关键字,看起来不是很爽啊
//Today it is the fisrt time when I test DMA+FSMC to drive ISSI 25616 SRAM successfully
//The first time I test DMA M2M success 2010 10 14
//The first time I test FSMC to drive 9325TFT success 2010 11 4
//The first time I test FSMC to drive ISSI25616 SRAM success 2011 2 28
//by ACM不挂科 928765096
//from HDU
//2011 3 16
//Note :we can use this to drive TFT,it can save CPU time to do other things
#include"DMA_FSMC.h"
#define BufferSize 32
#define Bank1_SRAM3_ADDR ((uint32_t)0x68000000)
const uint32_t SRC_Const_Buffer[BufferSize]= {
0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80};
void RCC_Config_My(void)
{
ErrorStatus HSEStartUpStatus;//The flag for test if success
RCC_HSEConfig(RCC_HSE_ON);//use extern clock
HSEStartUpStatus = RCC_WaitForHSEStartUp();//wait for HSE OK
if(HSEStartUpStatus== SUCCESS)//if it is OK
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK(AHB clock)
RCC_PCLK1Config(RCC_HCLK_Div2);//PCLK1(APB1 clock) can't over 36MHz
RCC_PCLK2Config(RCC_HCLK_Div1);//PCLK2(APB2 clock) can't over 72MHz
FLASH_SetLatency(FLASH_Latency_2);//FLASH clock control,SYSCLK0~24MHz Latency=0.SYSCLK25~48MHz Latency =1.SYSCLk 48~72MHz Latency=2
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);//HSE if use for SYSTEM clock,PLL is 72MHz
RCC_PLLCmd(ENABLE);// enable PLL
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);//wait for PLL OK
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//System clock is PLL clock
while(RCC_GetSYSCLKSource()!=0x08);//wait for System clock is OK
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//enable DMA1 clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);//enable FSMC clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE |
RCC_APB2Periph_GPIOF, ENABLE);
}
}
void SRAM_FSMC_Config_My(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
GPIO_InitTypeDef GPIO_InitStructure;
//config SRAM DATA lines configuration D0------->>D15
//please reference STC datasheet FSMC PINs Page37
//D0---->>D3 D13------->>D15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//D4----->>D12
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_Init(GPIOE, &GPIO_InitStructure);
//config SRAM ADRESS lines configuration A0------->>A18
//please reference STC datasheet FSMC PINs Page37
//A0------>>A9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOF, &GPIO_InitStructure);
//A10---->>A15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOG, &GPIO_InitStructure);
//A16------->>A18
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//config SRAM NOE NWE lines configuration
//please reference STC datasheet FSMC PINs Page37
//NOE-->PD4
//NWE ----->PD5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//config SRAM NE3 lines configuration
//please reference STC datasheet FSMC PINs Page37
//NE4-->PG12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOG, &GPIO_InitStructure);
//config SRAM NBL0, NBL1 lines configuration
//please reference STC datasheet FSMC PINs Page37
//NBL0(LB)-->PE0 NBL1(UB)-->PE1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOE, &GPIO_InitStructure);
//FSMC Structure Config
p.FSMC_AddressSetupTime = 0;//The time is used for duration address set up time
p.FSMC_AddressHoldTime = 0;//The time is used for duration address hold time
p.FSMC_DataSetupTime = 2;//The time is used for duration data set up time
p.FSMC_BusTurnAroundDuration = 0;//The time is used for the duration Bus turn
p.FSMC_CLKDivision = 0;//The division of HCLK
p.FSMC_DataLatency = 0;//The time is memory clock cycle before get first data
p.FSMC_AccessMode = FSMC_AccessMode_A;//
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;//choose FSMC bank
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;//Address and Data line is not muxed
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;//The type of externed memory
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//The memory data widthy
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;//disable burst access ,because this is only used for synchronous memory
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;//only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;//only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;//enable write
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;//only used in burst mode
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;//disable extended mode
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;//disable burst write mode
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;