本人移植的官方ov2640(ART-PI)驱动程序,在stm32F429上接的微雪的扩展板子连得微雪的ov2640可以初始化成功也可以使用,但是最近迁到stm32f407上发现无法初始化成功。另外原子的自带晶振,以下是关键代码片段:
static rt_err_t ov2640_read_id(struct rt_i2c_bus_device *bus)
{
rt_uint8_t read_value[2];
rt_uint16_t id = 0;
read_reg(bus, OV2640_SENSOR_MIDH, 1, &read_value[0]);
read_reg(bus, OV2640_SENSOR_MIDL, 1, &read_value[1]);
id = ((rt_uint16_t)(read_value[0] << 8) & 0xFF00);
id |= ((rt_uint16_t)(read_value[1]) & 0x00FF);
if (id != OV2640_MID)
{
LOG_E("ov2640 init error, mid: 0x%x ", id);
return RT_ERROR;
}
LOG_I("ov2640 read mid success, mid: 0x%x ", id);
read_reg(bus, OV2640_SENSOR_PIDH, 1, &read_value[0]);
read_reg(bus, OV2640_SENSOR_PIDL, 1, &read_value[1]);
id = ((rt_uint16_t)(read_value[0] << 8) & 0xFF00);
id |= ((rt_uint16_t)(read_value[1]) & 0x00FF);
if (id != OV2640_PID)
{
LOG_E("ov2640 init error, pid: 0x%04x ", id);
return RT_ERROR;
}
LOG_I("ov2640 read hid success, pid: 0x%04x", id);
return RT_EOK;
}
void rt_stm32407_atk_miniexpolre()
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOG_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_9|GPIO_PIN_15;//PG9,15 PG9---->PWDN PG15------>RST
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;
GPIO_Initure.Pull=GPIO_PULLUP;
GPIO_Initure.Speed=GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOG,&GPIO_Initure);
rt_thread_mdelay(50);
/* refence
OV2640_PWDN=0; //POWER ON
delay_ms(10);
OV2640_RST=0; //
delay_ms(10);
OV2640_RST=1; //
*/
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_9,GPIO_PIN_RESET);
rt_thread_mdelay(10);
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_15,GPIO_PIN_RESET);
rt_thread_mdelay(10);
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_15,GPIO_PIN_SET);
rt_thread_mdelay(10);
__HAL_RCC_GPIOD_CLK_ENABLE(); //
//PD6.73?ê??ˉéè??
GPIO_Initure.Pin=GPIO_PIN_6|GPIO_PIN_7;
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //í?íìê?3?
GPIO_Initure.Pull=GPIO_PULLUP; //é?à-
GPIO_Initure.Speed=GPIO_SPEED_FAST; //?ì?ù
HAL_GPIO_Init(GPIOD,&GPIO_Initure);
}
int rt_ov2640_init(void)
{
rt_uint16_t i = 0;
rt_device_t dcmi_dev = RT_NULL;
rt_stm32407_atk_miniexpolre();
i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
if (i2c_bus == RT_NULL)
{
LOG_E("can't find %c deivce", I2C_NAME);
return RT_ERROR;
}
write_reg(i2c_bus, OV2640_DSP_RA_DLMT, 0x01);
rt_thread_delay(10);
write_reg(i2c_bus, OV2640_SENSOR_COM7, 0x80);
rt_thread_delay(500);
ov2640_read_id(i2c_bus);
for (i = 0; i < sizeof(ov2640_svga_init_reg_tbl) / 2; i++)
{
write_reg(i2c_bus, ov2640_svga_init_reg_tbl[i][0], ov2640_svga_init_reg_tbl[i][1]);
}
ov2640_rgb565_mode();
ov2640_set_light_mode(0);
ov2640_set_color_saturation(3);
ov2640_set_brightness(4);
ov2640_set_contrast(3);
ov2640_jpeg_mode();
ov2640_set_image_window_size(0, 0, 800,600);
ov2640_set_image_out_size(800, 600);
//ov2640_set_image_window_size(0, 0, 1200,800);
//ov2640_set_image_out_size(1200, 800);
dcmi_dev = rt_device_find("dcmi");
if (dcmi_dev == RT_NULL)
{
LOG_E("can't find dcmi device!");
return RT_ERROR;
}
rt_device_open(dcmi_dev, RT_DEVICE_FLAG_RDWR);
jpeg_data_buf = rt_malloc(JPEG_BUF_SIZE);
if (RT_NULL == jpeg_data_buf)
{
rt_kprintf("jpeg data buf malloc error!\n");
return RT_ERROR;
}
/* start dcmi capture 开启双缓冲*/
//rt_hw_dcmi_dma_config((rt_uint32_t)JPEG_LINE0_BUF, (rt_uint32_t)JPEG_LINE1_BUF, JPEG_LINE_SIZE);
rt_kprintf("camera init success!\n");
return RT_EOK;
}
INIT_APP_EXPORT(rt_ov2640_init);
原子的初始化代码片段:
u8 OV2640_Init(void)
{
u16 i=0;
u16 reg;
//ÉèÖÃIO
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOG_CLK_ENABLE(); //¿ªÆôGPIOGʱÖÓ
GPIO_Initure.Pin=GPIO_PIN_9|GPIO_PIN_15;//PG9,15
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //ÍÆÍìÊä³ö
GPIO_Initure.Pull=GPIO_PULLUP; //ÉÏÀ
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //¸ßËÙ
HAL_GPIO_Init(GPIOG,&GPIO_Initure); //³õʼ»¯
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_9,GPIO_PIN_RESET);
delay_ms(10);
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_15,GPIO_PIN_RESET);
delay_ms(10);
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_15,GPIO_PIN_SET);
delay_ms(10);
// OV2640_PWDN=0; //POWER ON
// delay_ms(10);
// OV2640_RST=0; //¸´Î»OV2640
// delay_ms(10);
// OV2640_RST=1; //½áÊø¸´Î»
SCCB_Init(); //³õʼ»¯SCCB µÄIO¿Ú
SCCB_WR_Reg(OV2640_DSP_RA_DLMT, 0x01); //²Ù×÷sensor¼Ä´æÆ÷
SCCB_WR_Reg(OV2640_SENSOR_COM7, 0x80); //Èí¸´Î»OV2640
delay_ms(50);
reg=SCCB_RD_Reg(OV2640_SENSOR_MIDH); //¶ÁÈ¡³§¼ÒID ¸ß°Ëλ
reg<<=8;
reg|=SCCB_RD_Reg(OV2640_SENSOR_MIDL); //¶ÁÈ¡³§¼ÒID µÍ°Ëλ
if(reg!=OV2640_MID)
{
printf("MID:%d\r\n",reg);
return 1;
}
printf("MID:%x\r\n",reg);
reg=SCCB_RD_Reg(OV2640_SENSOR_PIDH); //¶ÁÈ¡³§¼ÒID ¸ß°Ëλ
reg<<=8;
reg|=SCCB_RD_Reg(OV2640_SENSOR_PIDL); //¶ÁÈ¡³§¼ÒID µÍ°Ëλ
if(reg!=OV2640_PID)
{
printf("HID:%d\r\n",reg);
//return 2;
}
printf("HID:%x\r\n",reg);
//³õʼ»¯ OV2640,²ÉÓÃSXGA·Ö±æÂÊ(1600*1200)
for(i=0;i<sizeof(ov2640_uxga_init_reg_tbl)/2;i++)
{
SCCB_WR_Reg(ov2640_uxga_init_reg_tbl[i][0],ov2640_uxga_init_reg_tbl[i][1]);
}
return 0x00; //ok
}
微雪的ov2640原理图:
原子的ov2640原理图:
二者的区别SCL SDA应该是原子没有上拉
原子在模拟sscb初始化的时候gpio上拉了,
我的rtt下模拟iic的引脚定义
目前现象初始化读id不正确,不知道哪里的问题。恳请大佬指点迷津
现在可以读到id了,但是执行的时间太慢了啊。
90多秒钟才能配置完
看看硬件的区别吧,是不是没接上拉电阻之类的问题。或者引脚配置模式问题。
感谢专家,牛逼~好了
试了一下确实变快了
PP用在I2C真是胆大,还是老实点用上拉电阻吧。
@aozima 正点原子的都是PP