你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

SM32f429ZI通过FSMC读写SDRAM失败,求指教!

[复制链接]
逸云剑 提问时间:2017-12-14 19:38 /
使用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的大侠指导!谢谢。
收藏 评论8 发布时间:2017-12-14 19:38

举报

8个回答
涛哥2035 回答时间:2017-12-15 16:06:14
本帖最后由 whtt 于 2017-12-15 16:13 编辑

基础不牢靠。。。
*(__IO uint32_t*) ADDRESS是啥意思懂不?就是把ADDRESS这个数强制转换为地址指针,再取这个指针中的内容。STM32是32位系统,能随便改成*(__IO uint8_t*) 吗?*(__IO uint8_t*) 就把ADDRESS头掐了,只剩后8位地址的内容,赶快看看你0X0000 00xx位置内容变了没
涛哥2035 回答时间:2017-12-15 16:09:27
本帖最后由 whtt 于 2017-12-15 16:15 编辑

每个地址内容都是8位,所以存8位数据就是内存地址+1;存16位数据就是内存地址+2;存32位数据就是地址+4。
地址本身是32位的
逸云剑 回答时间:2017-12-15 16:22:51
找到问题了,粗心大意,引脚配置错了...
逸云剑 回答时间:2017-12-16 11:09:25
whtt 发表于 2017-12-15 16:06
基础不牢靠。。。
*(__IO uint32_t*) ADDRESS是啥意思懂不?就是把ADDRESS这个数强制转换为地址指针,再取 ...

*(__IO uint8_t*) ADDRESS,我的理解是这样的:
ADDRESS是一个32bit的数值;
(__IO uint8_t*) 将ADDRESS强制转换成地址指针,指针类型是uint8_t*,也就是单字节的指针,并不是说把ADDRESS强制转换成一个字节;
*(__IO uint8_t*) ADDRESS是取这个单字节指针的内容;

这么理解有问题吗?
涛哥2035 回答时间:2017-12-16 11:28:31
*(__IO uint8_t*) ADDRESS,我的理解是这样的:
ADDRESS是一个32bit的数值;
(__IO uint8_t*) 将ADDRESS强制转换成地址指针,指针类型是uint8_t*,也就是单字节的指针

....................................................
以上说的都没错,指针类型是uint8_t,而不是指针指向的内容是uint8_t
逸云剑 回答时间:2017-12-16 14:14:23
whtt 发表于 2017-12-16 11:28
*(__IO uint8_t*) ADDRESS,我的理解是这样的:
ADDRESS是一个32bit的数值;
(__IO uint8_t*) 将ADDRESS强 ...

举个例子,我是这样理解,比如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为地址,取该地址内容。

所以还是想不通您说的这个问题,以上是我的理解。您看下有问题吗?



涛哥2035 回答时间:2017-12-17 08:08:10
经过开发板的实际仿真,你是对的,(*) ADDRESS把地址转换为指针;(uint8_t*) ADDRESS指明指针指向的类型是uint3_t;*(uint8_t*) ADDRESS为该指针指向的内容。
逸云剑 回答时间:2017-12-18 16:47:16
whtt 发表于 2017-12-17 08:08
经过开发板的实际仿真,你是对的,(*) ADDRESS把地址转换为指针;(uint8_t*) ADDRESS指明指针指向的类型是u ...

一起学习

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版