本帖最后由 Gohome_soon 于 2017-9-13 17:30 编辑
最近使用STM32F429IGT6 +SDRAM画了一块板子,准备将DCMI采集的OV5640数据存在SDRAM中,但是发现,在搬运了一帧后,STM32不是卡死就是重启
STM32F429IGT6 我没有画外部晶振,而是使用内部HSI,时钟设置为168M
硬件连接:FMC_NBL[0:3]顺序接反了有没有影响呀?,
SDRAM型号是32位的 MT48LC4M32B2P-7 IT
OV5640使用的是原子的OV5640模块,输出图像设置为160*120
SDRAM初始化程序:
变量定义:[mw_shl_code=c,true]
u8 stream_data_buf[stream_buf_size] __attribute__((at(0XC0000000)));
u8 rgb565_buff[40*1024];[/mw_shl_code]
[mw_shl_code=c,true]void SDRAM_InitSequence(void)
{
FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure;
uint32_t tmpr = 0;
/* 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)
{
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 4 --------------------------------------------------------------------*/
/* Insert 100 ms delay */
delay_ms(300);
/* 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 */
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* 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 */
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* Send the first command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* Send the second command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 7 --------------------------------------------------------------------*/
/* Program the external memory mode register */
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
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 */
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* 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(1200);
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
}
__IO uint32_t uwWriteReadStatus = 0;
void SDRAM_Init(void)
{
FMC_SDRAMInitTypeDef FMC_SDRAMInitStructure;
FMC_SDRAMTimingInitTypeDef FMC_SDRAMTimingInitStructure;
/* GPIO configuration for FMC SDRAM bank */
SDRAM_HW_Init();
/* Enable FMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
/* FMC Configuration ---------------------------------------------------------*/
/* FMC SDRAM Bank configuration */
/* Timing configuration for 84 Mhz of SD clock frequency (168Mhz/2) */
/* TMRD: 2 Clock cycles */
FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;
/* TXSR: min=70ns (7x11.90ns) */
FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7;
/* TRAS: min=42ns (4x11.11ns) max=120k (ns) */
FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;
/* TRC: min=70 (7x11.11ns) */
FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7;
/* TWR: min=1+ 7ns (1+1x11.11ns) */
FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;
/* TRP: 20ns => 2x11.11ns */
FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;
/* TRCD: 20ns => 2x11.11ns */
FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;
//FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_SDRAM_DEVICE;
/* FMC SDRAM control configuration */
FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank1_SDRAM;
/* Row addressing: [7:0] */
FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
/* Column addressing: [11:0] */
FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_12b;
FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_32b;
FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
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_Enable;
FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1;
FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
/* FMC SDRAM bank initialization */
FMC_SDRAMInit(&FMC_SDRAMInitStructure);
/* FMC SDRAM device initialization sequence */
SDRAM_InitSequence();
/* Disable write protection */
FMC_SDRAMWriteProtectionConfig(FMC_Bank1_SDRAM,DISABLE);
}[/mw_shl_code]OV5640和DCMI初始化,DCMI 使用原子的程序
[mw_shl_code=c,true]
while(OV5640_Init())//初始化OV5640
{
curr_times++;
delay_ms(1);
if(curr_times>=TIME_OUT)
{
showErrorInformation("Can't Find OV5640!
");
break;
}
}
if(curr_times<TIME_OUT)
{
// SHOW_OV5640_INFO("OV5640 Init 1
");
//delay_ms(100);
curr_times=0;
//自动对焦初始化
OV5640_RGB565_Mode(); //RGB565模式
OV5640_Focus_Init();
OV5640_Light_Mode(0); //自动模式
OV5640_Color_Saturation(3);// {MOD}彩饱和度0
OV5640_Brightness(4); //亮度0
OV5640_Contrast(3); //对比度0
OV5640_Sharpness(33); //自动锐度
OV5640_Focus_Constant();//启动持续对焦
OV5640_DCMI_Init(); //DCMI配置
DCMI_DMA_Init((uint32_t)rgb565_buff,0,160*120/2,0,1);//DCMI DMA配置
OV5640_WR_Reg(0x3035,0X51);//降低输出帧率,否则可能抖动
OV5640_OutSize_Set(4,0,160,120); //满屏缩放显示
SHOW_OV5640_INFO("OV5640 Init End
");
DCMI_Start(); //启动传输
// SHOW_OV5640_INFO("DCMI START End
");
}[/mw_shl_code]
首先DCMI将RGB565 数据传输到 stm32 内 RAM,然后再将数据拷贝到SDRAM中,循环运行,跑不了多久,stm32就会卡死,重启
while主循环
[mw_shl_code=c,true]while(1)
{
if(getSysTick()-last_times>=1000)
{
curr_times++;
PGout(9)=!PGout(9);
printf("Time is %d s
",curr_times);
last_times=getSysTick();
//Flag_UsbRxEnd |= (1<<4);//数据准备完成开始发送
}
if((Flag_UsbRxEnd&(1<<4)))
{
for(i=0;i<3840;i++)
{
stream_data_buf
=rgb565_buff;
}
Flag_UsbRxEnd&=(~(1<<4));
printf("test_%d
",j++);
DCMI_Start(); //启动传输
}
[/mw_shl_code]
DCMI 传输完成中断
[mw_shl_code=c,true]//DCMI中断服务函数
void DCMI_IRQHandler(void)
{
u32 i=0;
if(DCMI->MISR&0X01) //捕获到一帧图像
{
__disable_irq();
DCMI->ICR|=1<<0; //清除帧中断
DCMI_Stop();
for(i=0;i<0xFFFF;i++);
Flag_UsbRxEnd |= (1<<4);//数据准备完成开始发送
ov_frame++;
printf("BMP end_%d
",Flag_UsbRxEnd);
__enable_irq();
}
}[/mw_shl_code]
当SDRAM自测时,它又是正常的
自测程序
[mw_shl_code=c,true]uint32_t sdram_checksum(void)
{
uint32_t uwIndex = 0;
uint32_t ubReaddata_32b = 0;
/* Write data to the SDRAM memory */
for (uwIndex = 0; uwIndex < SDRAM_SIZE; uwIndex++)
{
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
*(__IO uint32_t*) (SDRAM_BANK_ADDR + 4*uwIndex) = (uint32_t)uwIndex+0x8B732167;
}
/* Read back data from the SDRAM memory */
for (uwIndex = 0; uwIndex < SDRAM_SIZE; uwIndex++)
{
ubReaddata_32b = *(__IO uint32_t*) (SDRAM_BANK_ADDR + 4*uwIndex);
if (ubReaddata_32b != (uint32_t)uwIndex+0x8B732167)
{
uwWriteReadStatus++;
}
ubReaddata_32b=0;
}
/* Erase SDRAM memory */
for (uwIndex = 0; uwIndex < SDRAM_SIZE; uwIndex++)
{
*(__IO uint32_t*) (SDRAM_BANK_ADDR + 4*uwIndex) = (uint32_t)0x00000000;
}
return uwWriteReadStatus;
}[/mw_shl_code]
DCMI 和SDRAM以前使用STM32F429-Dis 一起用过的,换成自己画的板子就不行了哪,是应为我没有使用外部晶振吗
确实不知道怎么弄了,求众坛友们解惑呀
一周热门 更多>