STM32利用DMA 和FSMC驱动ISSI 25616 外部SRAM 成功

发布者:老桃子最新更新时间:2017-02-06 来源: eefocus关键字:STM32  DMA  FSMC  驱动ISSI  外部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;

 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

 //enable FSMC bank1_NORSRAM
 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
}

//config DMA for FSMC
void DMA_Config_My(void)
{
 DMA_InitTypeDef  DMA_InitStructure;

 DMA_DeInit(DMA1_Channel4);
 DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)SRC_Const_Buffer;//The address of peripheral
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Bank1_SRAM3_ADDR;//The DAM RAM address
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//Peripheral is the source of data
 DMA_InitStructure.DMA_BufferSize =32;//32 times
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//The address of peripheral will be added
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//The address of DMA will be added
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//32 bits
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//32 bits
 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA Work in normal mode,not Circle
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA high Priority
 DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;// enable Memory to Memory transfer

 DMA_Init(DMA1_Channel4, &DMA_InitStructure);

 //Enable DMA1 channel 4 transfer complete interrupt
 DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
 //clear the flag
 DMA_ClearFlag(DMA1_FLAG_TC4);

 //Enable DAM1 channel4 transfer
 DMA_Cmd(DMA1_Channel4, ENABLE);

}

//config NVIC for DMA 1 channel 4
void NVIC_Config_My(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;

 NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel4_IRQn;//DMA1 channel 4 IRQ
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
 NVIC_Init(&NVIC_InitStructure);
}


关键字:STM32  DMA  FSMC  驱动ISSI  外部SRAM 引用地址:STM32利用DMA 和FSMC驱动ISSI 25616 外部SRAM 成功

上一篇:STM32|4-20mA输出电路
下一篇:ARM汇编指令的速查表、特点和格式

推荐阅读最新更新时间:2024-03-16 15:32

stm32-vref+ vref- vdda vssa
VDDA,VSSA则是模拟部分的电源,这个必须接,否则无法串口下载代码。
[单片机]
stm32专题十五:IIC通讯
IIC I2C 通讯协议(Inter-Integrated Circuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。 IIC总线物理层的特点: 1 它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个I2C通讯总线中,可连接多个I2C通讯设备,支持多个通讯主机及多个通讯从机; 2 一个I2C总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线 (SCL)。数据线即用来表示数据,时钟线用于数据收发同步; 3 每个连接到总线的设备都有一个独立
[单片机]
<font color='red'>stm32</font>专题十五:IIC通讯
使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信
本篇详细的记录了如何使用STM32CubeMX配置STM32F103C8T6的硬件SPI外设与DW1000通信,为移植DW1000官方驱动打下基础。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): DW1000模块 这里我连接到DW1000官方评估板上,直接与DW1000芯片通信: 连接方法 首先查看DW1000官方评估板预留的外接控制器SPI接口(J6接口)的引脚说明: 外部供电接口(J7)的引脚说明: ① 首先将DW1000官方评估板上的S1、S2拨码开关全部拨为OFF,这样配置之后才可以外接控制器。 ② 按照下图选择端子,配置为外部供电
[单片机]
使用<font color='red'>STM32</font>硬件SPI+STM32cubeMX+HAL库测试DW1000通信
stm32应用-简单的串口接收与发送程序
与上位机的串口通信是一个很常用的程序。碧海蓝天在刚刚接触stm32芯片时写的第一个简单程序就是串口通信,现在把程序代码甩出来与大家分享。完整的程序哦~一般人我不告诉他 库版本 :ST3.0.0 文件:mian.c //功能:串口初始化、打开定时器中断,然后一直接收数据状态就好了。发送在中断中实现 #include stm32f10x.h #include usart.h u8 USART_rx_data; int main(void) { RCC_Configuration(); //系统时钟配置 GPIO_Configuration(); //端口初始化 NVIC_Config
[单片机]
两片STM32之间I2C通信
硬件平台:master:stm32f401re slave:stm32f401ce 开发平台:keil 5.18 操作系统:win7 如上篇所讲,将401CE配置为I2C从机,并设置为从发送模式。 主机的I2C与从机相同,同样配置即可。同时增加uart设置,方便将接收到的数据打印出来。 主机的设置为主接收: printf( \n\rStart....\n\r ); /* Put I2C peripheral in reception process */ /* Timeout is set to 10S */ while(HAL_I2C_Master_Receive(&I2cHandle, (uint16
[单片机]
STM32高级开发(17)-使用DFU方案
什么是 DFU DFU全称为Device Firmware update,是ST官方推出的一个通过USB接口进行IAP升级的方案,同串口ISP一样,他们都集成在了芯片内部的Bootloader区段,可以通过配置boot引脚来启动。(具体可参照ST文档:AN2606)。不过内置DFU的芯片大部分型号都比较新,如果你用的型号没有内置DFU程序,没关系我们也可以通过CubeMX来快速生成和移植一个DFU功能程序到你的Flash中来使用。 DFU方案完整的组件包括单片机DFU Demo代码、PC端升级程序、PC端Demo代码以及相关资料手册等。通过使用DFU方案,我们可以快速的集成升级功能到开发的产品中,同时还能够快速的开发与之配套的
[单片机]
<font color='red'>STM32</font>高级开发(17)-使用DFU方案
STM32的CRC计算
CRC计算 CRC校验仅用于保证全双工通信的可靠性。数据发送和数据接收分别使用单独的CRC计算器。 通过对每一个接收位进行可编程的多项式运算来计算CRC。CRC的计算是在由SPI_CR1寄存器中CPHA和CPOL位定义的采样时钟边沿进行的。 注意: 该SPI接口提供了两种CRC计算方法,取决于所选的发送和/或接收的数据帧格式:8位数据帧采用CR8;16位数据帧采样CRC16-CCITT。 CRC计算是通过设置SPI_CR1寄存器中的CRCEN位启用的。设置CRCEN位时同时复位CRC寄存器(SPI_RXCRCR和SPI_TXCRCR)。当设置了SPI_CR1的CRCNEXT位,SPI_TXCRCR的内容将在当前字节
[单片机]
STM32触摸按键原理和电路设计
01触摸按键原理 触摸使用RC充放电原理: RC电路是指由电阻R和电容C组成的电路,它是脉冲产生和整形电路中常用的电路。 充电过程: 电源通过电阻给电容充电,由于一开始电容两端的电压为0,所以电压的电压都在电阻上,这时电流大,充电速度快。随着电容两端电压的上升,电阻两端的电压下降,电流也随之减小,充电速度小。充电的速度与电阻和电容的大小有关。电阻R越大,充电越慢,电容C越大,充电越慢。衡量充电速度的常数t(tao)=RC。 放电过程: 电容C通过电阻R放电,由于电容刚开始放电时电压为E,放电电流I=E/R,该电流很大,所以放电速度很快。随着电容不断的放电,电容的电压也随着下降。电流也很快减小。电容的放电速度与RC有关,R的阻值
[单片机]
<font color='red'>STM32</font>触摸按键原理和电路设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved