stm32f4的数字摄像头接口(DCMI)使用

您所在的位置:网站首页 图像采集是干什么用的 stm32f4的数字摄像头接口(DCMI)使用

stm32f4的数字摄像头接口(DCMI)使用

2024-07-07 03:12| 来源: 网络整理| 查看: 265

DCMI简介

 

STM32F4的DCMI接口包括如下信号

 

1,数据据输入(D[0:13]),接摄像头的数据输出。

2,水平同步(行同步)输入(HSYNC),接摄像头的HSYNC/HREF信号,用于确定一行数据的接收情况。

3,垂直同步(场同步)输入(VSYNC),接摄像头的VSYNC信号,用于确定一帧数据的接收情况。

4,像素时钟输入(PIXCLK),接摄像头的PCLK信号,同步时钟,数据接收同步信号。

 

DCMI接口的数据与PIXCLK(即PCLK)保持同步,并根据像素时钟的极性在像素时钟上升沿/下降沿发生变化。HSYNC(HREF)信号指示行的开始/结束,VSYNC信号指示帧的开始/结束。

DCMI的使用

1、配置时钟,初始化IO口

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE); //使能GPIOA B C E 时钟 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE); //使能DCMI时钟 //PA4/6初始化设置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6; //PA4/6 复用功能输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能输出 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6; // PB6/7 复用功能输出 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11; //PC6/7/8/9/11 复用功能输出 GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; //PE5/6 复用功能输出 GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化 GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI); //PA4 DCMI_HSYNC GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI); //PA6 DCMI_PCLK GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI); //PB7 DCMI_VSYNC GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI); //PC6 DCMI_D0 GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI); //PC7 DCMI_D1 GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_DCMI); //PC8 DCMI_D2 GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_DCMI); //PC9 DCMI_D3 GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_DCMI); //PC11 DCMI_D4 GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI); //PB6 DCMI_D5 GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_DCMI); //PE5 DCMI_D6 GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_DCMI); //PE6 DCMI_D7

2、根据时序配置DCMI接口

DCMI_DeInit();//清除原来的设置 DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; //连续模式 DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; //全帧捕获 DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; //8位数据格式 DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low; //HSYNC 低电平有效 DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising; //PCLK 上升沿有效 DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; //硬件同步HSYNC,VSYNC DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_Low; //VSYNC 低电平有效 DCMI_Init(&DCMI_InitStructure); DCMI_Cmd(ENABLE); //DCMI使能 //中断视情况配置 DCMI_ITConfig(DCMI_IT_FRAME, ENABLE); //开启帧中断 NVIC_InitStructure.NVIC_IRQChannel = DCMI_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); 代码 DCMI 初始化结构体 1 /** 2 * @brief DCMI 初始化结构体 3 */ 4 typedef struct 5 { 6 uint16_t DCMI_CaptureMode; /*选择连续模式或拍照模式 */ 7 uint16_t DCMI_SynchroMode; /*选择硬件同步模式还是内嵌码模式 */ 8 uint16_t DCMI_PCKPolarity; /*设置像素时钟的有效边沿*/ 9 uint16_t DCMI_VSPolarity; /*设置 VSYNC 的有效电平*/ 10 uint16_t DCMI_HSPolarity; /*设置 HSYNC 的有效边沿*/ 11 uint16_t DCMI_CaptureRate; /*设置图像的采集间隔 */ 12 uint16_t DCMI_ExtendedDataMode; /*设置数据线的宽度 */ 13 } DCMI_InitTypeDef;

这些结构体成员说明如下,其中括号内的文字是对应参数在 STM32 标准库中定义的宏: (1) DCMI_CaptureMode 本成员设置 DCMI的捕获模式,可以选择为连续摄像(DCMI_CaptureMode_Continuous) 或单张拍照 DCMI_CaptureMode_SnapShot。 (2) DCMI_SynchroMode 本成员设置 DCMI数据的同步模式,可以选择为硬件同步方式 (DCMI_SynchroMode_Hardware)或内嵌码方式(DCMI_SynchroMode_Embedded)。 (3) DCMI_PCKPolarity 本成员用于配置 DCMI接口像素时钟的有效边沿,即在该时钟边沿时,DCMI会对数 据线上的信号进行采样,它可以被设置为上升沿有效(DCMI_PCKPolarity_Rising)或下 降沿有效(DCMI_PCKPolarity_Falling)。 (4) DCMI_VSPolarity 本成员用于设置 VSYNC 的有效电平,当 VSYNC 信号线表示为有效电平时,表示新 的一帧数据传输完成,它可以被设置为高电平有效(DCMI_VSPolarity_High)或低电平 有效(DCMI_VSPolarity_Low)。 (5) DCMI_HSPolarity 类似地,本成员用于设置 HSYNC 的有效电平,当 HSYNC 信号线表示为有效电平时, 表示新的一行数据传输完成,它可以被设置为高电平有效(DCMI_HSPolarity_High)或 低电平有效(DCMI_HSPolarity_Low)。 (6) DCMI_CaptureRate 本成员可以用于设置 DCMI捕获数据的频率,可以设置为全采集、半采集或 1/4 采集 (DCMI_CaptureRate_All_Frame/ 1of2_Frame/ 1of4_Frame),在间隔采集的情况下, STM32的 DCMI外设会直接按间隔丢弃数据。 (7) DCMI_ExtendedDataMode 本成员用于设置 DCMI的数据线宽度,可配置为 8/10/12及 14位数据线宽 (DCMI_ExtendedDataMode_8b/10b/12b/14b)。 配置完这些结构体成员后,我们调用库函数 DCMI_Init 即可把这些参数写入到 DCMI 的控制寄存器中,实现 DCMI的初始化。

DCMI的DMA传输

DCMI接收到的数据,存储在DCMI_DR寄存器(32位)里面,我们采用8位数据宽度,所以每4个像素时钟,才会捕获完32位数据,第一个字节存放在LSB位置,第四个字节存放在MSB位置,如下图所示:

DCMI支持DMA传输,当DCMI_CR寄存器中的CAPTURE位置1时,激活DMA接口。摄像头接口每次在其寄存器(DCMI_DR)中收到一个完整的32位数据块时,都将发一个DMA请求,由DMA将DCMI_DR寄存器的值搬运到目的地址。

/** * @brief 配置 DCMI/DMA 以捕获摄像头数据 * @param DMA_Memory0BaseAddr:本次传输的目的首地址 * @param DMA_BufferSize:本次传输的数据量(单位为字,即4字节) */ void OV2640_DMA_Config(uint32_t DMA_Memory0BaseAddr,uint16_t DMA_BufferSize) { DMA_InitTypeDef DMA_InitStructure; /* 配置DMA从DCMI中获取数据*/ /* 使能DMA*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_Cmd(DMA2_Stream1,DISABLE); while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE){} DMA_InitStructure.DMA_Channel = DMA_Channel_1; DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&DCMI->DR;//外设地址为:DCMI->DR DMA_InitStructure.DMA_Memory0BaseAddr = DMA_Memory0BaseAddr;//DMA传输的目的地址(传入的参数) DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize =DMA_BufferSize; //传输的数据大小(传入的参数) 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_HalfWord; 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_INC8; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /*DMA初始化 */ DMA_Init(DMA2_Stream1, &DMA_InitStructure); DMA_Cmd(DMA2_Stream1,ENABLE); while(DMA_GetCmdStatus(DMA2_Stream1) != ENABLE){} }

传输设置

//DCMI,启动传输 void DCMI_Start(void) { DMA_Cmd(DMA2_Stream1, ENABLE);//开启DMA2,Stream1 DCMI_CaptureCmd(ENABLE);//DCMI捕获使能 } //DCMI,关闭传输 void DCMI_Stop(void) { DCMI_CaptureCmd(DISABLE);//DCMI捕获使关闭 while(DCMI->CR&0X01); //等待传输结束 DMA_Cmd(DMA2_Stream1,DISABLE);//关闭DMA2,Stream1 }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3