STM32F429+OV2640中斷疑惑

2019-07-20 23:15发布

STM32F429+OV2640中斷疑惑 用的是DCMI+DMA
DCMI的帧中断不太理解,我DCMI设置CaptureMode设置为SnapShot模式,中断采用FRAME中断,单步调试之后发现,进中断之后显示的数据并不是一张完整的图片。



问题:这个帧中断的意思是DCMI接收完成一整张图片之后触发的中断吗?


下面我贴出我的配置,希望有经验的网友可以帮我看下问题所在:
原理图:

原理图 原理图        msb msb
DCMI数据接口采用8bits数据线,默认MSB方式设置,0V2640作为主设备

GPIO初始化:
/**************此处省略结构体定义与开启时钟的设定**********************/
…………
/**************power down 和 reset 模式的设置***********************/
  // setup the pwdn and rst pins
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  // pdwn set low to disable (active high)
  GPIO_ResetBits(GPIOD, GPIO_Pin_4);
  // rst low to reset for 200 ms
  GPIO_ResetBits(GPIOD, GPIO_Pin_5);
  mdelay(200);
  // rst high to disable (active low)
  GPIO_SetBits(GPIOD, GPIO_Pin_5);
  // should be running now !


/********************DCMI GPIO初始化*********************/
  /* Connect DCMI pins to AF13 ************************************************/
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);//HSYNC
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);//PCLK
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);//VSYNC

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_DCMI);//D6
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_DCMI);//D7  
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI);//D0
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI);//D1
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_DCMI);//D5  
  GPIO_PinAFConfig(GPIOH, GPIO_PinSource11, GPIO_AF_DCMI);//D2
  GPIO_PinAFConfig(GPIOH, GPIO_PinSource12, GPIO_AF_DCMI);//D3
  GPIO_PinAFConfig(GPIOH, GPIO_PinSource14, GPIO_AF_DCMI);//D4

    /* DCMI GPIO configuration **************************************************/
    /*
  D0 -- PC6
  D1 -- PC7
  D2 -- PH11
  D3 -- PH12
  D4 -- PH14
  D5 -- PD3
  D6 -- PB8
  D7 -- PB9
  PCK - PA6
  HS -- PA4
  VS -- PB7
  XCLK -- PA8 // mc0 driven
  Y1,Y0 Not connected
  RST -- PD5 // active low
  PWDN -- PD4 // active hi
  */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14;
  GPIO_Init(GPIOH, &GPIO_InitStructure);  

  /* PCLK(PA6) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /****** Configures the I2C2 used for OV2640 camera module configuration *****/
/* I2C2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

  /* GPIOB clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  /* Connect I2C2 pins to AF4 */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);

  /* Configure I2C2 GPIOs */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);


  /* Configure I2C2 */
  /* I2C DeInit */
  I2C_DeInit(I2C2);

  /* Set the I2C structure parameters */
  I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStruct.I2C_OwnAddress1 = 0xFE;
  I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStruct.I2C_ClockSpeed = 30000;

  /* Initialize the I2C peripheral w/ selected parameters */
  I2C_Init(I2C2, &I2C_InitStruct);

  /* Enable the I2C peripheral */
  I2C_Cmd(I2C2, ENABLE);


/*********************DCMI初始化*********************/
  /*** Configures the DCMI to interface with the OV2640 camera module ***/
  /* Enable DCMI clock */
  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);


  /* DCMI configuration */
  DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
  DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
  DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising;
  DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_Low;
  DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_High;
  DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
  DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;

  DCMI_Init(&DCMI_InitStructure);
  DCMI_ITConfig(DCMI_IT_VSYNC | DCMI_IT_FRAME | DCMI_IT_OVF | DCMI_IT_ERR, ENABLE);


/*******************DMA初始化****************/
  /* DMA2 Stream1 Configuration */
  DMA_DeInit(DMA2_Stream1);
  while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE);

  DMA_InitStructure.DMA_Channel = DMA_Channel_1;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(DCMI->DR);
  DMA_InitStructure.DMA_Memory0BaseAddr = SDRAM_BANK_ADDR + WRITE_READ_ADDR;//此处为外部SDRAM地址,用来把拍到的图片显示到LCD上
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 9600;//这里的buffersize定义成1可以进入DMA传输完成中断,定义成9600,发现进不了中断,把DMA传输的数据取出来看,也只有2700个(uint16_t)的数据,不知道是不是DMA的设置问题?
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

  DMA_ITConfig(DMA2_Stream1, DMA_IT_TC, ENABLE);
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);

/***********中断初始化*******************/

  /**
   * Interrupts
   */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
  NVIC_InitStructure.NVIC_IRQChannel = DCMI_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 21;
  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_Init(&NVIC_InitStructure);



/************0V2640设置***************/
/**
  * @brief  Configures the OV2640 camera in QQVGA mode.
  * @param  None
  * @retval None
  */
void OV2640_QQVGAConfig(void)
{
  uint32_t i;

  OV2640_Reset();
  mdelay(200);


  /* Initialize OV2640 */
  for(i=0; i<(sizeof(OV2640_QQVGA)/2); i++)
  {
    OV2640_WriteReg(OV2640_QQVGA[0], OV2640_QQVGA[1]);//这里的I2C读写都没有问题,我写进去后读出来看过,数据是正确的
    mdelay(2);
  }
}


/*******************QQVGA的设置************************/
/* Initialization sequence for QQVGA resolution (160x120) */
const char OV2640_QQVGA[][2]=
{
  {0xff, 0x00},
  {0x2c, 0xff},
  {0x2e, 0xdf},

  {0xff, 0x01},
  {0x3c, 0x32},
  {0x11, 0x00},//CLKRC: Clock Rate Control -- CLK = XVCLK/(CLKRC[5:0] + 1)
               //XVCLK: 24MHz
               //CLKRC: CLKRC[6] 0 -- 0 master mode; 1 slave mode
  {0x09, 0x02},//COM2: COM2[2] 0 -- 0 master mode; 1 slave mode
  {0x04, 0xA8},
  {0x13, 0xe5},
  {0x14, 0x48},
  {0x2c, 0x0c},
  {0x33, 0x78},
  {0x3a, 0x33},
  {0x3b, 0xfB},
  {0x3e, 0x00},
  {0x43, 0x11},
  {0x16, 0x10},
  {0x4a, 0x81},
  {0x21, 0x99},
  {0x24, 0x40},
  {0x25, 0x38},
  {0x26, 0x82},
  {0x5c, 0x00},
  {0x63, 0x00},
  {0x46, 0x3f},//FLL: Frame Lengtn Adjustment LSBs
               //Each bit will add 1 horizontal lines timing in frame
  {0x0c, 0x3c},
  {0x61, 0x70},
  {0x62, 0x80},
  {0x7c, 0x05},
  {0x20, 0x80},
  {0x28, 0x30},
  {0x6c, 0x00},
  {0x6d, 0x80},
  {0x6e, 0x00},
  {0x70, 0x02},
  {0x71, 0x94},
  {0x73, 0xc1},
  {0x3d, 0x34},
  {0x5a, 0x57},
  {0x12, 0x00},//COM7: COM7[3] 0 -- 0 master mode; 1 slave mode
  {0x11, 0x00},
  {0x17, 0x11},//HREFST MSB 8 bits, 3LSBs in REG32[2:0] Horizontal Window start: 0001 0001 110 -- 142
  {0x18, 0x75},//HREFEND MSB 8 bits, .............[5:3]...................end  : 0111 0101 110 -- 942
               //Horizontal Window width 942-142=800
  {0x19, 0x01},//VSTRT MSB 8 bits, 2LSB2 in COM1[1:0] Vertical Window Start: 0000 0001 11 -- 7
  {0x1a, 0x97},//VEND ......................COM1[3:2].................end  : 1001 0111 11 -- 607
               //Vertical window height 607-7=600
  {0x32, 0x36},//REG32 include horizontal window end/start position 3 LSBs
               //end:bit[5:3] 110
               //start: bit[2:0] 110
  {0x03, 0x0f},//REG COM1
               //end: bit[3:2] 11
               //start: bit[0:1] 11
  {0x37, 0x40},
  {0x4f, 0xbb},
  {0x50, 0x9c},
  {0x5a, 0x57},
  {0x6d, 0x80},
  {0x6d, 0x38},
  {0x39, 0x02},
  {0x35, 0x88},
  {0x22, 0x0a},
  {0x37, 0x40},
  {0x23, 0x00},
  {0x34, 0xa0},//ARCOM2 bit[2] Zoom window horizontal start point: 0
  {0x36, 0x1a},
  {0x06, 0x02},
  {0x07, 0xc0},
  {0x0d, 0xb7},
  {0x0e, 0x01},
  {0x4c, 0x00},

  {0xff, 0x00},
  {0xe5, 0x7f},
  {0xf9, 0xc0},
  {0x41, 0x24},
  {0xe0, 0x14},
  {0x76, 0xff},
  {0x33, 0xa0},
  {0x42, 0x20},
  {0x43, 0x18},
  {0x4c, 0x00},
  {0x87, 0xd0},
  {0x88, 0x3f},
  {0xd7, 0x03},
  {0xd9, 0x10},
  {0xd3, 0x82},
  {0xc8, 0x08},
  {0xc9, 0x80},
  {0x7d, 0x00},
  {0x7c, 0x03},
  {0x7d, 0x48},
  {0x7c, 0x08},
  {0x7d, 0x20},
  {0x7d, 0x10},
  {0x7d, 0x0e},
  {0x90, 0x00},
  {0x91, 0x0e},
  {0x91, 0x1a},
  {0x91, 0x31},
  {0x91, 0x5a},
  {0x91, 0x69},
  {0x91, 0x75},
  {0x91, 0x7e},
  {0x91, 0x88},
  {0x91, 0x8f},
  {0x91, 0x96},
  {0x91, 0xa3},
  {0x91, 0xaf},
  {0x91, 0xc4},
  {0x91, 0xd7},
  {0x91, 0xe8},
  {0x91, 0x20},
  {0x92, 0x00},
  {0x93, 0x06},
  {0x93, 0xe3},
  {0x93, 0x02},
  {0x93, 0x02},
  {0x93, 0x00},
  {0x93, 0x04},
  {0x93, 0x00},
  {0x93, 0x03},
  {0x93, 0x00},
  {0x93, 0x00},
  {0x93, 0x00},
  {0x93, 0x00},
  {0x93, 0x00},
  {0x93, 0x00},
  {0x93, 0x00},
  {0x96, 0x00},
  {0x97, 0x08},
  {0x97, 0x19},
  {0x97, 0x02},
  {0x97, 0x0c},
  {0x97, 0x24},
  {0x97, 0x30},
  {0x97, 0x28},
  {0x97, 0x26},
  {0x97, 0x02},
  {0x97, 0x98},
  {0x97, 0x80},
  {0x97, 0x00},
  {0x97, 0x00},
  {0xc3, 0xef},

  {0xff, 0x00},
  {0xba, 0xdc},
  {0xbb, 0x08},
  {0xb6, 0x24},
  {0xb8, 0x33},
  {0xb7, 0x20},
  {0xb9, 0x30},
  {0xb3, 0xb4},
  {0xb4, 0xca},
  {0xb5, 0x43},
  {0xb0, 0x5c},
  {0xb1, 0x4f},
  {0xb2, 0x06},
  {0xc7, 0x00},
  {0xc6, 0x51},
  {0xc5, 0x11},
  {0xc4, 0x9c},
  {0xbf, 0x00},
  {0xbc, 0x64},
  {0xa6, 0x00},
  {0xa7, 0x1e},
  {0xa7, 0x6b},
  {0xa7, 0x47},
  {0xa7, 0x33},
  {0xa7, 0x00},
  {0xa7, 0x23},
  {0xa7, 0x2e},
  {0xa7, 0x85},
  {0xa7, 0x42},
  {0xa7, 0x33},
  {0xa7, 0x00},
  {0xa7, 0x23},
  {0xa7, 0x1b},
  {0xa7, 0x74},
  {0xa7, 0x42},
  {0xa7, 0x33},
  {0xa7, 0x00},
  {0xa7, 0x23},
  {0xc0, 0xc8},//0xc8 image horizontal size 200
  {0xc1, 0x96},//0x96 image vertical size 150
  {0x8c, 0x00},
  {0x86, 0x3d},
  {0x50, 0x92},
  {0x51, 0x90},//HSIZE[7:0] 1001 0000 VHYX[3](HSIZE[3]): 1 1001 0000 -- 400
  {0x52, 0x2c},//BSIZE[7:0] 0010 1100 VHYX[7](HSIZE[8]): 1 0010 1100 -- 300
  {0x53, 0x00},//0
  {0x54, 0x00},//0
  {0x55, 0x88},//VHYX[3] is HSIZE[8]; VHYX[7] is VSIZE[8]: 1000 1000
  {0x5a, 0x50},
  {0x5b, 0x3c},
  {0x5c, 0x00},
  {0xd3, 0x04},
  {0x7f, 0x00},
  {0xda, 0x00},
  {0xe5, 0x1f},
  {0xe1, 0x67},
  {0xe0, 0x00},
  {0xdd, 0x7f},
  {0x05, 0x00},

  {0xff, 0x00},  
  {0xe0, 0x04},
  {0xc0, 0xa0},//图片长160
  {0xc1, 0x78},//图片款120
  {0x86, 0x3d},
  {0x50, 0x92},
  {0x51, 0x90},
  {0x52, 0x2c},
  {0x53, 0x00},
  {0x54, 0x00},
  {0x55, 0x88},
  {0x57, 0x00},
  {0x5a, 0x28},
  {0x5b, 0x1E},
  {0x5c, 0x00},
  {0xd3, 0x08},
  {0xe0, 0x00},
  {0xFF, 0x00},
  {0x05, 0x00},
  {0xDA, 0x08},
  {0xda, 0x09},
  {0x98, 0x00},
  {0x99, 0x00},
  {0x00, 0x00},
};

/*****************mian函数的程式*****************/
    DMA_Cmd(DMA2_Stream1, ENABLE);
    while ( DMA_GetCmdStatus(DMA2_Stream1) != ENABLE );
    DCMI_Cmd(ENABLE);
    DCMI_CaptureCmd(ENABLE);

    while(1);

/******************DCMI中断函数***********************/
void DCMI_IRQHandler(void)
{
    /* DCMI overrun */
    if ( DCMI_GetITStatus(DCMI_IT_OVF) != RESET) // Overflow interrupt mask
    {
      DCMI_ClearITPendingBit(DCMI_IT_OVF);
    }


    if ( DCMI_GetITStatus(DCMI_IT_FRAME) != RESET) // Frame capture complete interrupt mask
    {   
      DCMI_flag=1;           
      DCMI_ClearITPendingBit(DCMI_IT_FRAME);
    }


    if ( DCMI_GetITStatus(DCMI_IT_ERR) != RESET) // Synchronization error interrupt mask
    {
      DCMI_ClearITPendingBit(DCMI_IT_ERR);
    }


    if ( DCMI_GetITStatus(DCMI_IT_LINE) != RESET) // Line interrupt mask
    {   
      DCMI_ClearITPendingBit(DCMI_IT_LINE);
    }


    if ( DCMI_GetITStatus(DCMI_IT_VSYNC) != RESET) // Line interrupt mask
    {     
      DCMI_ClearITPendingBit(DCMI_IT_VSYNC);
    }
}



/***********************DMA中断函数***********************/
void DMA2_Stream1_IRQHandler(void)
{


    if ( DMA_GetITStatus(DMA2_Stream1, DMA_IT_DMEIF1) != RESET)
    { // direct mode error interrupt
      DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_DMEIF1);
    }


    if ( DMA_GetITStatus(DMA2_Stream1, DMA_IT_FEIF1) != RESET)
    { // FIFO error interrupt
      DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_FEIF1);
    }


    if ( DMA_GetITStatus(DMA2_Stream1, DMA_IT_HTIF1) != RESET)
    { // half transfer complete interrupt
      DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_HTIF1);
    }


    if ( DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1) != RESET)
    { // transfer complete interrupt
      DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
    }


    if ( DMA_GetITStatus(DMA2_Stream1, DMA_IT_TEIF1) != RESET)
    { // transfer error interrupt
      DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TEIF1);
    }


}



/******************实验结果说明******************/
虽然中断不正常,但是LCD上还是可以显示到一些奇怪的绿 {MOD}和黑 {MOD}的点,DCMI设置CaptureMode设置为连续模式,可以不断地刷出来奇怪的点的图片。


希望调试过的网友看看我的程式,可以帮帮我。










友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。