使用SM32f429ZI芯片,通过FSMC读写32M的SDRAM(IS42S16160J),测试读写失败。 每次擦除和写入的数据在memory窗口看都只有第一行显示,后面全是FF。感觉memory是不可信的。 执行全片擦除(全片写入0x00)后结果如下图: 而且发现擦除任意一个byte,在memory就会显示第一行全是0x00,然后其他行全是FF 执行全片写入后结果如下图: 跟擦除一样,写入任意一个字节,都会在第一行显示该字节,其他行为FF。 所以觉得memory窗口显示不可信,使用软件去校验写入数据。将写入数据读出来,再与写入的对比,结果第一个字节就对不上。 下面是读写数据的代码: while(1) { /*********************** 8-bits AHB transaction test ************************/ /* Erase SDRAM memory */ for (counter = 0x00; counter < IS42S16160J_SIZE*2; counter++) { *(__IO uint8_t*) (SDRAM_BANK_ADDR + counter) = (uint8_t)0x0; } /* Write data value to all SDRAM memory */ for (counter = 0; counter < IS42S16160J_SIZE*2; counter++) { *(__IO uint8_t*) (SDRAM_BANK_ADDR + counter) = (uint8_t)(ubWritedata_8b + counter); } /* Read back SDRAM memory and check content correctness*/ counter = 0; uwReadwritestatus = 0; while ((counter < IS42S16160J_SIZE) && (uwReadwritestatus == 0)) { ubReaddata_8b = *(__IO uint8_t*)(SDRAM_BANK_ADDR + counter); if ( ubReaddata_8b != (uint8_t)(ubWritedata_8b + counter)) { uwReadwritestatus = 1; } counter++; } } SDRAM配置代码: void bsp_InitExtSDRAM(void) { FMC_SDRAMInitTypeDef FMC_SDRAMInitStructure; FMC_SDRAMTimingInitTypeDef FMC_SDRAMTimingInitStructure; /* GPIO configuration for FMC SDRAM bank */ SDRAM_GPIOConfig(); /* Enable FMC clock */ RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE); /* FMC Configuration ---------------------------------------------------------*/ /* FMC SDRAM Bank configuration */ /* Timing configuration for 90 Mhz of SD clock frequency (168Mhz/2) */ /* TMRD: 2 Clock cycles */ FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2; /* TXSR: min=70ns (7x11.11ns) (6x11.9ns)*/ FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 6;//7; /* TRAS: min=42ns (4x11.11ns) max=120k (ns) 37ns(4x11.9ns) */ FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4; /* TRC: min=70 (7x11.11ns) 60ns (6x11.9ns)*/ FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 6;//7; /* TWR: min=1+ 7ns (1+1x11.11ns) */ FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2; /* TRP: 20ns => 2x11.11ns 15ns (2x11.9ns)*/ FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2; /* TRCD: 20ns => 2x11.11ns 15ns (2x11.9ns)*/ FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2; /* FMC SDRAM control configuration */ FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank1_SDRAM; //FMC_Bank2_SDRAM; /* Row addressing: [7:0] */ FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_9b; /* Column addressing: [10:0] --> [11:0], _12b = 16M, _11b = 8M */ FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_13b; FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = SDRAM_MEMORY_WIDTH; FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4; /* CL: Cas Latency = 3 clock cycles */ FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3; FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable; FMC_SDRAMInitStructure.FMC_SDClockPeriod = SDCLOCK_PERIOD; FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_Disable;//FMC_Read_Burst_Enable;// FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1;//FMC_ReadPipe_Delay_0;// FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure; /* FMC SDRAM bank initialization */ FMC_SDRAMInit(&FMC_SDRAMInitStructure); /* FMC SDRAM device initialization sequence */ SDRAM_InitSequence(); } SDRAM_InitSequence函数: static void SDRAM_InitSequence(void) { FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure; uint32_t tmpr = 0; uint32_t timeout = SDRAM_TIMEOUT; /* Step 3 --------------------------------------------------------------------*/ /* Configure a clock configuration enable command */ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0)) { timeout--; } /* Send the command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Step 4 --------------------------------------------------------------------*/ /* Insert 100 ms delay */ bsp_DelayMS(100); /* Step 5 --------------------------------------------------------------------*/ /* Configure a PALL (precharge all) command */ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ timeout = SDRAM_TIMEOUT; while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0)) { timeout--; } /* Send the command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Step 6 --------------------------------------------------------------------*/ /* Configure a Auto-Refresh command */ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 8; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ timeout = SDRAM_TIMEOUT; while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0)) { timeout--; } /* Send the command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Wait until the SDRAM controller is ready */ timeout = SDRAM_TIMEOUT; while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0)) { timeout--; } /* Step 7 --------------------------------------------------------------------*/ /* Program the external memory mode register */ tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | //2******************************???***** SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | SDRAM_MODEREG_CAS_LATENCY_3 | SDRAM_MODEREG_OPERATING_MODE_STANDARD | SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; /* Configure a load Mode register command*/ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr; /* Wait until the SDRAM controller is ready */ timeout = SDRAM_TIMEOUT; while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0)) { timeout--; } /* Send the command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Step 8 --------------------------------------------------------------------*/ /* Set the refresh rate counter */ /* (15.62 us x Freq) - 20 */ /* Set the device refresh counter */ //FMC_SetRefreshCount(1385); //168000000Hz/2 * 0.064s / 8192 = 656 è?600 FMC_SetRefreshCount(980); /* Wait until the SDRAM controller is ready */ timeout = SDRAM_TIMEOUT; while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0)) { timeout--; } } 使用的BANK1,行列13*9,芯片的各项配置是根据主频对照手册算的,不知道是否哪里配置还有问题,请教调试过SDRAM的大侠指导!谢谢。 |
基础不牢靠。。。
*(__IO uint32_t*) ADDRESS是啥意思懂不?就是把ADDRESS这个数强制转换为地址指针,再取这个指针中的内容。STM32是32位系统,能随便改成*(__IO uint8_t*) 吗?*(__IO uint8_t*) 就把ADDRESS头掐了,只剩后8位地址的内容,赶快看看你0X0000 00xx位置内容变了没
每个地址内容都是8位,所以存8位数据就是内存地址+1;存16位数据就是内存地址+2;存32位数据就是地址+4。
地址本身是32位的
*(__IO uint8_t*) ADDRESS,我的理解是这样的:
ADDRESS是一个32bit的数值;
(__IO uint8_t*) 将ADDRESS强制转换成地址指针,指针类型是uint8_t*,也就是单字节的指针,并不是说把ADDRESS强制转换成一个字节;
*(__IO uint8_t*) ADDRESS是取这个单字节指针的内容;
这么理解有问题吗?
ADDRESS是一个32bit的数值;
(__IO uint8_t*) 将ADDRESS强制转换成地址指针,指针类型是uint8_t*,也就是单字节的指针
....................................................
以上说的都没错,指针类型是uint8_t,而不是指针指向的内容是uint8_t
举个例子,我是这样理解,比如ADDRESS=0x12345678,*(__IO uint8_t*) ADDRESS就代表从0x12345678这个地址存放的第一个字节,*(__IO uint32_t*) ADDRESS就代表从0x12345678这个地址开始存放的4个字节。
再举个例子,我在程序中定义一个指针型的变量,uint16_t* ADDRESS,当我给这个指针变量赋值的时候,是应该给ADDRESS赋值一个地址吧,而且这个地址指向的是一个uint16_t型的变量,比如uint16_t aaa= 0x0001; aaa的地址就是之前例子中的0x12345678,那么ADDRESS = &aaa;即:ADDRESS = 0x12345678;
现在如果我做个强制转换:
*(uint8_t*) ADDRESS的值是不是应该就是aaa的低字节0x01,并不是把0x12345678强制转换成0x78,然后以0x00000078为地址,取该地址内容。
所以还是想不通您说的这个问题,以上是我的理解。您看下有问题吗?
一起学习