打印
[STM32F4]

请教关于SDRAM读写出现的问题

[复制链接]
2114|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jjl3|  楼主 | 2018-8-22 21:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 jjl3 于 2018-8-22 21:56 编辑

大家好!

我做了一块STM32F427IIG的板子,上面有一块ISSI SDRAM IS42S32160F, SDRAM接的是FMC_SDNE1和FMC_SDCKE1引脚. 自己写了一个简单的SDRAM读写程序,但只要读SDRAM中的内容就进入到BusFault_handler中断里面去,查了一下说MPU要配置一下才行,我已经把MPU disable掉怎么还是进入 到BusFault_handler中断里面去? 请大家帮我看看,谢谢!

#include "stm32f4xx_conf.h"

#define SDRAM_BASE_ADDR ((uint8_t *)(0xD0000000))

/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M      25
/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      7


#define PLL_N      360
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2

static void SetSysClock(void)
{
/******************************************************************************/
/*            PLL (clocked by HSE) used as System clock source                */
/******************************************************************************/
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* Enable HSE */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Select regulator voltage output Scale 1 mode */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_VOS;

    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
   
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
   
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
   
    /* Configure the main PLL */
    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

    /* Enable the main PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till the main PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
   
    /* Enable the Over-drive to extend the clock frequency to 180 Mhz */
    PWR->CR |= PWR_CR_ODEN;
    while((PWR->CSR & PWR_CSR_ODRDY) == 0)
    {
    }
    PWR->CR |= PWR_CR_ODSWEN;
    while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
    {
    }      
    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

    /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock
         configuration. User can add here some code to deal with this error */
  }

}

void SystemInit(void)
{
  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Disable all interrupts */
  RCC->CIR = 0x00000000;
         
  /* Configure the System clock source, PLL Multiplier and Divider factors,
     AHB/APBx prescalers and Flash settings ----------------------------------*/
  SetSysClock();
}

void Clock_Init(void)
{
  /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH, GPIOI, GPIOK and GPIOJ interface clock */
  /* Enable Ethernet Reception clock and Ethernet Transmission clock*/
  RCC->AHB1ENR |= 0x0E0007FF;
  
  /* Enable the FMC interface clock */
  RCC->AHB3ENR |= 0x00000001;
}

void SystemInit_ExtMemCtl(void)
{
  register uint32_t tmpreg = 0, timeout = 0xFFFF;
  register uint32_t index;
  
/*-- FMC Configuration ------------------------------------------------------*/
  
  /* Configure and enable SDRAM bank2 */
  FMC_Bank5_6->SDCR[1] = 0x000029E9;             // 9-bit column addr; 13-bit raw addr
  FMC_Bank5_6->SDTR[1] = 0x01112551;      
  
  /* SDRAM initialization sequence */
  /* Clock enable command */
  FMC_Bank5_6->SDCMR = 0x00000009;
  tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
  while((tmpreg != 0) & (timeout-- > 0))
  {
    tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
  }
  
  /* Delay */
  for (index = 0; index<10000; index++);
  
  /* PALL command */
  FMC_Bank5_6->SDCMR = 0x0000000A;           
  timeout = 0xFFFF;
  while((tmpreg != 0) & (timeout-- > 0))
  {
  tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
  }
  
  /* Auto refresh command */
  FMC_Bank5_6->SDCMR = 0x000000AB;
  timeout = 0xFFFF;
  while((tmpreg != 0) & (timeout-- > 0))
  {
  tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
  }

  /* MRD register program */
  FMC_Bank5_6->SDCMR = 0x0000660C;
  timeout = 0xFFFF;
  while((tmpreg != 0) & (timeout-- > 0))
  {
  tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
  }
  
  /* Set refresh count */
  tmpreg = FMC_Bank5_6->SDRTR;
  FMC_Bank5_6->SDRTR = 0x00000381;
  
  /* Disable write protection */
  tmpreg = FMC_Bank5_6->SDCR[1];
  FMC_Bank5_6->SDCR[1] = (tmpreg & 0xFFFFFDFF);  
}

void GPIO_Init1(void)
{
  /* Connect PCx pins to FMC Alternate function */
  GPIOC->AFR[0]  = 0x0000000C;
  // GPIOC->AFR[1]  = 0x00007700;
  /* Configure PCx pins in Alternate function mode */  
  GPIOC->MODER   = 0x50000002;
  /* Configure PCx pins speed to 50 MHz */  
  GPIOC->OSPEEDR = 0x00000002;
  /* Configure PCx pins Output type to push-pull */  
  GPIOC->OTYPER  = 0x00000000;
  /* No pull-up, No pull-down for PCx pins */
  GPIOC->PUPDR   = 0x00000000;
  
  /* Connect PDx pins to FMC Alternate function */
  GPIOD->AFR[0]  = 0x000000CC;
  GPIOD->AFR[1]  = 0xCC000CCC;
  /* Configure PDx pins in Alternate function mode */  
  GPIOD->MODER   = 0xA02A000A;
  /* Configure PDx pins speed to 50 MHz */  
  GPIOD->OSPEEDR = 0xA02A000A;
  /* Configure PDx pins Output type to push-pull */  
  GPIOD->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PDx pins */
  GPIOD->PUPDR   = 0x00000000;

  /* Connect PEx pins to FMC Alternate function */
  GPIOE->AFR[0]  = 0xC00000CC;
  GPIOE->AFR[1]  = 0xCCCCCCCC;
  /* Configure PEx pins in Alternate function mode */
  GPIOE->MODER   = 0xAAAA800A;
  /* Configure PEx pins speed to 50 MHz */
  GPIOE->OSPEEDR = 0xAAAA800A;
  /* Configure PEx pins Output type to push-pull */  
  GPIOE->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PEx pins */
  GPIOE->PUPDR   = 0x00000000;

  /* Connect PFx pins to FMC Alternate function */
  GPIOF->AFR[0]  = 0x00CCCCCC;
  GPIOF->AFR[1]  = 0xCCCCC000;
  /* Configure PFx pins in Alternate function mode */   
  GPIOF->MODER   = 0xAA800AAA;
  /* Configure PFx pins speed to 50 MHz */
  GPIOF->OSPEEDR = 0xAA800AAA;
  /* Configure PFx pins Output type to push-pull */  
  GPIOF->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PFx pins */
  GPIOF->PUPDR   = 0x00000000;

  /* Connect PGx pins to FMC Alternate function */
  GPIOG->AFR[0]  = 0x00CC0CCC;
  GPIOG->AFR[1]  = 0xC000000C;
  /* Configure PGx pins in Alternate function mode */
  GPIOG->MODER   = 0x80020A2A;
  /* Configure PGx pins speed to 50 MHz */
  GPIOG->OSPEEDR = 0x80020A2A;
  /* Configure PGx pins Output type to push-pull */  
  GPIOG->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PGx pins */
  GPIOG->PUPDR   = 0x00000000;
  
  /* Connect PHx pins to FMC Alternate function */
  GPIOH->AFR[0]  = 0xCC000000;
  GPIOH->AFR[1]  = 0xCCCCCCCC;
  /* Configure PHx pins in Alternate function mode */
  GPIOH->MODER   = 0xAAAAA000;
  /* Configure PHx pins speed to 50 MHz */
  GPIOH->OSPEEDR = 0xAAAAA000;
  /* Configure PHx pins Output type to push-pull */  
  GPIOH->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PHx pins */
  GPIOH->PUPDR   = 0x00000000;
  
  /* Connect PIx pins to FMC Alternate function */
  GPIOI->AFR[0]  = 0xCCCCCCCC;
  GPIOI->AFR[1]  = 0x00000CC0;
  /* Configure PIx pins in Alternate function mode */
  GPIOI->MODER   = 0x0028AAAA;
  /* Configure PIx pins speed to 50 MHz */
  GPIOI->OSPEEDR = 0x0028AAAA;
  /* Configure PIx pins Output type to push-pull */  
  GPIOI->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PIx pins */
  GPIOI->PUPDR   = 0x00000000;
}

int main()
{
  uint32_t tmpreg;
  uint8_t *addr, i, temp;
   
  SystemInit();
  Clock_Init();
  GPIO_Init1();
  SystemInit_ExtMemCtl();
  
  MPU->CTRL   = 0x00000000;   //disable MPU
  
  GPIOC->ODR  = 0x00008000;        //GPIO点个灯
  
  addr = SDRAM_BASE_ADDR;
   
  *addr = 0xAA;   // 单步能执行到这步
   
temp = *addr;    // 只要执行到这句就进入到busfault中断里去出不来了
  
  while(1)
  {
  for(tmpreg = 0; tmpreg < 8000000; tmpreg++);
  if(temp == 0xAA)
     GPIOC->ODR  = GPIOC->ODR ^ 0x0000C000;
  else
     GPIOC->ODR  = GPIOC->ODR ^ 0x00004000;
  };
}
沙发
antusheng| | 2018-8-23 10:59 | 只看该作者
不用temp呢?

使用特权

评论回复
板凳
jjl3|  楼主 | 2018-8-23 14:12 | 只看该作者
本帖最后由 jjl3 于 2018-8-24 10:36 编辑

用temp只是读一下sdram中的内容,如果没有这一句,程序可以正常运行到结束,有这句的话就在busfault中断里出不来了。我怀疑应该不是硬件问题,可能还是配置问题,因为即使虚焊了最多是读出的值不对,而不应该是进到busfault中断中去。网上查有的说是mpu问题,但st例程中根本没提过mpu。设置SDRAM配置信息的函数是可以正常完成的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

265

帖子

2

粉丝