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

DCMI简介

 

STM32F4DCMI接口包括如下信号

 

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

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

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

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

 

DCMI接口的数据与PIXCLK(即PCLK)保持同步,并根据像素时钟的极性在像素时钟上升沿/下降沿发生变化。HSYNCHREF)信号指示行的开始/结束,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
} 

 

  • 25
    点赞
  • 175
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值