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

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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版