完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
手册上提到“与具有字节选择功能的存储器(SRAM、ROM、PSRAM等)进行异步传输时,FSMC 执行读写操作并通过它的字节通道BL[1:0]访问正确的数据。 ”
如下图所示: SRAM挂到FSMC的NOR/PSRAM 1上, 现在定义一个8位和一个16位的变量temp_8 temp_16: #define Bank1_SRAM1_ADDR ((uint32_t)0x60000000) #define temp_8 (*(u8 *)(Bank1_SRAM1_ADDR+0x0)) #define temp_16 (*(u16 *)(Bank1_SRAM1_ADDR+0x1)) 赋值 temp_8=0x12; temp_16=0x3456; --------------------------------------------------------------------------------------- 1.两个变量在FSMC存储块中的存放位置应该如上图所示吧 2.而在SRAM中呢,temp_8会放在00000中的低8位,然后temp_16中的0x56会放在00000中的高8位,而0x34会放在00001中的低8位 还是temp_8直接放在00000的低8位,而高8位空,temp_16高低8位对应该放入00001中呢?应该不会是第二种情况吧,不明NBL0、NBL1的控制时序 |
|
相关推荐
10个回答
|
|
|
|
|
|
还要注意硬件脚位 A0 A1
|
|
|
|
现在发现先对两个不同的地址写入数据,再把数据读出时就会出错了,读出的都是最后写入的那一个数,如下面程序
#define Bank1_SRAM3_ADDR ((uint32_t)0x68000000) #define temp1 (*(vu8 *)(Bank1_SRAM3_ADDR+0x1000)) #define temp2 (*(vu8 *)(Bank1_SRAM3_ADDR+0x2000)) temp1=0x12; //对偏移地址1000写入0x12 temp2=0x34;; //对偏移地址2000写入0x34 USART1_Transmit(temp1); //串口读出0x1000地址 USART1_Transmit(temp2); //串口读出0x2000地址 读出的都是0x34 如果换成以下程序 temp1=0x12; //对偏移地址1000写入0x12 USART1_Transmit(temp1 ); //串口读出0x1000地址 temp2=0x34;; //对偏移地址2000写入0x34 USART1_Transmit(temp2); //串口读出0x2000地址 这样的话,输出又正确了,不明白那里出问题了 |
|
|
|
确定你的硬件无问题?
|
|
|
|
硬件连接线是有点多,但是正确的,检查多次了
上面的引脚都是按STM32103Z手册连接相应的FSMC引脚 LB---PE0 UB---PE1 CE---PG10 WE--PD5 OE---PD4 其余数据和地址线都按相应连接。 |
|
|
|
这是FSMC初始化代码
void FSMC_SRAM_Init(void) { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef p; GPIO_InitTypeDef GPIO_InitStructure; /* Enable FSMC, GPIOD, GPIOE, GPIOF, GPIOG and AFIO clocks */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG , ENABLE); /*-- GPIO Configuration ------------------------------------------------------*/ /* SRAM Data lines configuration */ 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); 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); /* SRAM Address lines configuration */ 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); 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); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; GPIO_Init(GPIOD, &GPIO_InitStructure); /* NOE and NWE configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5; GPIO_Init(GPIOD, &GPIO_InitStructure); /* NE3 configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOG, &GPIO_InitStructure); /* NBL0, NBL1 configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOE, &GPIO_InitStructure); /*-- FSMC Configuration ------------------------------------------------------*/ p.FSMC_AddressSetupTime = 0; /*ADDSET 地址建立时间*/ p.FSMC_AddressHoldTime = 0; /*ADDHOLD 地址保持时间*/ p.FSMC_DataSetupTime = 2; /*DATAST 数据建立时间*/ p.FSMC_BusTurnAroundDuration = 0; /*BUSTURN 总线返转时间*/ p.FSMC_CLKDivision = 0; /*CLKDIV 时钟分频*/ p.FSMC_DataLatency = 0; /*DATLAT 数据保持时间*/ p.FSMC_AccessMode = FSMC_AccessMode_A; /*ACCMOD FSMC 访问模式*/ /*选择设置的BANK及片选信号*/ FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; /*设置是否数据地址总线分时复用(禁用)*/ FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; /*设置存储器类型*/ FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; /*设置数据宽度*/ FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; /*设置是否使用突发访问模式(连续读写模式)*/ FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; /*设定是否使用异步等待信号*/ FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; /*设置WAIT信号的有效电平*/ FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; /*设置是否使用环回模式*/ FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; /*设置WAIT信号有效时机*/ FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; /*设定是否使能写操作*/ FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; /*设定是否使用WAIT信号*/ 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_NORSRAMInit(&FSMC_NORSRAMInitStructure); /*打开SRAM控制权 */ FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); } ///////////////////////////////////////////////////////////////// 非复用模式的,选择FSMC_Bank1_NORSRAM3存储块 |
|
|
|
/*******************************************************************************
* Function Name : FSMC_SRAM_Init * Description : Configures the FSMC and GPIOs to interface with the SRAM memory. * This function must be called before any write/read operation * on the SRAM. * Input : None * Output : None * Return : None *******************************************************************************/ void FSMC_SRAM_Init(void) { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef p; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF, ENABLE); /*-- GPIO Configuration ------------------------------------------------------*/ /* SRAM Data lines configuration */ 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); 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); /* SRAM Address lines configuration */ 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); 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); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; GPIO_Init(GPIOD, &GPIO_InitStructure); /* NOE and NWE configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5; GPIO_Init(GPIOD, &GPIO_InitStructure); /* NE3 configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOG, &GPIO_InitStructure); /* NBL0, NBL1 configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOE, &GPIO_InitStructure); /*-- FSMC Configuration ------------------------------------------------------*/ p.FSMC_AddressSetupTime = 0; /*ADDSET 地址建立时间*/ p.FSMC_AddressHoldTime = 0; /*ADDHOLD 地址保持时间*/ p.FSMC_DataSetupTime = 3; /*DATAST 数据建立时间*/ p.FSMC_BusTurnAroundDuration = 0; /*BUSTURN 总线返转时间*/ p.FSMC_CLKDivision = 0; /*CLKDIV 时钟分频*/ p.FSMC_DataLatency = 0; /*DATLAT 数据保持时间*/ p.FSMC_AccessMode = FSMC_AccessMode_A; /*ACCMOD FSMC 访问模式*/ FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; /*设置是否数据地址总线分时复用*/ FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; /*设置存储器类型*/ FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; /*设置数据宽度*/ FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; /*设置是否使用迸发访问模式(应该就是连续读写模式吧),*/ FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; /*设置WAIT信号的有效电平*/ FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; /*设置是否使用环回模式*/ FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; /*设置WAIT信号有效时机*/ FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; /*设定是否使能写操作*/ FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; /*设定是否使用WAIT信号*/ 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; p.FSMC_DataSetupTime = 5; /*DATAST 数据建立时间*/ FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); /* Enable FSMC Bank1_SRAM Bank */ FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); } |
|
|
|
给你一段豪华版的代码.
测试OK. 注意,可以通过调用exsram_self_test函数测试你的外部SRAM是否全部OK. #include "..sramsram.h" //使用NOR/SRAM的 BANK 4,地址位HADDR[27,26]=10 //对IS61LV25616,地址线范围为A0~A17 //对IS61LV51216,地址线范围为A0~A18 #define Bank1_SRAM3_ADDR ((u32)(0x60000000 | 0x08000000)) //初始化外部SRAM void fsmc_sram_init(void) { RCC->AHBENR|=1<<8; //使能FSMC时钟 RCC->APB2ENR|=1<<5; //使能PORTD时钟 RCC->APB2ENR|=1<<6; //使能PORTE时钟 RCC->APB2ENR|=1<<7; //使能PORTF时钟 RCC->APB2ENR|=1<<8; //使能PORTG时钟 RCC->APB2ENR|=1<<0; //使能AFIO时钟 //PORTD复用推挽输出 GPIOD->CRH&=0X00000000; GPIOD->CRH|=0XBBBBBBBB; GPIOD->CRL&=0XFF00FF00; GPIOD->CRL|=0X00BB00BB; //PORTE复用推挽输出 GPIOE->CRH&=0X00000000; GPIOE->CRH|=0XBBBBBBBB; GPIOE->CRL&=0X0FFFFF00; GPIOE->CRL|=0XB00000BB; //PORTF复用推挽输出 GPIOF->CRH&=0X0000FFFF; GPIOF->CRH|=0XBBBB0000; GPIOF->CRL&=0XFF000000; GPIOF->CRL|=0X00BBBBBB; //PORTG复用推挽输出 G10->NE3 GPIOG->CRH&=0XFFFFF0FF; GPIOG->CRH|=0X00000B00; GPIOG->CRL&=0XFF000000; GPIOG->CRL|=0X00BBBBBB; //寄存器清零 //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。 //这里我们使用NE3 ,也就对应BTCR[4],[5]。 FSMC_Bank1->BTCR[4]=0X00000000; FSMC_Bank1->BTCR[5]=0X00000000; FSMC_Bank1E->BWTR[4]=0X00000000; //操作BCR寄存器使用异步模式,模式A //BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器 FSMC_Bank1->BTCR[4]|=1<<12;//存储器写使能 FSMC_Bank1->BTCR[4]|=1<<4; //存储器数据宽度为16bit //操作BTR寄存器 FSMC_Bank1->BTCR[5]|=2<<8; //数据保持时间(DATAST)为2个HCLK 1/36M=27ns FSMC_Bank1->BTCR[5]|=0<<4; //地址保持时间(ADDHLD)未用到 FSMC_Bank1->BTCR[5]|=0<<0; //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns //闪存写时序寄存器 FSMC_Bank1E->BWTR[4]=0x0FFFFFFF;//默认值 //使能BANK3(PC卡设备) FSMC_Bank1->BTCR[4]|=1<<0; } //测试内部sram u8 exsram_self_test(void) { u32 i=0; u16 temp; for(i=0;i<512;i++) { FSMC_SRAM_WriteBuffer((u16*)&i,i*1024,1); } for(i=0;i<512;i++) { FSMC_SRAM_ReadBuffer(&temp,i*1024,1); if(temp!=i)return 1;//exsram测试失败 } return 0;//测试成功 } //设置速度 0~15 void exsram_speed_set(u16 x) { FSMC_Bank1->BTCR[5]&=0xffff0000;//清空低位 FSMC_Bank1->BTCR[5]|=x<<8; //数据保持时间(DATAST)为2个HCLK 1/36M=27ns //FSMC_Bank1->BTCR[5]|=x<<4; //地址保持时间(ADDHLD)为2个HCLK 1/36M=27ns //FSMC_Bank1->BTCR[5]|=x<<0; //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns } //在指定地址开始,连续写入n个字节. //pBuffer:字节指针 //WriteAddr:要写入的地址 //n:要写入的字节数(16bit) void FSMC_SRAM_WriteBuffer(u16* pBuffer, u32 WriteAddr, u32 n) { for(;n!=0;n--) { *(vu16 *) (Bank1_SRAM3_ADDR + WriteAddr) = *pBuffer; WriteAddr += 2;//这里需要加2,是因为STM32的FSMC地址右移一位对其.加2相当于加1. pBuffer++; } } //在指定地址开始,连续读出n个字节. //pBuffer:字节指针 //ReadAddr:要读出的起始地址 //n:要写入的字节数(16bit) void FSMC_SRAM_ReadBuffer(u16* pBuffer, u32 ReadAddr, u32 n) { for(;n!=0;n--) { *pBuffer++= *(vu16*) (Bank1_SRAM3_ADDR + ReadAddr); ReadAddr += 2;//这里需要加2,是因为STM32的FSMC地址右移一位对其.加2相当于加1. } } |
|
|
|
原子大哥,找到原因了,内存模块CS的标号标错位置了,与排针不对应.之前每条线都测过都通了,后再再测每一个脚与排针,才发现CS不对应.该死的模块,太相信它了.因没有做过FSMC,所以自己也一直盯着程序.
等你的豪华版很久了啊,又是直接操作寄存器,先收藏了 |
|
|
|
呵呵.
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
568浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 13:16 , Processed in 1.025744 second(s), Total 95, Slave 78 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号