FSMC结构体:
控制FSMC使用SRAM存储器时主要是配置时序寄存器以及控制寄存器,利用ST标准库的SRAM时序结构体以及初始化结构体可以很方便地写入参数。
时序结构体配置:
SRAM初始化结构体配置:
硬件连接:
操作的时候,就直接进行指针操作,向相应的地址写入和读出就行了,非常简单。
sram.c
#include "./sram/sram.h"
/**
* @brief 初始化控制SRAM的IO
* @param 无
* @retval 无
*/
static void SRAM_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能SRAM相关的GPIO时钟 */
/*地址信号线*/
RCC_APB2PeriphClockCmd(FSMC_A0_GPIO_CLK | FSMC_A1_GPIO_CLK | FSMC_A2_GPIO_CLK |
FSMC_A3_GPIO_CLK | FSMC_A4_GPIO_CLK | FSMC_A5_GPIO_CLK |
FSMC_A6_GPIO_CLK | FSMC_A7_GPIO_CLK | FSMC_A8_GPIO_CLK |
FSMC_A9_GPIO_CLK | FSMC_A10_GPIO_CLK| FSMC_A11_GPIO_CLK|
FSMC_A12_GPIO_CLK| FSMC_A13_GPIO_CLK|FSMC_A14_GPIO_CLK|
FSMC_A15_GPIO_CLK|FSMC_A16_GPIO_CLK|FSMC_A17_GPIO_CLK|FSMC_A18_GPIO_CLK|
/*数据信号线*/
FSMC_D0_GPIO_CLK | FSMC_D1_GPIO_CLK | FSMC_D2_GPIO_CLK |
FSMC_D3_GPIO_CLK | FSMC_D4_GPIO_CLK | FSMC_D5_GPIO_CLK |
FSMC_D6_GPIO_CLK | FSMC_D7_GPIO_CLK | FSMC_D8_GPIO_CLK |
FSMC_D9_GPIO_CLK | FSMC_D10_GPIO_CLK| FSMC_D11_GPIO_CLK|
FSMC_D12_GPIO_CLK| FSMC_D13_GPIO_CLK| FSMC_D14_GPIO_CLK|
FSMC_D15_GPIO_CLK|
/*控制信号线*/
FSMC_CS_GPIO_CLK | FSMC_WE_GPIO_CLK | FSMC_OE_GPIO_CLK |
FSMC_UDQM_GPIO_CLK|FSMC_LDQM_GPIO_CLK, ENABLE);
/*-- GPIO 配置 -----------------------------------------------------*/
/* 通用 GPIO 配置 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //配置为复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*A地址信号线 针对引脚配置*/
GPIO_InitStructure.GPIO_Pin = FSMC_A0_GPIO_PIN;
GPIO_Init(FSMC_A0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A1_GPIO_PIN;
GPIO_Init(FSMC_A1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A2_GPIO_PIN;
GPIO_Init(FSMC_A2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A3_GPIO_PIN;
GPIO_Init(FSMC_A3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A4_GPIO_PIN;
GPIO_Init(FSMC_A4_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A5_GPIO_PIN;
GPIO_Init(FSMC_A5_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A6_GPIO_PIN;
GPIO_Init(FSMC_A6_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A7_GPIO_PIN;
GPIO_Init(FSMC_A7_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A8_GPIO_PIN;
GPIO_Init(FSMC_A8_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A9_GPIO_PIN;
GPIO_Init(FSMC_A9_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A10_GPIO_PIN;
GPIO_Init(FSMC_A10_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A11_GPIO_PIN;
GPIO_Init(FSMC_A11_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A12_GPIO_PIN;
GPIO_Init(FSMC_A12_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A13_GPIO_PIN;
GPIO_Init(FSMC_A13_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A14_GPIO_PIN;
GPIO_Init(FSMC_A14_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A15_GPIO_PIN;
GPIO_Init(FSMC_A15_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A16_GPIO_PIN;
GPIO_Init(FSMC_A16_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A17_GPIO_PIN;
GPIO_Init(FSMC_A17_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A18_GPIO_PIN;
GPIO_Init(FSMC_A18_GPIO_PORT, &GPIO_InitStructure);
/*DQ数据信号线 针对引脚配置*/
GPIO_InitStructure.GPIO_Pin = FSMC_D0_GPIO_PIN;
GPIO_Init(FSMC_D0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D1_GPIO_PIN;
GPIO_Init(FSMC_D1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D2_GPIO_PIN;
GPIO_Init(FSMC_D2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D3_GPIO_PIN;
GPIO_Init(FSMC_D3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D4_GPIO_PIN;
GPIO_Init(FSMC_D4_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D5_GPIO_PIN;
GPIO_Init(FSMC_D5_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D6_GPIO_PIN;
GPIO_Init(FSMC_D6_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D7_GPIO_PIN;
GPIO_Init(FSMC_D7_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D8_GPIO_PIN;
GPIO_Init(FSMC_D8_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D9_GPIO_PIN;
GPIO_Init(FSMC_D9_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D10_GPIO_PIN;
GPIO_Init(FSMC_D10_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D11_GPIO_PIN;
GPIO_Init(FSMC_D11_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D12_GPIO_PIN;
GPIO_Init(FSMC_D12_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D13_GPIO_PIN;
GPIO_Init(FSMC_D13_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D14_GPIO_PIN;
GPIO_Init(FSMC_D14_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D15_GPIO_PIN;
GPIO_Init(FSMC_D15_GPIO_PORT, &GPIO_InitStructure);
/*控制信号线*/
GPIO_InitStructure.GPIO_Pin = FSMC_CS_GPIO_PIN;
GPIO_Init(FSMC_CS_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_WE_GPIO_PIN;
GPIO_Init(FSMC_WE_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_OE_GPIO_PIN;
GPIO_Init(FSMC_OE_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_UDQM_GPIO_PIN;
GPIO_Init(FSMC_UDQM_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_LDQM_GPIO_PIN;
GPIO_Init(FSMC_LDQM_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief 初始化FSMC外设
* @param None.
* @retval None.
*/
void FSMC_SRAM_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
/*初始化SRAM相关的GPIO*/
SRAM_GPIO_Config();
/*使能FSMC外设时钟*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);
//地址建立时间(ADDSET)为1个HCLK 1/72M=14ns
readWriteTiming.FSMC_AddressSetupTime = 0x00;
//地址保持时间(ADDHLD)模式A未用到
readWriteTiming.FSMC_AddressHoldTime = 0x00;
//数据保持时间(DATAST)+ 1个HCLK = 3/72M=42ns(对EM的SRAM芯片)
readWriteTiming.FSMC_DataSetupTime = 0x02;
//设置总线转换周期,仅用于复用模式的NOR操作
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
//设置时钟分频,仅用于同步类型的存储器
readWriteTiming.FSMC_CLKDivision = 0x00;
//数据保持时间,仅用于同步型的NOR
readWriteTiming.FSMC_DataLatency = 0x00;
//选择匹配SRAM的模式
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;
// 选择FSMC映射的存储区域: Bank1 sram3
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
//设置地址总线与数据总线是否复用,仅用于NOR
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_AsynchronousWait=FSMC_AsynchronousWait_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 = &readWriteTiming;
//读写同样时序,使用扩展模式时这个配置才有效
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); // 使能BANK
}
/**
* @brief 以“字”为单位向sdram写入数据
* @param pBuffer: 指向数据的指针
* @param uwWriteAddress: 要写入的SRAM内部地址
* @param uwBufferSize: 要写入数据大小
* @retval None.
*/
void SRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize)
{
__IO uint32_t write_pointer = (uint32_t)uwWriteAddress;
/* 循环写入数据 */
for (; uwBufferSize != 0; uwBufferSize--)
{
/* 发送数据到SRAM */
*(uint32_t *) (Bank1_SRAM3_ADDR + write_pointer) = *pBuffer++;
/* 地址自增*/
write_pointer += 4;
}
}
/**
* @brief 从SRAM中读取数据
* @param pBuffer: 指向存储数据的buffer
* @param ReadAddress: 要读取数据的地十
* @param uwBufferSize: 要读取的数据大小
* @retval None.
*/
void SRAM_ReadBuffer(uint32_t* pBuffer, uint32_t uwReadAddress, uint32_t uwBufferSize)
{
__IO uint32_t write_pointer = (uint32_t)uwReadAddress;
/*读取数据 */
for(; uwBufferSize != 0x00; uwBufferSize--)
{
*pBuffer++ = *(__IO uint32_t *)(Bank1_SRAM3_ADDR + write_pointer );
/* 地址自增*/
write_pointer += 4;
}
}
/**
* @brief 测试SRAM是否正常
* @param None
* @retval 正常返回1,异常返回0
*/
uint8_t SRAM_Test(void)
{
/*写入数据计数器*/
uint32_t counter=0;
/* 8位的数据 */
uint8_t ubWritedata_8b = 0, ubReaddata_8b = 0;
/* 16位的数据 */
uint16_t uhWritedata_16b = 0, uhReaddata_16b = 0;
SRAM_INFO("正在检测SRAM,以8位、16位的方式读写sram...");
/*按8位格式读写数据,并校验*/
/* 把SRAM数据全部重置为0 ,IS62WV51216_SIZE是以8位为单位的 */
for (counter = 0x00; counter < IS62WV51216_SIZE; counter++)
{
*(__IO uint8_t*) (Bank1_SRAM3_ADDR + counter) = (uint8_t)0x0;
}
/* 向整个SRAM写入数据 8位 */
for (counter = 0; counter < IS62WV51216_SIZE; counter++)
{
*(__IO uint8_t*) (Bank1_SRAM3_ADDR + counter) = (uint8_t)(ubWritedata_8b + counter);
}
/* 读取 SRAM 数据并检测*/
for(counter = 0; counter<IS62WV51216_SIZE;counter++ )
{
ubReaddata_8b = *(__IO uint8_t*)(Bank1_SRAM3_ADDR + counter); //从该地址读出数据
if(ubReaddata_8b != (uint8_t)(ubWritedata_8b + counter)) //检测数据,若不相等,跳出函数,返回检测失败结果。
{
SRAM_ERROR("8位数据读写错误!");
return 0;
}
}
/*按16位格式读写数据,并检测*/
/* 把SRAM数据全部重置为0 */
for (counter = 0x00; counter < IS62WV51216_SIZE/2; counter++)
{
*(__IO uint16_t*) (Bank1_SRAM3_ADDR + 2*counter) = (uint16_t)0x00;
}
/* 向整个SRAM写入数据 16位 */
for (counter = 0; counter < IS62WV51216_SIZE/2; counter++)
{
*(__IO uint16_t*) (Bank1_SRAM3_ADDR + 2*counter) = (uint16_t)(uhWritedata_16b + counter);
}
/* 读取 SRAM 数据并检测*/
for(counter = 0; counter<IS62WV51216_SIZE/2;counter++ )
{
uhReaddata_16b = *(__IO uint16_t*)(Bank1_SRAM3_ADDR + 2*counter); //从该地址读出数据
if(uhReaddata_16b != (uint16_t)(uhWritedata_16b + counter)) //检测数据,若不相等,跳出函数,返回检测失败结果。
{
SRAM_ERROR("16位数据读写错误!");
return 0;
}
}
SRAM_INFO("SRAM读写测试正常!");
/*检测正常,return 1 */
return 1;
}
sram.h
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
//使用NOR/SRAM的 Bank1.sector3,地址位HADDR[27,26]=10
//对IS61LV25616/IS62WV25616,地址线范围为A0~A17
//对IS61LV51216/IS62WV51216,地址线范围为A0~A18
#define Bank1_SRAM3_ADDR ((uint32_t)(0x68000000))
#define IS62WV51216_SIZE 0x100000 //512*16/2bits = 0x100000 ,1M字节
/*A地址信号线*/
#define FSMC_A0_GPIO_PORT GPIOF
#define FSMC_A0_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A0_GPIO_PIN GPIO_Pin_0
#define FSMC_A1_GPIO_PORT GPIOF
#define FSMC_A1_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A1_GPIO_PIN GPIO_Pin_1
#define FSMC_A2_GPIO_PORT GPIOF
#define FSMC_A2_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A2_GPIO_PIN GPIO_Pin_2
#define FSMC_A3_GPIO_PORT GPIOF
#define FSMC_A3_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A3_GPIO_PIN GPIO_Pin_3
#define FSMC_A4_GPIO_PORT GPIOF
#define FSMC_A4_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A4_GPIO_PIN GPIO_Pin_4
#define FSMC_A5_GPIO_PORT GPIOF
#define FSMC_A5_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A5_GPIO_PIN GPIO_Pin_5
#define FSMC_A6_GPIO_PORT GPIOF
#define FSMC_A6_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A6_GPIO_PIN GPIO_Pin_12
#define FSMC_A7_GPIO_PORT GPIOF
#define FSMC_A7_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A7_GPIO_PIN GPIO_Pin_13
#define FSMC_A8_GPIO_PORT GPIOF
#define FSMC_A8_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A8_GPIO_PIN GPIO_Pin_14
#define FSMC_A9_GPIO_PORT GPIOF
#define FSMC_A9_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A9_GPIO_PIN GPIO_Pin_15
#define FSMC_A10_GPIO_PORT GPIOG
#define FSMC_A10_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A10_GPIO_PIN GPIO_Pin_0
#define FSMC_A11_GPIO_PORT GPIOG
#define FSMC_A11_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A11_GPIO_PIN GPIO_Pin_1
#define FSMC_A12_GPIO_PORT GPIOG
#define FSMC_A12_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A12_GPIO_PIN GPIO_Pin_2
#define FSMC_A13_GPIO_PORT GPIOG
#define FSMC_A13_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A13_GPIO_PIN GPIO_Pin_3
#define FSMC_A14_GPIO_PORT GPIOG
#define FSMC_A14_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A14_GPIO_PIN GPIO_Pin_4
#define FSMC_A15_GPIO_PORT GPIOG
#define FSMC_A15_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A15_GPIO_PIN GPIO_Pin_5
#define FSMC_A16_GPIO_PORT GPIOD
#define FSMC_A16_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A16_GPIO_PIN GPIO_Pin_11
#define FSMC_A17_GPIO_PORT GPIOD
#define FSMC_A17_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A17_GPIO_PIN GPIO_Pin_12
#define FSMC_A18_GPIO_PORT GPIOD
#define FSMC_A18_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A18_GPIO_PIN GPIO_Pin_13
/*D 数据信号线*/
#define FSMC_D0_GPIO_PORT GPIOD
#define FSMC_D0_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D0_GPIO_PIN GPIO_Pin_14
#define FSMC_D1_GPIO_PORT GPIOD
#define FSMC_D1_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D1_GPIO_PIN GPIO_Pin_15
#define FSMC_D2_GPIO_PORT GPIOD
#define FSMC_D2_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D2_GPIO_PIN GPIO_Pin_0
#define FSMC_D3_GPIO_PORT GPIOD
#define FSMC_D3_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D3_GPIO_PIN GPIO_Pin_1
#define FSMC_D4_GPIO_PORT GPIOE
#define FSMC_D4_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D4_GPIO_PIN GPIO_Pin_7
#define FSMC_D5_GPIO_PORT GPIOE
#define FSMC_D5_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D5_GPIO_PIN GPIO_Pin_8
#define FSMC_D6_GPIO_PORT GPIOE
#define FSMC_D6_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D6_GPIO_PIN GPIO_Pin_9
#define FSMC_D7_GPIO_PORT GPIOE
#define FSMC_D7_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D7_GPIO_PIN GPIO_Pin_10
#define FSMC_D8_GPIO_PORT GPIOE
#define FSMC_D8_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D8_GPIO_PIN GPIO_Pin_11
#define FSMC_D9_GPIO_PORT GPIOE
#define FSMC_D9_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D9_GPIO_PIN GPIO_Pin_12
#define FSMC_D10_GPIO_PORT GPIOE
#define FSMC_D10_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D10_GPIO_PIN GPIO_Pin_13
#define FSMC_D11_GPIO_PORT GPIOE
#define FSMC_D11_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D11_GPIO_PIN GPIO_Pin_14
#define FSMC_D12_GPIO_PORT GPIOE
#define FSMC_D12_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D12_GPIO_PIN GPIO_Pin_15
#define FSMC_D13_GPIO_PORT GPIOD
#define FSMC_D13_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D13_GPIO_PIN GPIO_Pin_8
#define FSMC_D14_GPIO_PORT GPIOD
#define FSMC_D14_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D14_GPIO_PIN GPIO_Pin_9
#define FSMC_D15_GPIO_PORT GPIOD
#define FSMC_D15_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D15_GPIO_PIN GPIO_Pin_10
/*控制信号线*/
/*CS片选*/
/*NE3 ,对应的基地址0x68000000*/
#define FSMC_CS_GPIO_PORT GPIOG
#define FSMC_CS_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_CS_GPIO_PIN GPIO_Pin_10
/*WE写使能*/
#define FSMC_WE_GPIO_PORT GPIOD
#define FSMC_WE_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_WE_GPIO_PIN GPIO_Pin_5
/*OE读使能*/
#define FSMC_OE_GPIO_PORT GPIOD
#define FSMC_OE_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_OE_GPIO_PIN GPIO_Pin_4
/*LB数据掩码*/
#define FSMC_UDQM_GPIO_PORT GPIOE
#define FSMC_UDQM_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_UDQM_GPIO_PIN GPIO_Pin_1
/*UB数据掩码*/
#define FSMC_LDQM_GPIO_PORT GPIOE
#define FSMC_LDQM_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_LDQM_GPIO_PIN GPIO_Pin_0
/*信息输出*/
#define SRAM_DEBUG_ON 1
#define SRAM_INFO(fmt,arg...) printf("<<-SRAM-INFO->> "fmt"\n",##arg)
#define SRAM_ERROR(fmt,arg...) printf("<<-SRAM-ERROR->> "fmt"\n",##arg)
#define SRAM_DEBUG(fmt,arg...) do{\
if(SRAM_DEBUG_ON)\
printf("<<-SRAM-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\
}while(0)
void FSMC_SRAM_Init(void);
void FSMC_SRAM_WriteBuffer(uint8_t* pBuffer,uint32_t WriteAddr,uint32_t NumHalfwordToWrite);
void FSMC_SRAM_ReadBuffer(uint8_t* pBuffer,uint32_t ReadAddr,uint32_t NumHalfwordToRead);
uint8_t SRAM_Test(void);
然后在主函数main.c中进行测试:
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./sram/sram.h"
/*绝对定位方式访问SRAM,这种方式必须定义成全局变量*/
uint8_t testValue __attribute__((at(Bank1_SRAM3_ADDR)));
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
LED_GPIO_Config();
//串口初始化
Debug_USART_Config();
//初始化外部SRAM
FSMC_SRAM_Init();
printf ( "\r\n外部 SRAM 测试\r\n" );
/*蓝灯亮,表示正在读写SRAM测试*/
LED_BLUE;
/*对SRAM进行读写测试,检测SRAM是否正常*/
if(SRAM_Test()==1)
{
//测试正常 绿灯亮
LED_GREEN;
}
else
{
//测试失败 红灯亮
LED_RED;
}
/*指针方式访问SRAM*/
{
uint32_t temp;
printf("\r\n指针方式访问SRAM\r\n");
/*向SRAM写入8位数据*/
*( uint8_t*) (Bank1_SRAM3_ADDR ) = (uint8_t)0xAA;
printf("\r\n指针访问SRAM,写入数据0xAA \r\n");
/*从SRAM读取数据*/
temp = *( uint8_t*) (Bank1_SRAM3_ADDR );
printf("读取数据:0x%X \r\n",temp);
/*写/读 16位数据*/
*( uint16_t*) (Bank1_SRAM3_ADDR+10 ) = (uint16_t)0xBBBB;
printf("指针访问SRAM,写入数据0xBBBB \r\n");
temp = *( uint16_t*) (Bank1_SRAM3_ADDR+10 );
printf("读取数据:0x%X \r\n",temp);
/*写/读 32位数据*/
*( uint32_t*) (Bank1_SRAM3_ADDR+20 ) = (uint32_t)0xCCCCCCCC;
printf("指针访问SRAM,写入数据0xCCCCCCCC \r\n");
temp = *( uint32_t*) (Bank1_SRAM3_ADDR+20 );
printf("读取数据:0x%X \r\n",temp);
}
/*绝对定位方式访问SRAM,这种方式必须定义成全局变量*/
{
testValue = 0xDD;
printf("\r\n绝对定位访问SRAM,写入数据0xDD,读出数据0x%X,变量地址为%X\r\n",testValue,(uint32_t )&testValue);
}
}