STM32F103C8T6移植OV7670摄像头出现的若干问题

移植环境(蓝色粗体字为特别注意内容)
1,开发板:STM32F103C8T6最小系统开发板。

2,开发环境:Keil uv5

3,参考文献:https://blog.csdn.net/u011964923/article/details/50966735

最近在移植OV7670带FIFO摄像头到STM32F103,发现在摄像头初始化的地方总是出错,无法读取IDCode,各种尝试,返回的IDCode都是0,

int Sensor_Init(void)
{
	uint16_t i = 0;
	uint8_t Sensor_IDCode = 0;
		FIFO_WE_H();//先置1使能

	I2C_Configuration();
	if( 0 == I2C_WriteByte ( 0x12, 0x80 , ADDR_OV7670 ) )             /* Reset SCCB */
	{
		return 1 ;
	}

	Delay(1500);
	if( 0 == I2C_ReadByte( &Sensor_IDCode, 1, 0x0b,  ADDR_OV7670 ) )	 /* read ID */
	{
		return 2;	                              /* error*/
	}
	//	while(1){
	//  USART_OUT(USART1," Code->%d",Sensor_IDCode);
	//	Delay(500);
	//}
	if(Sensor_IDCode == OV7670)				  /* ID = OV7670 */
	{
		for( i = 0 ; i < OV7670_REG_NUM ; i++ )
		{
			if( 0 == I2C_WriteByte(  OV7670_Reg[i][0], OV7670_Reg[i][1] , ADDR_OV7670 ) )
			{
				return 3;
			}
		}
	}
	else										  /* NO ID */
	{
		//led();
		return 4;
	}


	return 0;
}
int I2C_ReadByte(uint8_t *pBuffer,   uint16_t length,   uint8_t ReadAddress,  uint8_t DeviceAddress)
{
	if(!I2C_Start())
	{
		return DISABLE;
	}
	I2C_SendByte( DeviceAddress );         /* 器件地址 */
	if( !I2C_WaitAck() )
	{
		I2C_Stop();
		return DISABLE;
	}
	I2C_SendByte( ReadAddress );           /* 设置低起始地址 */
	I2C_WaitAck();
	I2C_Stop();

	if(!I2C_Start())
	{
		return DISABLE;
	}
	I2C_SendByte( DeviceAddress + 1 );               /* 器件地址 */
	if(!I2C_WaitAck())
	{
		I2C_Stop();
		return DISABLE;
	}
	while(length)
	{
		*pBuffer = I2C_ReceiveByte();
		if(length == 1)
		{
			I2C_NoAck();
		}
		else
		{
			I2C_Ack();
		}
		pBuffer++;
		length--;
	}
	I2C_Stop();
	return ENABLE;
}
static int I2C_ReceiveByte(void)
{
	uint8_t i = 8;
	uint8_t ReceiveByte = 0;

	SDA_H;
	while(i--)
	{
		ReceiveByte <<= 1;
		SCL_L;
		I2C_delay();
		SCL_H;
		I2C_IN();
		I2C_delay();
		if(SDA_read)
		{
			ReceiveByte |= 0x01;
		}
	}
	SCL_L;
	I2C_OUT();
	return ReceiveByte;
}
#define SDA_read      SCCB_PORT->IDR  & SCCB_PIN_SDL

在查找问题的过程中,引脚初始化的时候由于没仔细检查,走了很多弯路。

确认引脚接线正确,程序里面写个while循环,之后用示波器测量SCL(SIOC)引脚波形,发现波形正确, 但是为什么无法读取IDCode呢,于是用示波器测量SDA(SIOD)引脚的电平,发现都是高电平,于是怀疑是不是stm32的引脚没有配置正确或者是损坏了,于是手动设置SDA引脚对应的IO口的电平,检测是否有变化,这么一测问题就出来了我SDA引脚接的是PB3,但是检测PB3都是高电平,很是困惑,于是换一个IO口试试,换到PB4,这回又总是低电平,难道PB4也出问题了??经过查找资料,发现这篇文章:点击打开链接,乖乖,居然是这个原因!!!于是main函数中加入这句:

void disableJTAG()
{
/*开启GPIOB的外设时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); //屏蔽所有作为JTAG口的GPIO口
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //屏蔽PB口上IO口JTAG功能

}

这下终于正常了。

需要注意一点就是,该摄像头初始化的时候,只需要接3跟数据线即可,即SCL,SDA,OE(使能)脚,当然还有VCC,GND,即可,读取FIFO数据的时候则需要把其他的数据线接上。

于是把整个工程打包,分享给大家,希望能够帮助大家,下载之后,按照工程说明连好线之后,工程直接运行就能把摄像头初始化,非常方便^_^

点击下载工程


猜你喜欢

转载自blog.csdn.net/pang9998/article/details/79807235