STM32单片机用FSMC接口控制SRAM
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:WIN7
开发环境:MDK4.72
MCU:STM32F103ZE
说明:
sram型号:IS62WV51216BLL
连接方式:FSMC
大小:1M字节.512K * 16
源代码:
inf_sram.h
/********************************************************************** sram接口层头文件* (c)copyright 2013,jdh* All Right Reserved*文件名:inf_sram.h*程序员:jdh*修改日期:2013/10/10* 2013/10/11**********************************************************************//********************************************************************** 说明*sram型号:IS62WV51216BLL*连接方式:FSMC*大小:1M字节.512K * 16**********************************************************************/#ifndef _INF_SRAM_H_#define _INF_SRAM_H_/********************************************************************** 头文件**********************************************************************/#include "stm32f10x.h"#include "stm32f10x_fsmc.h"/********************************************************************** 宏定义**********************************************************************//********************************************************************** SRAM2的BANK1起始地址**********************************************************************/#define Bank1_SRAM2_ADDR ((uint32_t)0x64000000)/********************************************************************** 函数**********************************************************************//********************************************************************** 初始化sram**********************************************************************/void inf_init_sram(void);/********************************************************************** 写入数据包*输入:pBuffer:数据指针* WriteAddr:写入数据地址* NumHalfwordToWrite:数据长度*返回:无**********************************************************************/void FSMC_SRAM_WriteBuffer(uint16_t* pBuffer,uint32_t WriteAddr,uint32_t NumHalfwordToWrite);/********************************************************************** 读取数据包*输入:pBuffer:存放数据的指针* ReadAddr:读取数据地址* NumHalfwordToRead:读取数据长度,单位半字,即2字节*返回:无**********************************************************************/void FSMC_SRAM_ReadBuffer(uint16_t* pBuffer, uint32_t ReadAddr, uint32_t NumHalfwordToRead);/********************************************************************** 写入半字数据*输入:WriteAddr:写入数据地址* data:数据*返回:无**********************************************************************/void FSMC_SRAM_WriteHalfWord(uint32_t WriteAddr, uint16_t data);/********************************************************************** 读取半字数据*输入:ReadAddr:读取数据地址*返回:读取的数据**********************************************************************/uint16_t FSMC_SRAM_ReadHalfWord(uint32_t ReadAddr);#endif
inf_sram.c
/********************************************************************** sram接口层头文件* (c)copyright 2013,jdh* All Right Reserved*文件名:inf_sram.c*程序员:jdh*修改日期:2013/10/10* 2013/10/11**********************************************************************//********************************************************************** 说明*sram型号:IS62WV51216BLL*连接方式:FSMC*大小:1M字节.512K * 16**********************************************************************//********************************************************************** 头文件**********************************************************************/#include "inf_sram.h"/********************************************************************** 函数**********************************************************************//********************************************************************** 初始化sram**********************************************************************/void inf_init_sram(void){ GPIO_InitTypeDef GPIO_InitStructure; FSMC_NORSRAMTimingInitTypeDef p; FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; //开启FSMC时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE); //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC | RCC_AHBPeriph_SRAM,ENABLE); //开启FSMC相关的IO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | \ RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | \ RCC_APB2Periph_AFIO, ENABLE); //FSMC相关的IO配置 //数据线 //PD口 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); //PE口 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); //地址线 //PF口 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); //PG口 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); //PD口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; GPIO_Init(GPIOD, &GPIO_InitStructure); //NOE和NWE配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_Init(GPIOD, &GPIO_InitStructure); //NE2配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOG, &GPIO_InitStructure); //NBL0, NBL1配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOE, &GPIO_InitStructure); //FSMC配置 //地址建立时间 p.FSMC_AddressSetupTime = 0; //地址保持时间 p.FSMC_AddressHoldTime = 0; //数据建立时间 p.FSMC_DataSetupTime = 5; //总线恢复时间 p.FSMC_BusTurnAroundDuration = 0; //时钟分频因子 p.FSMC_CLKDivision = 0; //数据产生时间 p.FSMC_DataLatency = 0; //控制器时序 p.FSMC_AccessMode = FSMC_AccessMode_A; //总线参数配置 //使用FSMC的Bank1的字块2 FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; //禁止地址数据线复用 FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; //存储类型为sram FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; //存储器位宽16位 FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; //关闭突发模式访问 FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; //使能突发访问模式后才有效,等待信号极性 FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; //使能突发访问模式后才有效,非对齐成组模式 FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //使能突发访问模式后才有效,配置等待时序 FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; //使能写操作 FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //使能突发访问模式后才有效,关闭等待信号 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; //扩展模式使能 FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; //成组写使能位 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; //读操作时序操作 FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; //写操作时序参数 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; //初始化FSMC总线 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //使能FSMC Bank1_SRAM Bank FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE); }/********************************************************************** 写入数据包*输入:pBuffer:数据指针* WriteAddr:写入数据地址* NumHalfwordToWrite:数据长度,单位半字,即2字节*返回:无**********************************************************************/void FSMC_SRAM_WriteBuffer(uint16_t* pBuffer,uint32_t WriteAddr,uint32_t NumHalfwordToWrite){ for(; NumHalfwordToWrite != 0; NumHalfwordToWrite--) { *(u16 *) (Bank1_SRAM2_ADDR + WriteAddr) = *pBuffer++; WriteAddr += 2; } }/********************************************************************** 读取数据包*输入:pBuffer:存放数据的指针* ReadAddr:读取数据地址* NumHalfwordToRead:读取数据长度,单位半字,即2字节*返回:无**********************************************************************/void FSMC_SRAM_ReadBuffer(uint16_t* pBuffer, uint32_t ReadAddr, uint32_t NumHalfwordToRead){ for(; NumHalfwordToRead != 0; NumHalfwordToRead--) { *pBuffer++ = *(vu16*) (Bank1_SRAM2_ADDR + ReadAddr); ReadAddr += 2; } }/********************************************************************** 写入半字数据*输入:WriteAddr:写入数据地址* data:数据*返回:无**********************************************************************/void FSMC_SRAM_WriteHalfWord(uint32_t WriteAddr, uint16_t data){ *(u16 *)(Bank1_SRAM2_ADDR + WriteAddr) = data;}/********************************************************************** 读取半字数据*输入:ReadAddr:读取数据地址*返回:读取的数据**********************************************************************/uint16_t FSMC_SRAM_ReadHalfWord(uint32_t ReadAddr){ return (*(vu16 *)((Bank1_SRAM2_ADDR + ReadAddr)));}
测试代码:
main.c
/********************************************************************** 无线定位基站程序* 主文件* (c)copyright 2013,jdh* All Right Reserved*文件名:main.c*程序员:jdh**********************************************************************//********************************************************************** 头文件**********************************************************************/#include "public.h"uint8_t test_sram[100] __attribute__((at(Bank1_SRAM2_ADDR)));/********************************************************************** 函数**********************************************************************/int main(void){ uint8_t i = 0; uint16_t buf1[3] = {1,2,3}; uint16_t buf2[10] = {0}; //初始化设备 init_device();#ifndef DEBUG //打开内部看门狗 inf_enable_iwdg();#endif //sram测试代码 //FSMC_SRAM_WriteHalfWord(0,1); //FSMC_SRAM_WriteHalfWord(2,2); //FSMC_SRAM_WriteHalfWord(4,3); //Test_Data = FSMC_SRAM_ReadHalfWord(2); //FSMC_SRAM_WriteBuffer(buf1,0,3); //FSMC_SRAM_ReadBuffer(buf2,0,3); test_sram[0] = 5; test_sram[1] = 2; test_sram[2] = 3; FSMC_SRAM_ReadBuffer(buf2,0,10); __nop(); //状态机执行 while (1) { for (i = 0;i < 6;i++) { //inf_set_led(i + 1,LED_ON); inf_delay_ms(10); //inf_set_led(i + 1,LED_OFF); inf_delay_ms(10); } }}#ifdef USE_FULL_ASSERT/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */void assert_failed(uint8_t* file, uint32_t line){ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { }}#endif