OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3126|回复: 5

F429操作外部SDRAM失败问题

[复制链接]

4

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2017-7-12
在线时间
34 小时
发表于 2019-12-22 19:03:48 | 显示全部楼层 |阅读模式
5金钱
板子是阿波罗F429,看了原子哥的sdram教程,使用cubemx配置了FMC,然后操作SDRAM是失败的,看了FMC的寄存器值,和原子哥例程是一样的,不知道是什么原因导致的失败,求助各路大神,这是main函数,
  1. int main(void)
  2. {
  3.   /* USER CODE BEGIN 1 */
  4. int ts;
  5.   /* USER CODE END 1 */
  6.   

  7.   /* MCU Configuration--------------------------------------------------------*/

  8.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  9.   HAL_Init();

  10.   /* USER CODE BEGIN Init */

  11.   /* USER CODE END Init */

  12.   /* Configure the system clock */
  13.   SystemClock_Config();

  14.   /* USER CODE BEGIN SysInit */

  15.   /* USER CODE END SysInit */

  16.   /* Initialize all configured peripherals */
  17.   MX_USART1_UART_Init();
  18.         MX_GPIO_Init();
  19.   MX_FMC_Init();
  20.   /* USER CODE BEGIN 2 */
  21.         sdram_InitSequent(&hsdram1);
  22.        
  23.         //刷新频率计数器(以SDCLK频率计数),计算方法:
  24.         //COUNT=SDRAM刷新周期/行数-20=SDRAM刷新周期(us)*SDCLK频率(Mhz)/行数
  25.   //我们使用的SDRAM刷新周期为64ms,SDCLK=180/2=90Mhz,行数为8192(2^13).
  26.         //所以,COUNT=64*1000*90/8192-20=683
  27.         HAL_SDRAM_ProgramRefreshRate(&hsdram1, 683);

  28.         HAL_Delay(20);

  29.                 fsmc_sdram_test();

  30.   /* USER CODE END 2 */

  31.   /* Infinite loop */
  32.   /* USER CODE BEGIN WHILE */
  33.   while (1)
  34.   {
  35.     /* USER CODE END WHILE */
  36.     HAL_Delay(20);
  37.     /* USER CODE BEGIN 3 */
  38.   }
  39.   /* USER CODE END 3 */
  40. }
复制代码
sdram的测试代码
  1. //SDRAM内存测试            
  2. void fsmc_sdram_test(void)
  3. {  
  4.         uint32_t i=0;            
  5.         uint32_t temp=0;          
  6.         uint32_t sval=0;        //在地址0读到的数据                                            

  7.         //每隔16K字节,写入一个数据,总共写入2048个数据,刚好是32M字节
  8.         for(i=0;i<32*1024*1024;i+=16*1024)
  9.         {
  10.                 *(volatile uint32_t*)(Bank5_SDRAM_ADDR+i)=temp;
  11.                 temp++;
  12.         }
  13.         //依次读出之前写入的数据,进行校验                  
  14.         for(i=0;i<32*1024*1024;i+=16*1024)
  15.         {       
  16.           temp=*(volatile uint32_t*)(Bank5_SDRAM_ADDR+i);
  17.                 if(i==0)sval=temp;
  18.                 else if(temp<=sval)break;//后面读出的数据一定要比第一次读到的数据大.                             

  19.                 printf("SDRAM Capacity:%dKB\r\n",(uint16_t)(temp-sval+1)*16);//打印SDRAM容量
  20.         }                                         
  21. }       
复制代码

sdram初始化函数
  1. void sdram_InitSequent(SDRAM_HandleTypeDef *hsdram)
  2. {
  3.         uint32_t temp;
  4.        
  5.         sdram_send_cmd(hsdram->Init.SDBank, FMC_SDRAM_CMD_CLK_ENABLE, 1, 0);
  6.         HAL_Delay(1);
  7.         sdram_send_cmd(hsdram->Init.SDBank, FMC_SDRAM_CMD_PALL, 1, 0);
  8.         sdram_send_cmd(hsdram->Init.SDBank, FMC_SDRAM_CMD_AUTOREFRESH_MODE, 8, 0);
  9.        
  10.         temp = (uint32_t)        SDRAM_BURST_LENGTH_1        |                                //设置突发长度:1(可以是1/2/4/8)
  11.                                                                                 SDRAM_ADDR_MODE_SEQUENTIAL        |        //设置突发类型:连续(可以是连续/交错)
  12.                                                                                 SDRAM_CAS_LATENCY_3        |                                        //设置CAS值:3(可以是2/3)
  13.                                                                                 SDRAM_WRITE_MODE_SINGLE;                        //设置突发写模式:1,单点访问
  14.        
  15.         sdram_send_cmd(hsdram->Init.SDBank, FMC_SDRAM_CMD_LOAD_MODE, 1, temp);
  16. }
复制代码

FMC初始化,这部分是cubemx生成的
  1. void MX_FMC_Init(void)
  2. {
  3.   FMC_SDRAM_TimingTypeDef SdramTiming = {0};

  4.   /** Perform the SDRAM1 memory initialization sequence
  5.   */
  6.   hsdram1.Instance = FMC_SDRAM_DEVICE;
  7.   /* hsdram1.Init */
  8.   hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
  9.   hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
  10.   hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
  11.   hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
  12.   hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  13.   hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  14.   hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  15.   hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  16.   hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  17.   hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
  18.   /* SdramTiming */
  19.   SdramTiming.LoadToActiveDelay = 2;
  20.   SdramTiming.ExitSelfRefreshDelay = 8;
  21.   SdramTiming.SelfRefreshTime = 6;
  22.   SdramTiming.RowCycleDelay = 6;
  23.   SdramTiming.WriteRecoveryTime = 4;
  24.   SdramTiming.RPDelay = 2;
  25.   SdramTiming.RCDDelay = 2;

  26.   if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  27.   {
  28.     Error_Handler( );
  29.   }

  30. }

  31. static uint32_t FMC_Initialized = 0;

  32. static void HAL_FMC_MspInit(void){
  33.   /* USER CODE BEGIN FMC_MspInit 0 */

  34.   /* USER CODE END FMC_MspInit 0 */
  35.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  36.   if (FMC_Initialized) {
  37.     return;
  38.   }
  39.   FMC_Initialized = 1;
  40.   /* Peripheral clock enable */
  41.   __HAL_RCC_FMC_CLK_ENABLE();
  42.         __HAL_RCC_GPIOF_CLK_ENABLE();
  43.   __HAL_RCC_GPIOC_CLK_ENABLE();
  44.   __HAL_RCC_GPIOG_CLK_ENABLE();
  45.   __HAL_RCC_GPIOE_CLK_ENABLE();
  46.   __HAL_RCC_GPIOD_CLK_ENABLE();

  47.   
  48.   /** FMC GPIO Configuration  
  49.   PF0   ------> FMC_A0
  50.   PF1   ------> FMC_A1
  51.   PF2   ------> FMC_A2
  52.   PF3   ------> FMC_A3
  53.   PF4   ------> FMC_A4
  54.   PF5   ------> FMC_A5
  55.   PC0   ------> FMC_SDNWE
  56.   PC2   ------> FMC_SDNE0
  57.   PC3   ------> FMC_SDCKE0
  58.   PF11   ------> FMC_SDNRAS
  59.   PF12   ------> FMC_A6
  60.   PF13   ------> FMC_A7
  61.   PF14   ------> FMC_A8
  62.   PF15   ------> FMC_A9
  63.   PG0   ------> FMC_A10
  64.   PG1   ------> FMC_A11
  65.   PE7   ------> FMC_D4
  66.   PE8   ------> FMC_D5
  67.   PE9   ------> FMC_D6
  68.   PE10   ------> FMC_D7
  69.   PE11   ------> FMC_D8
  70.   PE12   ------> FMC_D9
  71.   PE13   ------> FMC_D10
  72.   PE14   ------> FMC_D11
  73.   PE15   ------> FMC_D12
  74.   PD8   ------> FMC_D13
  75.   PD9   ------> FMC_D14
  76.   PD10   ------> FMC_D15
  77.   PD14   ------> FMC_D0
  78.   PD15   ------> FMC_D1
  79.   PG2   ------> FMC_A12
  80.   PG4   ------> FMC_BA0
  81.   PG5   ------> FMC_BA1
  82.   PG8   ------> FMC_SDCLK
  83.   PD0   ------> FMC_D2
  84.   PD1   ------> FMC_D3
  85.   PG15   ------> FMC_SDNCAS
  86.   PE0   ------> FMC_NBL0
  87.   PE1   ------> FMC_NBL1
  88.   */
  89.   /* GPIO_InitStruct */
  90.   GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
  91.                           |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12
  92.                           |GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  93.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  94.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  95.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  96.   GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  97.   HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  98.   /* GPIO_InitStruct */
  99.   GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3;
  100.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  101.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  102.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  103.   GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  104.   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  105.   /* GPIO_InitStruct */
  106.   GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4
  107.                           |GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15;
  108.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  109.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  110.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  111.   GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  112.   HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  113.   /* GPIO_InitStruct */
  114.   GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
  115.                           |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
  116.                           |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
  117.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  118.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  119.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  120.   GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  121.   HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  122.   /* GPIO_InitStruct */
  123.   GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
  124.                           |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
  125.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  126.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  127.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  128.   GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  129.   HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  130.   /* USER CODE BEGIN FMC_MspInit 1 */

  131.   /* USER CODE END FMC_MspInit 1 */
  132. }
复制代码



最佳答案

查看完整内容[请看2#楼]

问题已经找到,是这个函数的实现出了问题,但是很奇怪的是仿真读出来寄存器的值又和原子哥的例程读出来的值是一样的,这里原因就不得而知了,这也是我一直觉得自己参数的设置没有问题的主要依据。。 总结:自己太粗心,寄存器参数的使用居然用了另一个结构体的参数。。。。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2017-7-12
在线时间
34 小时
 楼主| 发表于 2019-12-22 19:03:49 | 显示全部楼层
问题已经找到,是
  1. sdram_send_cmd
复制代码
这个函数的实现出了问题,但是很奇怪的是仿真读出来寄存器的值又和原子哥的例程读出来的值是一样的,这里原因就不得而知了,这也是我一直觉得自己参数的设置没有问题的主要依据。。
总结:自己太粗心,寄存器参数的使用居然用了另一个结构体的参数。。。。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2019-12-23 02:06:28 | 显示全部楼层
慢慢对比
回复

使用道具 举报

4

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2017-7-12
在线时间
34 小时
 楼主| 发表于 2019-12-23 09:56:20 | 显示全部楼层

原子哥有看出什么问题吗?我对比了很久确实没看出什么。
回复

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14407
金钱
14407
注册时间
2018-8-3
在线时间
1156 小时
发表于 2019-12-23 10:09:34 | 显示全部楼层
首先IO 自己对比下  那么多IO 实在看不下去了 IO 确定没有问题的话 那就看SDRAM的驱动代码那部分 时序这些参照例程的  还有就是指令这些顺序也必须一致
啊哈~加油!!
回复

使用道具 举报

4

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2017-7-12
在线时间
34 小时
 楼主| 发表于 2019-12-23 10:15:11 | 显示全部楼层
翼行园子 发表于 2019-12-23 10:09
首先IO 自己对比下  那么多IO 实在看不下去了 IO 确定没有问题的话 那就看SDRAM的驱动代码那部分 时序这些 ...

IO一个一个对比过了,驱动部分是指初始化吗?初始化指令的话也是对比过,确实都看不出有什么问题,也仿真对比过寄存器的数值,和原子哥的例程是一样的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-12 10:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表