本次操作的SRAM的型號(hào)是IS62WV51216,是高速,8M位靜態(tài)SRAM。它采用ISSI(Intergrated Silicon Solution, Inc)公司的高性能CMOS技術(shù),按照512K個(gè)字(16)位進(jìn)行組織存儲(chǔ)單元。其具有高性能、低功耗特點(diǎn)。為方便用戶擴(kuò)展SRAM的存儲(chǔ)空間,為用戶有提供了兩個(gè)片選引腳;此外,含有兩個(gè)字節(jié)控制信號(hào)UB和LB,可方便用戶按字節(jié)訪問SRAM或按字訪問SRAM。IS62WV51216具有45ns/55ns訪問速度,因?yàn)槭侨o態(tài)操作,因此無需外部時(shí)鐘和刷新要求。
IS62WV51216功能框圖
IS62WV51216有地址譯碼器、數(shù)據(jù)IO、控制邏輯和存儲(chǔ)陣列四部分構(gòu)成。地址譯碼器將19根地址線上的輸入進(jìn)行譯碼,將譯碼值與內(nèi)部存儲(chǔ)陣列的單元地址進(jìn)行建立映射。數(shù)據(jù)IO是SRAM是主控制器數(shù)據(jù)交互的通道,訪問數(shù)據(jù)時(shí),即可字節(jié)進(jìn)行訪問也可按字訪問,按字節(jié)訪問功能增強(qiáng)了其與8位機(jī)的兼容性??刂七壿嫴糠职ㄗx和寫的選通信號(hào),以及字節(jié)訪問和片選引腳。
在硬件連接上,SRAM與STM32F4通過FSMC接口進(jìn)行互連。SRAM的片選信號(hào)CE與FSMC的NE3連接在一起。由此可知,SRAM被映射到Bank1的第3個(gè)存儲(chǔ)區(qū)當(dāng)中,顯然,其首地址為0x68000000。由于SRAM的數(shù)據(jù)口有16根數(shù)據(jù)線,因此為加快訪問速度,提高數(shù)據(jù)吞吐量,這里仍將數(shù)據(jù)寬度設(shè)置為16位寬。
此時(shí),F(xiàn)SMC接口的一個(gè)地址,映射到AHB地址時(shí)對(duì)應(yīng)2個(gè)地址空間,即u16數(shù)據(jù)類型所占寬度。但是,當(dāng)用戶按字節(jié)AHB地址空間時(shí),如讀取的是兩個(gè)相鄰字節(jié)地址空間(地址按2個(gè)字節(jié)對(duì)齊),則顯然此時(shí)映射到FSMC接口時(shí),地址是一個(gè)值,此時(shí)用戶操作AHB地址空間中低地址的字節(jié),即相當(dāng)于操作了FSMC對(duì)應(yīng)地址的低字節(jié),而當(dāng)用戶操作AHB地址窠中高地址字節(jié)時(shí),則相當(dāng)于操作了FSMC同一地址空間中的高字節(jié),即FSMC地址空間可以不變,但通過SRAM的UB和LB,分別訪問了同一地址的不同字節(jié)。同理,由于UB和LB的存在,可以按字節(jié)操作FSMC接口的外部設(shè)備。
SRAM的初始化函數(shù)如下
void SRAM_Init()
{
//1. 開時(shí)鐘PD/PE/PF/PG
RCC- >AHB1ENR |= 0XF< 3;
//其他所有引腳復(fù)用為FSMC
/*
LCD_CS:PG12
RS:PF12 = >FSMC_A[6]
WR:PD5
RD:PD4
D0-D1:PD14/PD15
D2-D3:PD0/PD1
D4-D12:PE7-PE15
D13-D15:PD8-PD10
*/
//2. PD(配置為復(fù)用)
GPIOD- >MODER &= ~(0XF< 0 | 0XF< 8 | 0X3F< 16 | 0xf< 28);
GPIOD- >MODER |= 0X0a< 0 | 0xa< 8 | 0x2a < 16 |0xa< 28; //PD口復(fù)用
GPIOD- >OTYPER &= ~(0X3< 0 | 0X3< 4 | 0X7< 8 | 0X3< 14); //推挽
GPIOD- >OSPEEDR |= (0XF< 0 | 0XF< 8 | 0X3F< 16 | 0xf< 28); //速度100Mhz
GPIOD- >PUPDR &= ~(0XF< 0 | 0XF< 8 | 0X3F< 16 | 0xf< 28); //無上下拉
GPIOD- >MODER &= 0XF03FFFFF; //PD11-PD13
GPIOD- >MODER |= 0X0A800000;
GPIOD- >OTYPER &= ~(0X7< 11);
GPIOD- >OSPEEDR |= 0X3F< 22;
GPIOD- >PUPDR &= ~(0X3F< 22);
//PE口配置
GPIOE- >MODER &= 0X00003FFF;
GPIOE- >MODER |= 0Xaaaa8000; //PE復(fù)用
GPIOE- >OTYPER &= 0X007F; //PE7-15推挽
GPIOE- >OSPEEDR |= 0XFFFFC000; //PE7-15速度為100Mhz
GPIOE- >PUPDR &= 0X00003FFF; //PE7-15無上下拉
GPIOE- >MODER &= 0XFFFFFFF0;
GPIOE- >MODER |= 0X0000000A; //PE0/1復(fù)用
GPIOE- >OTYPER &= 0XFFFFFFFC;
GPIOE- >OSPEEDR |= 0X0000000F;
GPIOE- >PUPDR &= 0XFFFFFFF0;
//FP12
GPIOF- >MODER &= ~(0X3< 24);
GPIOF- >MODER |= 2< 24;
GPIOF- >OTYPER &= ~(1< 12); //推挽
GPIOF- >OSPEEDR |= 0X3< 24; //100mHZ
GPIOF- >PUPDR &= ~(0X3< 24); //無上下拉
// fsmc_a0~fsmc_a5:PF0~PF5
// FSMC_A7~FSMC_A9:PF13~PF15
GPIOF- >MODER &= 0X03FFF000;
GPIOF- >MODER |= 0XA8000AAA;
GPIOF- >OTYPER &= ~(0X3F< 0 | 7< 13); //推挽
GPIOF- >OSPEEDR |= 0XFC000FFF; //100mHZ
GPIOF- >PUPDR &= 0X03FFF000; //無上下拉
//FG10
GPIOG- >MODER &= ~(0X3< 20);
GPIOG- >MODER |= 2< 20;
GPIOG- >OTYPER &= ~(1< 10); //推挽
GPIOG- >OSPEEDR |= 0X3< 20; //100mHZ
GPIOG- >PUPDR &= ~(0X3< 20); //無上下拉
// FSMC_A10~FSMC_A15:PG0~PG5
GPIOG- >MODER &= 0XFFFFF000;
GPIOG- >MODER |= 0X00000AAA;
GPIOG- >OTYPER &= ~(0X3F< 0); //推挽
GPIOG- >OSPEEDR |= 0X00000fff; //100mHZ
GPIOG- >PUPDR &= 0XFFFFF000; //無上下拉
//選擇復(fù)用的功能:復(fù)用為FSMC
//復(fù)用功能選擇
//PD:PD0/1/4/5/8-15
GPIOD- >AFR[0] &= 0XFF00FF00;
GPIOD- >AFR[0] |= 0x00cc00cc; //PD0/1/4/5復(fù)用為FSMC
GPIOD- >AFR[1] = 0;
GPIOD- >AFR[1] |= 0XCCCCCCCC; //PD8-15:復(fù)用為FSMC
//PE:
GPIOE- >AFR[0] &= 0X0FFFFF00;
GPIOE- >AFR[0] |= 0XC00000CC; //PE7復(fù)用為FSMC
GPIOE- >AFR[1] &= 0x00000000;
GPIOE- >AFR[1] |= 0XCCCCCCCC; //PE8-15復(fù)用,可以直接往AFR[1]中賦值
//PF:0-5 12-15
GPIOF- >AFR[0] &= 0xff000000;
GPIOF- >AFR[0] |= 0X00CCCCCC; //PF0-5復(fù)用為FSMC
GPIOF- >AFR[1] &= 0x0000ffff;
GPIOF- >AFR[1] |= 0XCCCC0000; //PF12-15復(fù)用為FSMC
//PG:0-5 10
GPIOG- >AFR[0] &= 0xff000000;
GPIOG- >AFR[0] |= 0X00CCCCCC; //PF0-5復(fù)用為FSMC
GPIOG- >AFR[1] &= 0xfffFf0ff;
GPIOG- >AFR[1] |= 0X00000C00; //PG10復(fù)用為FSMC
//配置FSMC
//3. 開FSMC時(shí)鐘
RCC- >AHB3ENR |= 1< 0;
//4. 配置FSMC寄存器
//BCR3
FSMC_Bank1- >BTCR[4] &= ~(1< 19); //始終在異步模式下操作
FSMC_Bank1- >BTCR[4] &= ~(1< 15); //不考慮等待信號(hào)
FSMC_Bank1- >BTCR[4] |= 1< 14; //使能擴(kuò)展功能,即讀寫時(shí)序分開
FSMC_Bank1- >BTCR[4] &= ~(1< 13); //禁止等待nWait信號(hào)
FSMC_Bank1- >BTCR[4] |= 1< 12; //使能寫操作
FSMC_Bank1- >BTCR[4] &= ~(0x3< 4);
FSMC_Bank1- >BTCR[4] |= 1< 4; //16位數(shù)據(jù)寬度
FSMC_Bank1- >BTCR[4] &= ~(0x3< 2); //存儲(chǔ)器類型為:SRAM
//BTR4:
//BTR4(讀時(shí)序)
FSMC_Bank1- >BTCR[5] &= ~(0x3< 28); //異步模式A
FSMC_Bank1- >BTCR[5] |= 0xf< 16; //總線周轉(zhuǎn)階段持續(xù)時(shí)間為默認(rèn)值
FSMC_Bank1- >BTCR[5] &= 0xffff00ff;
FSMC_Bank1- >BTCR[5] |= 5< 8; //DATAST為5HCLK
FSMC_Bank1- >BTCR[5] |= 0x10< 0; //ADDSET為10HCLK
//BWTR(寫時(shí)序)
FSMC_Bank1E- >BWTR[4] = 0;
FSMC_Bank1E- >BWTR[4] &= ~(0x3< 28); //異步模式A
FSMC_Bank1E- >BWTR[4] |= 0xf< 16; //總線周轉(zhuǎn)階段持續(xù)時(shí)間為默認(rèn)值
FSMC_Bank1E- >BWTR[4] |= 8< 8; //DATAST為3個(gè)HCLK
FSMC_Bank1E- >BWTR[4] |= 0< 0; //ADDSET為3個(gè)HCLK
//使能存儲(chǔ)塊
FSMC_Bank1- >BTCR[4] |= 1< 0;
}
在主函數(shù)中調(diào)用SRAM初始化函數(shù),就可以直接操作SRAM,使用SRAM需要用到C語言中__attribute__ ((at()),絕對(duì)定位的應(yīng)用。
u16 buf[512] __attribute__((at(SRAM_ADD+0)));//定位到RAM中起始地址為SRAM_ADD處
定位到SRAM中,一般用于數(shù)據(jù)量比較大的緩存,如串口的接收緩存,再就是某個(gè)位置的特定變量。
主函數(shù)
#include "usart.h"
#include "stdio.h"
#include "stm32f4xx.h"
#include "stdlib.h"
#include "sram.h"
//注意:SRAM的使用空間為:0x68000000 ~ 0x680fffff
//所以,開辟空間時(shí),要保證開辟的空間在SRAM內(nèi)
u16 buf[512] __attribute__((at(SRAM_ADD+0)));
int main()
{
u32 i=0;
Usart1_Init(115200);
SRAM_Init();
for(i=0;i< 512;i++)
buf[i] = 0;
for(i=0;i< 512;i++)
buf[i] = i;
while(1)
{
for(i=0;i< 512;i++)
printf("buf[%d] = %drn",i,buf[i]);
}
}
編譯后燒入程序運(yùn)行,串口助手中可以看到打印出了寫入SRAM中的數(shù)據(jù)。
評(píng)論
查看更多