当前位置: 首页 > news >正文

怎么创建网站建设什么网站做电子元器件

怎么创建网站建设,什么网站做电子元器件,建设六马路小学 网站,dede世界杯网站模板目录 前言 1. SRAM控制原理 1.1 SRAM功能框图 1.2 SRAM读写时序 2. FSMC简介 2.1 FSMC架构 2.2 FSMC地址映射 2.3 FSMC控制SRAM时序 3. FSMC结构体 4. 库函数配置FSMC 5. 实验程序 5.1 main.c 5.2 SRAM.c 5.3 SRAM.h 前言 STM32F4自带了192K字节的SRAM#xff1…目录 前言 1. SRAM控制原理 1.1 SRAM功能框图 1.2 SRAM读写时序 2. FSMC简介 2.1 FSMC架构 2.2 FSMC地址映射 2.3 FSMC控制SRAM时序 3. FSMC结构体 4. 库函数配置FSMC 5. 实验程序 5.1 main.c 5.2 SRAM.c 5.3 SRAM.h 前言 STM32F4自带了192K字节的SRAM对于一般的应用来说192K字节已经够用了但是对于那些对内存要求比较高的192K字节是远远不够用的为此STM32F4板载了一个1M字节的SRAM芯片IS62WV51216以满足大内存的需求。         IS62WV51216是ISSIIntegrated Silicon Solution Inc公司生产的一颗16位宽512K512*16即1M字节下面会做精确讲解计算为什么是512*16又为什么是1M字节容量的CMOS静态内存SRAM芯片。 1. SRAM控制原理 STM32控制器芯片内部有一定大小的SRAM及FLASH作为内存和程序存储空间但是当程序比较大时内存和程序空间不足时就需要STM32芯片的外部扩展存储器了。  实际生活中不管是我们使用手机还是电脑我们常常说的运行内存8128、12256中的8G和12G实际上是执行内存而我们下载APP或者游戏所消耗的内存是存储内存这是截然不同的。 给STM32芯片扩展内存与给PC电脑扩展内存的原理是一样的只不过我们平时给电脑扩展内存一般以内存条的形式扩展内存条实质上是由多个内存颗粒即SDRAM芯片组成的通用标准模块而STM32扩展时直接与SRAM芯片连接即可。 扩展内存的本质是利用STM32的FSMC灵活静态存储器去驱动IS62WV51216芯片进而达到扩展内存的目的STM32芯片追其根本还是起控制作用真正其作用的是IS62WV51216芯片 1.1 SRAM功能框图 SRAM芯片内部功能框图 A0-A18是地址线会连接到内部地址译码器然后会发送给存储器矩阵SRAM、FLASH和EEPROM在内部都是通过矩阵的形式进行存储的一方面有利于指针的读写另一方面也有利于擦除 其中存储器矩阵是512K*16单位是Bit1个字节对应于8位512*168192Bit8192/81024字节所以外部扩展Flash的大小是1M A0-A18输入引脚地址输入  设置指针寻址获取存储器矩阵中对应的数据I/O0-I/O7输入输出引脚数据输入输出信号低字节I/O8-I/O15输入输出引脚数据输入输出信号高字节CS2和CS1#输入引脚片选信号CS2高电平有效CS1#低电平有效部分芯片只要其中一个引脚OE#输入引脚输出使能信号低电平有效WE#输入引脚写入使能低电平有效UB#输入引脚数据掩码信号Upper Byte高位字节允许访问低电平有效LB#输入引脚数据掩码信号Lower Byte低位字节允许访问低电平有效 拓展         数据掩码信号将真正的客户数据转换成其他人都不能使用的完全伪造的数据但是那些数据仍可以被用于应用程序测试。         简单来说就是一种读写保护机制因为写入芯片的程序对使用者来说都非常重要为防止被他人窃取所以引入数据掩码信号。 地址译码器的作用 地址译码器是把 N 根地址线转换成  根信号线。每根信号线对应一行或者一列存储单元通过地址线找到具体的存储单元实现寻址。 美中不足的是STM32F4的开发板中拓展的SRAM还比较小只有1M是没有列地址线的它的数据宽度因为存储器矩阵类似于我们使用的Excel矩阵是由行和列组成的那么每一行的长度称为数据宽度是16位一行能放2个字节每个字节占8位其中因为数据宽度是16位的所以一行可以存放2个字节每次写入一个字节那么就需要分别写入这16位的高8位和低8位那么就需要借助I/O0-I/O7、I/O8-I/O15数据线分别写入这16位的高字节和低字节 A0-A18是地址信号线18根地址线一共可以表示*1024512K行存储单元所以总共可以访问 512K*16Bit 大小的空间。访问时使用UB#或LB#线控制数据宽度。 UB#和LB#的作用 因为存储器矩阵是通过地址线寻址进而得到对应的数据的那么如果我们想要访问第二行的高8位并且不想改变第二行的低8位此时就需要借助于UB#和LB#UB#是高位字节允许访问低电平有效LB#是低位字节允许访问低电平有效设置LB#等于1那么低位字节就不允许访问此时就无法访问第二行的低8位在此基础上设置UB#0高位字节允许访问此时就可以改变第二行高8位的数据。 控制电路 控制电路主要包括片选信号CS、读写使能OE、WE以及宽度控制信号UB#和LB#。利用CS2和CS1#片选信号可以把多个SRAM芯片组成一个大容量的内存条。OE#和WE#控制读写使能防止误操作。 1.2 SRAM读写时序 SRAM读数据时序 读时序的过程是 首先通过A0-A18地址线发送一个地址这个地址代表我们想要访问的SRAM对应地址上的数据因为SRAM是通过寻址的方式找到对应数据的紧接着读使能OE置低电平因为读使能引脚OE低电平有效接下来片选信号线CS1置低电平片选信号线CS2置高电平因为CS1低电平有效CS2高电平有效然后设置掩码信号LB#和UB#如果我们想要访问一行16位那么LB和UB均设置为低电平即可如果只是想访问16位中高8位和低8位其中之1那么按照需要对应设置掩码信号即可最后通过数据线 I/O 将对应地址上的数据发送给 STM32 即可这样就可以实现在SRAM上读取数据。 注 图中橙色区域和黄色区域的含义是         因为SRAM读取数据是异步通讯也就是没有时钟总线也可以说是双方没有规定好时间那么我将要读取的地址发送以后就需要给出一定的反应时间因为没有时钟不是同步通信也就是图中程序区域的长度整个程序区域长度表示整个读数据的时间黄色区域表示在发送地址一定时间后SRAM才会将对应地址上的数据返回给STM32也就是说对应时间过去以后我才会在黄色区域时间内把对应数据返回回去 SRAM写数据时序 写时序的过程是 首先在整个黄色区域也就是写时序周期内发送一个地址该地址表示STM32想要往SRAM的哪个地址上写确定写的地方以后紧接着拉低片选信号线CS1置高片选信号线CS2接下来写使能WE置低表示开始写数据到SRAM中然后根据自己想要写的数据宽度是16位还是16位中的高8位还是低8位设置掩码信号最后通过数据线将所要写入的数据写到对应的地址上 和的作用         因为是异步通信没有时钟总线所以我们默认在整个写时序的过程中在把写地址发送给SRAM以后等待一段时间这段时间是黄色区域的前半部分然后默认再等待时间就认为数据一定是写入了发送的地址上。 2. FSMC简介 首先我们需要明确STM32单片机只是起到了控制作用也就是说MCU控制外设去实现单片机内部集成的某些功能。这里学习的FSMC就是其中一个外设通过STM32控制FSMC就可以管理扩展的存储器SRAM。 FSMCFlexible Static Memory Controller的缩写译为灵活的静态存储器。FSMC可以用来驱动SRAM、NOR FLASH以及NAND FLASH类型的存储器但是不可以驱动动态存储器SDRAM动态存储器位于STM32F429中。 2.1 FSMC架构 ①通讯引脚 通讯引脚和原理图上的SRAM模块的引脚是一一对应的 FSMC_NBL[1:0]对应SRAM引脚为LB#和UB#表示数据掩码信号FSMC_A[18:0]对应SRAM引脚为地址线A[18:0]表示行地址线FSMC_D[15:0]对应SRAM引脚为数据线I/0[15:0]表示数据线FSMC_NWE对应SRAM引脚为WE#表示写入使能FSMC_NOE对应SRAM引脚为OE#表示输出使能读使能FSMC_NE[1:4]对应SRAM引脚为CE#表示片选信号 ②存储器控制器 原理图中对应的所有引脚都是连接到对应的存储控制器中的。 NOR/PSRAM/SRAM设备使用相同的控制器NAND/PC卡设备使用相同的控制器不同的控制器有专用的寄存器用于配置其工作模式 其中控制SRAM的由有FSMC_BCR1/2/3/4控制寄存器、FSMC_BTR1/2/3/4片选时序寄存器以及FSMC_BWTR1/2/3/4写时序寄存器每种寄存器都有4个对应于4个不同的存储区域 FSMC_BCR控制寄存器可配置要控制的存储器类型、数据线宽度以及信号有效极性能参数。 FSMC_BTR时序寄存器用于配置SRAM访问时的各种时间延迟如数据保持时间、地址保持时间等。 FSMC_BWTR写时序寄存器与FSMC_BTR控制的参数类似专门用于控制写时序的时间参数。 ③时钟控制逻辑 FSMC外设挂载在AHB总线上时钟信号来自于HCLK默认168MHz存储器控制器的同步时钟输出就是由它分频得到的。 2.2 FSMC地址映射 FSMC连接好外部的存储器SRAM拓展芯片IS62WV51216并初始化后就可以直接通过访问地址来读写数据。 FSMC访问存储的方式不同于IIC EEPROM、SPI FlashIIC和SPI都需要控制总线给存储器发送地址然后获取数据在程序里地址和数据是需要定义不同的变量来存储的我们的IIC、SPI程序中通常写字节函数都会定义第一个参数Address、第二个参数Data表示往地址Address上写入数据Data并且访问时还需要使用代码控制发送读写命令。 而FSMC外接存储器时其存储单元是映射到STM32的内部寻址空间的在程序里定义一个指向这些地址的指针就可以通过指针直接修改这些存储单元的内容。并且FSMC外设会自动完成数据访问过程读写命令之类的操作不需要程序控制。 2.3 FSMC控制SRAM时序 FSMC外设支持输出多种不同的时序以便于控制不同的存储器它具有ABCD四种模式 其中ADDSET表示地址设置阶段的持续时间 0000地址设置阶段的持续时间0*HCLK时钟周期168MHz        0001地址设置阶段的持续时间1*HCLK时钟周期168MHz        ……        1111地址设置阶段的持续时间1615*HCLK时钟周期168MHz复位后的默认值 DATAST表示数据阶段的持续时间 00000000Reserved        00000001DATAST阶段的持续时间1*HCLK时钟周期        00000010DATAST阶段的持续时间2*HCLK时钟周期        ……        11111111DATAST阶段的持续时间255*HCLK时钟周期复位后的默认值 以上的两个时间均通过FSMC片选时序寄存器的相应位进行设置 3. FSMC结构体 //FSMC时序结构体//一个HCLK周期为1/168微秒typedef struct {uint32_t FSMC_AddressSetupTime; //地址建立时间0-0xF个HCLK周期//通过时序寄存器进行设置//0000地址建立持续时间0*HCLK时钟周期//1111地址建立持续时间15*HCLK时钟周期uint32_t FSMC_AddressHoldTime; //地址保持时间0-0xF个HCLK周期//通过时序寄存器设置//0000保留//0001保持时间1*HCLK时钟周期//1111保持时间15*HCLK时钟周期uint32_t FSMC_DataSetupTime //数据建立时间0-0xF个HCLK周期//通过时序寄存器设置//0000 0000保留//0000 0001持续时间1*HCLK时钟周期//1111 1111持续时间255*HCLK时钟周期uint32_t FSMC_BusTurnAroundDuration; //总线转换周期0-0xF个HCLK周期//通过时序寄存器BTR/BWTR配置//0000增加0个HCLK时钟周期//1111增加15个HCLK时钟周期uint32_t FSMC_CLKDivision; //时钟分频因子1-0xF//时序寄存器BTR位[23:20]设置//0000Reserved//0001CLK周期2*HCLK周期//0010CLK周期3*HCLK周期//1111CLK周期16*HCLK周期uint32_t FSMC_DataLatency; //数据延迟时间//时序寄存器BTR/BWTR位[18:15]设置数据延迟时间//0000 0000Reserved//0000 0001延迟时间1*HCLK168MHz//0000 0010延迟时间2*HCLK168MHz以此类推//1111 1111延迟时间255*HCLK168MHzuint32_t FSMC_AccessMode; //设置访问模式//时序寄存器BTR/BWTR位[29:28]设置访问模式//00访问模式A//01访问模式B//10访问模式C//11访问模式D }FSMC_NORSRAMTimingInitTypeDef; //FSMC初始化结构体//除了最后两个成员是时序寄存器配置以外其余的成员都是FSMC_BCR控制寄存器配置的typedef struct {uint32_t FSMC_Bank; //设置要控制的Bank区域 选择FSMC映射的存储区域SRAM不需要通过寻址STM32内部是有其映射地址的只需要通过指针即可访问内部存储区域//FSMC_Bank1_NORSRAM1 0x6000 0000~0x63FF FFFF//FSMC_Bank1_NORSRAM2 0x6400 0000~0x67FF FFFF//FSMC_Bank1_NORSRAM3 0x6800 0000~0x6BFF FFFF//FSMC_Bank1_NORSRAM4 0x6C00 0000~0x6FFF FFFF//原理图上对应的引脚标明FSMC_NE3 所以在此选择FSMC_Bank1_NORSRAM3 对应的地址uint32_t FSMC_DataAddressMux; //设置地址总线和数据总线是否复用//FSMC_DataAddressMux_Enable/Disable //在控制NOR FLASH时可以地址总线和数据总线分时复用减少STM32信号线的数量uint32_t FSMC_MemoryType; //设置存储器的类型//它支持控制的存储器类型为SRAM、PSRAM、NOR//FSMC_MemoryType_SRAM/PSRAM/NORuint32_t FSMC_MemoryDataWidth; //设置存储器的数据宽度 可以选择设置为8或者16位//FSMC_MemoryDataWidth_8b/16buint32_t FSMC_BurstAccessMode; //设置是否支持突发访问模式//FSMC_BurstAccessMode_Enable/Disable//突发访问模式是指发送一个地址后连续访问多个数据//非突发模式下每访问一个数据都需要输入一个地址//控制同步类型的存储器时才能使用突发模式SRAM是异步类型的存储器uint32_t FSMC_AsynchronousWait; //设置是否使能在同步传输时的等待信号//FSMC_AsynchronousWait_Enable/Disable//在控制同步类型的NOR或PSRAM时存储器可以使用FSMC_NWAIT引脚通知STM32需要等待uint32_t FSMC_WaitSignalPolarity; //设置等待信号的极性 要求等待时使用高电平还是低电平//FSMC_WaitSignalPolarity_High/Low;uint32_t FSMC_WrapMode; //设置是否支持对齐的突发模式//是否支持把非对齐的AHB突发模式分割成2次线性操作//FSMC_WrapMode_Enable/Disableuint32_t FSMC_WaitSignalActive; //配置等待信号是在等待前有效还是等待期间有效 //决定存储器是在等待状态之前的一个数据周期有效还是在等待状态期间有效//FSMC_WaitSignalActive_BeforeWaitState/DuringWaitStateuint32_t FSMC_WriteOperation; //设置是否写使能//FSMC_WriteOperation_Enable/Disableuint32_t FSMC_WaitSignal; //设置是否使能等待状态插入//设置当存储器突发传输模式时是否允许通过NWAIT信号插入等待状态//FSMC_WaitSignal_Enable/Disableuint32_t FSMC_ExtendedMode; //设置是否使能扩展模式//FSMC_ExtendedMode_Enable/Disableuint32_t FSMC_WriteBurst; //设置是否使能写突发操作//FSMC_WriteBurst_Enable/Disable//当不使用扩展模式时本参数用于配置读写时序否则用于配置读时序FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct;//当使用扩展模式时本参数用于配置写时序//FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;}FSMC_NORSRAMInitTypeDef; 4. 库函数配置FSMC 1. 使能FSMC时钟配置FSMC相关的IO及其时钟使能 要使用FSMC首先要开启其时钟。然后需要把FSMC_D0~D15FSMC_A0~A18相关的IO口全部配置为复用功能使能各个IO组的时钟 RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);    //使能 FSMC 时钟 GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF;     //复用输出 void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);   //设置引脚映射 2. 设置FSMC BANK1 区域3的相关寄存器 void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct);   //调用结构体设置FSMC控制寄存器的工作模式、位宽和读写时序 3. 使能BANK1 区域3 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);    // 使能 BANK1  区域3 5. 实验程序 实验现象 开机后显示提示信息然后按下KEY0按键测试外部SRAM容量大小并显示在LCD上。 按下KEY1按键显示预存在外部的SRAM数据。 5.1 main.c #include stm32f4xx.h #include delay.h #include usart.h #include LED.h #include lcd.h #include Key.h #include usmart.h #include SRAM.h//LCD状态设置函数 void led_set(u8 sta)//只要工程目录下有usmart调试函数主函数就必须调用这两个函数 {LED1sta; } //函数参数调用测试函数 void test_fun(void(*ledset)(u8),u8 sta) {led_set(sta); } u32 TestSRAM[250000] __attribute__((at(0x68000000))); //测试用数组 //定义一个局部变量 该数组是用来测试的数组 //__attribute__((at(0x68000000)))这个是用来指定变量或结构位域的特殊属性该关键字后的双括弧中的内容是属性说明 //at是关键字该关键字用来设置变量的绝对地址也就是说通过该关键字可以指定某个变量处于内存里面的某个给定的地址 //综合起来就是设置变量处于0x68000000这个地址//外部内存测试最大支持1M字节内存测试 void fsmc_sram_test(u16 x,u16 y) {u32 i0;u8 temp0;u8 sval0; //在地址0读到的数据LCD_ShowString(x,y,239,y16,16,Ex Memory Test: 0KB); //提示信息 239y16是指区域大小//每隔4K字节写入一个数据总共写入256个数据正好是1M字节用来测试SRAM内存for(i0;i1024*1024;ii4096) //1M1024KB,1KB1024字节4096字节就是4KB ii4096表示for每循环一次就跳过4K字节{//i是在1024*1024的存储器矩阵中进行循环的FSMC_SRAM_WriteBuffer(temp,i,1);//调用在指定地址上写入n个字节函数//temp取地址变量temp表示拿到了temp变量的存储首地址指针指向temp首地址表示从这个地址开始写//i表示要写入的值i在存储器矩阵中递增SRAM写是不需要软件参与的只要指针能指向这个i对应的地址就能对该地址进行写操作//每次写入1个字节temp;}//依次读出之前写入的数据进行校验for(i0;i1024*1024;ii4096){FSMC_SRAM_ReadBuffer(temp,i,1);if(i0) //表示在地址0上读出的数据{svaltemp; //把地址0上读到的数据给到sval}else if(tempsval) //else if 此时i不再是0也就表示之前已经写入数据了因为i在存储器矩阵中是递增的所以只要后面读取的值小于地址0上的值就break结束{break; //后面读出的数据一定要比第一次读到的数据大}LCD_ShowxNum(x15*8,y,(u16)(temp-sval1)*4,4,16,0); //显示内容容量 //第三个参数表示要写入的数值 第四个参数表示长度//u16 表示unsigned int 表示强制类型转换为int型 //temp是最后一次读取到值sval是位置0上读取的值temp-sval1表示在整个存储器矩阵读到了多少个数每个4K写一次那么读到的数也是每隔4K的//(temp-sval1)*4 表示总的数据长度也就是内存容量} } int main(void) {u8 key;u8 i0;u32 j0;delay_init(168);uart_init(115200);LED_Init();LCD_Init();Key_Init();FSMC_SRAM_Init();POINT_COLORRED;LCD_ShowString(30,50,200,16,16,Explorer STM32F4);LCD_ShowString(30,70,200,16,16,SRAM Test);LCD_ShowString(30,90,200,16,16,ATOMALIENTEK);LCD_ShowString(30,110,200,16,16,2023/20/23);LCD_ShowString(30,130,200,16,16,KEY0:Test Sram);LCD_ShowString(30,150,200,16,16,KEY1:Test Data);POINT_COLORBLUE; //设置字体为蓝色for(j0;j250000;j){TestSRAM[j]j; //预存测试数据} // 可以借助该程序在串口查看数据 // while(1) // { // printf(\r\nSRAM中的数据是:\r\n); // for(j0;j250000;j) // { // LED0!LED0; // printf(%d ,TestSRAM[j]); // } // }while(1){keyKEY_Scan(0);if(key1) //KEY0按下{fsmc_sram_test(60,170); //测试SRAM容量}else if(key2) //KEY1按下 打印预存测试数据{for(j0;j250000;j){LCD_ShowxNum(60,190,TestSRAM[j],6,16,0); //显示测试数据}}else{delay_ms(10);}i;if(i20){i0;LED0!LED0;}} } 5.2 SRAM.c #include stm32f4xx.h #include SRAM.h//使用NOR/SRAM的 Bank1.sector3地址位HADDR[27,26]10 //00sector1 //01sector2 //10sector3 //11sector4 //对IS62WV51216来说地址线范围为A0~A18#define Bank1_SRAM3_ADDRESS ((u32)(0x68000000)) //Bank1_SRAM3的起始地址为0x68000000//初始化外部SRAM void FSMC_SRAM_Init(void) {RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOG,ENABLE); //使能B D E F G时钟RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE); //使能FSMC时钟//PB15GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_ModeGPIO_Mode_OUT;GPIO_InitStructure.GPIO_OTypeGPIO_OType_PP; //推挽输出GPIO_InitStructure.GPIO_PinGPIO_Pin_15; //PB15 推挽输出 控制背光GPIO_InitStructure.GPIO_PuPdGPIO_PuPd_UP;GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz;GPIO_Init(GPIOB,GPIO_InitStructure);//PD0 PD1 PD4 PD5 PD8~15 GPIO_InitStructure.GPIO_ModeGPIO_Mode_AF;GPIO_InitStructure.GPIO_OTypeGPIO_OType_PP; //推挽输出GPIO_InitStructure.GPIO_PinGPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|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_InitStructure.GPIO_PuPdGPIO_PuPd_UP;GPIO_InitStructure.GPIO_SpeedGPIO_Speed_100MHz;GPIO_Init(GPIOD,GPIO_InitStructure);//PE0 PE1 PE7~15GPIO_InitStructure.GPIO_ModeGPIO_Mode_AF; //引脚模式设置为复用后续将引脚复用为FSMCGPIO_InitStructure.GPIO_OTypeGPIO_OType_PP; //推挽输出GPIO_InitStructure.GPIO_PinGPIO_Pin_0|GPIO_Pin_1|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_InitStructure.GPIO_PuPdGPIO_PuPd_UP;GPIO_InitStructure.GPIO_SpeedGPIO_Speed_100MHz;GPIO_Init(GPIOE,GPIO_InitStructure);//PF0~5 PF12~15GPIO_InitStructure.GPIO_ModeGPIO_Mode_AF;GPIO_InitStructure.GPIO_OTypeGPIO_OType_PP; //推挽输出GPIO_InitStructure.GPIO_PinGPIO_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_InitStructure.GPIO_PuPdGPIO_PuPd_UP;GPIO_InitStructure.GPIO_SpeedGPIO_Speed_100MHz;GPIO_Init(GPIOF,GPIO_InitStructure);//PG0~5 PG10GPIO_InitStructure.GPIO_ModeGPIO_Mode_AF;GPIO_InitStructure.GPIO_OTypeGPIO_OType_PP; //推挽输出GPIO_InitStructure.GPIO_PinGPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_10; GPIO_InitStructure.GPIO_PuPdGPIO_PuPd_UP;GPIO_InitStructure.GPIO_SpeedGPIO_Speed_100MHz;GPIO_Init(GPIOG,GPIO_InitStructure);//将所有复用功能的引脚设置为 复用FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC); //PD0复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC); //PD1复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC); //PD4复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC); //PD5复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC); //PD8复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC); //PD9复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC); //PD10复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource11,GPIO_AF_FSMC); //PD11复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_FSMC); //PD12复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_FSMC); //PD13复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC); //PD14复用为FSMCGPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC); //PD15复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource0,GPIO_AF_FSMC); //PE0复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource1,GPIO_AF_FSMC); //PE1复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC); //PE7复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC); //PE8复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC); //PE9复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC); //PE10复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC); //PE11复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC); //PE12复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC); //PE13复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC); //PE14复用为FSMCGPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC); //PE15复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource0,GPIO_AF_FSMC); //PF0复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource1,GPIO_AF_FSMC); //PF1复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource2,GPIO_AF_FSMC); //PF2复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource3,GPIO_AF_FSMC); //PF3复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource4,GPIO_AF_FSMC); //PF4复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource5,GPIO_AF_FSMC); //PF5复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource12,GPIO_AF_FSMC); //PF12复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource13,GPIO_AF_FSMC); //PF13复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource14,GPIO_AF_FSMC); //PF14复用为FSMCGPIO_PinAFConfig(GPIOF,GPIO_PinSource15,GPIO_AF_FSMC); //PF15复用为FSMCGPIO_PinAFConfig(GPIOG,GPIO_PinSource0,GPIO_AF_FSMC);GPIO_PinAFConfig(GPIOG,GPIO_PinSource1,GPIO_AF_FSMC);GPIO_PinAFConfig(GPIOG,GPIO_PinSource2,GPIO_AF_FSMC);GPIO_PinAFConfig(GPIOG,GPIO_PinSource3,GPIO_AF_FSMC);GPIO_PinAFConfig(GPIOG,GPIO_PinSource4,GPIO_AF_FSMC);GPIO_PinAFConfig(GPIOG,GPIO_PinSource5,GPIO_AF_FSMC);GPIO_PinAFConfig(GPIOG,GPIO_PinSource10,GPIO_AF_FSMC);FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructure; //调用STM32库函数配置的结构体配置时序寄存器FSMC_NORSRAMTimingInitStructure.FSMC_AccessModeFSMC_AccessMode_A; //设置访问模式为模式AFSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime0x00; //地址保持时间模式A未用到FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime0x00; //地址建立时间(ADDSET)为1个HCLK 1/36M27nsFSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration0x00; //总线转换周期 0000增加0个HCLK时钟周期FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision0x00; //时钟分频因子 0000 0000保留FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency0x00; //数据延迟时间 0000 0000保留FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime0x08; //数据保持时间(DATAST)为9个HCLK 6*954ns//调用STM32库函数配置的结构体配置FSMC_BCR控制寄存器FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;FSMC_NORSRAMInitStructure.FSMC_AsynchronousWaitFSMC_NORSRAMInitStructure.FSMC_BankFSMC_Bank1_NORSRAM3; //Bank1区域3FSMC_NORSRAMInitStructure.FSMC_BurstAccessModeFSMC_BurstAccessMode_Disable; //不支持突发访问模式FSMC_NORSRAMInitStructure.FSMC_DataAddressMuxFSMC_DataAddressMux_Disable; //地址总线和数据总线不复用FSMC_NORSRAMInitStructure.FSMC_ExtendedModeFSMC_ExtendedMode_Disable; //不使能扩展模式读写使用相同的时序FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidthFSMC_MemoryDataWidth_16b; //存储器的数据宽度为16位FSMC_NORSRAMInitStructure.FSMC_MemoryTypeFSMC_MemoryType_SRAM; //选择存储器种类为SRAMFSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStructFSMC_NORSRAMTimingInitStructure; //不使用扩展模式时配置读写时序FSMC_NORSRAMInitStructure.FSMC_WaitSignalFSMC_WaitSignal_Disable; //不使能等待状态插入FSMC_NORSRAMInitStructure.FSMC_WaitSignalActiveFSMC_WaitSignalActive_BeforeWaitState; //配置等待信号在等待前有效FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarityFSMC_WaitSignalPolarity_Low; //要求等待时设置为低电平FSMC_NORSRAMInitStructure.FSMC_WrapModeFSMC_WrapMode_Disable; //不支持对齐的突发模式FSMC_NORSRAMInitStructure.FSMC_WriteBurstFSMC_WriteBurst_Disable; //不使能写突发操作FSMC_NORSRAMInitStructure.FSMC_WriteOperationFSMC_WriteOperation_Enable; //存储器写使能FSMC_NORSRAMInitStructure.FSMC_WriteTimingStructFSMC_NORSRAMTimingInitStructure; //扩展模式时本参数用于配置写时序FSMC_NORSRAMInit(FSMC_NORSRAMInitStructure);FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3,ENABLE); //使能Bank1 区域3 } //在指定地址(WriteAddressBank1_SRAM3_ADDRESS)上开始连续写入n个字节 //pBuffer字节指针 //WriteAddress要写入的地址 //n要写入的字节数 void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddress,u32 n) //在SRAM上写字节是不需要软件来操作的因为地址是在STM32上映射的//所有只需要给出地址通过指针就可以实现读写操作读写操作通过硬件来完成无需软件操作来参与 {for(;n!0;n--) //通过for循环将n个字节写到SRAM每循环一次要写入的字节就少一个{*(vu8*)(Bank1_SRAM3_ADDRESSWriteAddress)*pBuffer; //该代码的含义是Bank1_SRAM3_ADDRESS是Bank1区域3的起始地址WriteAddress要写入的地址表示首先要将指针指向我们要写入的地址上//(vu8*)(Bank1_SRAM3_ADDRESSWriteAddress)表示强制类型转换成vu8的指针然后解引用拿到该指针指向地址上的数据//将*pBuffer指针指向这个数据硬件自动写入数据WriteAddress;//要写入的地址加1pBuffer;//指针指向下一个地址}//这里注意//假设WriteAddress要写入的地址是0也就是说从SRAM起始地址开始写起始地址是0x68000000写入的地址是偶数那么地址线最低位A0一定是0因为SRAM是通过地址线发送要访问的地址的//此时LB#和UB#掩码信号中LB有效所以LB0写入数据D0~D7有效D8~D15无效UB1//继续写地址1的时候写入的地址就变成了0x68000001此时LB1无效UB0有效因此数据写入高8位地址//UB和LB与要写入地址的最低位有关//如果要写入的数据是16位的那么UB和LB都要有效所以UB和LB都是0//如果地址是奇数那么1个16位的数据需要分两次去写因为强制类型转换把要写入的地址转换成了8位//所以需要分别去写地址的高8位和低8位//这样写两次相对于写一次速度就会减半 } //在指定地址(ReadAddressBank1_SRAM3_ADDRESS)上开始连续读出n个字节 //pBuffer字节指针 //ReadAddress要读出的起始地址 //n要写入的字节数 void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddress,u32 n) {for(;n!0;n--) //循环n次从SRAM中读出n个字节 同理读字节也是硬件来完成的无需软件操作{*pBuffer*(vu8*)(Bank1_SRAM3_ADDRESSReadAddress); //解引用拿到指针指向地址上的数据字节指针指向这个数据//通过硬件循环读取该数据,指针后置ReadAddress;//对应地址} }//测试函数 //在指定地址写入1个字节 //Address地址 //Data要写入的数据 void fsmc_sram_test_write(u32 Address,u8 Data) {FSMC_SRAM_WriteBuffer(Data,Address,1); //第一个参数字节指针指向要写入数据的首元素地址第二个参数是要写入的地址第三个参数是要写入的字节个数//写入一个字节 } //读取一个字节 //Address要读取的地址 //返回值读取到的数据 u8 fsmc_sram_test_read(u32 Address) {u8 Data;FSMC_SRAM_ReadBuffer(Data,Address,1); //读取一个字节return Data; } 5.3 SRAM.h #ifndef _SRAM__H_ #define _SRAM__H_ #include sys.hvoid FSMC_SRAM_Init(void); void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddress,u32 n); void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddress,u32 n);void fsmc_sram_test_write(u32 addr,u8 data); u8 fsmc_sram_test_read(u32 addr);#endif
http://www.yayakq.cn/news/2473/

相关文章:

  • 广州seo网站推广优化青少年编程培训哪家好
  • 房地产网站模板库国内crm系统
  • 怎样制作一个app软件网站关键词快速排名优化
  • 网站建设基础问题企业网站建设智恒网络
  • 天河低价网站建设哪里有零基础网站建设教学公司
  • 建设一个连接的网站个人网站有必要备案吗
  • 怎么上传网页到wordpress郑州seo地址
  • 模板网站建设珠海wordpress发布工具
  • 佛山建设工程交易中心网站教育类网站开发费用
  • 湖南响应式网站哪家好wordpress 解析插件
  • 手机网站和微网站wordpress统计访问量
  • 北京网站建设的服务公司自己搭建视频播放网站
  • 微信网站案例无极网络平台
  • 微信网站建设费用计入什么科目如何在手机上做微电影网站
  • 网站导出链接查询天津公司建站
  • 西安建站模板厂家网站建设业务前景
  • 方又圆网站建设百度关键词数据
  • 企业建设网站的主要目的有哪些服务公司的经营范围
  • 温州做网站哪里好建造自己的网站
  • 建网站的8个详细步骤昌乐建设局网站
  • 一个ip怎么做多个网站百度seo关键词点击软件
  • 如何构建个人网站安阳贴吧论坛
  • php精品网站建设连云港市建设工程安全监督站网站
  • 泰州营销型网站工程造价信息网官网信息价
  • 全国水利建设市场信用信息平台门户网站比较有设计感的网站
  • 寺庙网站开发建设方案安徽智能网站建设制作
  • 石家庄网站推广专业鑫菲互动网站建设公司
  • 网站名称写什么网易邮箱163登录入口
  • 成都网站排名app开发多少钱?
  • 网站导航插件wordpress第三方账号