OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8227|回复: 5

ov7670 正点原子摄像头 V2.2版 sccb读取是0xff ???

[复制链接]

260

主题

809

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1896
金钱
1896
注册时间
2012-10-28
在线时间
357 小时
发表于 2013-5-13 09:36:10 | 显示全部楼层 |阅读模式
现在在捣鼓这个ov7670 v2.2 带fifo的摄像头,目前通过sccb进行读写测试时,写摄像头有应答,可以; 但是读出来的数据全部是0xff,

SCCB->SCL   外部已经加了上4.7K拉电阻
SCCB->SDA   外部已经加了上4.7K拉电阻
程序如下:

#define SCCB_ID   0X42   //OV7670的ID

#define SCCB_SEND_ACK (0x10)
#define SCCB_SEND_NACK (0x11)  

#define SCCB_STATE_NACK (0x20)
#define SCCB_STATE_ACK  (0x21)


#define SCCB_SCL  GPIOEout(2)        // 定义 I2C-SCL 为 GPIOE_Pin_2
#define SCCB_SDA  GPIOEout(3)        // 定义 I2C-SDA 为 GPIOE_Pin_3

#define SCCB_SCL_L   (SCCB_SCL=0)    //#define I2C1_SCL_L         GPIOB->BSRRL = GPIO_Pin_6
#define SCCB_SCL_H   (SCCB_SCL=1)    //#define I2C1_SCL_H         GPIOB->BSRRH = GPIO_Pin_6

#define SCCB_SDA_L   (SCCB_SDA=0)    //#define I2C1_SDA_L         GPIOB->BSRRL = GPIO_Pin_7
#define SCCB_SDA_H   (SCCB_SDA=1)    //#define I2C1_SDA_H         GPIOB->BSRRH = GPIO_Pin_7
   
 
#define SCCB_SDA_IN()  GPIOEin(3)
#define SCCB_SDA_OUT() GPIOEout(3)  
 
 
#define SCCB_SDA_READ      ((GPIOE->IDR)  & GPIO_Pin_3)




void SCCB_Delay(u16 i)
{        
   while(i--); 
}



#define SCCB_Delay_5us     SCCB_Delay(8)
#define SCCB_Delay_3us     SCCB_Delay(6)
#define SCCB_Delay_2us     SCCB_Delay(4)
#define SCCB_Delay_1us     SCCB_Delay(2)


void SCCB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //SCCB  SCL->E2, SDA->E3
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE, &GPIO_InitStructure);

SCCB_SCL_H;
SCCB_Delay_5us;
SCCB_Delay_5us;
SCCB_SDA_H;
SCCB_Delay_5us;    
    
}


/**********************************************************
启动子程序
在 SCL 高电平期间 SDA 发生负跳变【从高到低】
scl为高电平期间,sda产生一个下降沿
 **********************************************************/
u8 SCCB_Start(void)
{
  u8 i;
SCCB_SDA_H;
  SCCB_SCL_H;
SCCB_Delay_5us;
  
i=0;
while((SCCB_SDA_READ == 1) && (i<250)) //如果SCCB_SDA=1,表示被控器无应答或损坏
{
i++; //计时开始,
if(i==249) //如果计时到了249,器件还没有应答则自动退出
return (SCCB_STATE_NACK);
}
      
  
SCCB_SDA_L;
  SCCB_Delay_5us;
i=0;
while((SCCB_SDA_READ == 1) && (i<250)) //如果SCCB_SDA=1,表示被控器无应答或损坏
{
i++; //计时开始,
if(i==249) //如果计时到了249,器件还没有应答则自动退出
return (SCCB_STATE_NACK);
}
 
  
  SCCB_SCL_L;
  SCCB_Delay_2us;
  
  return SCCB_STATE_ACK; //SUCCESS;
}


/**********************************************************
停止子函数
在 SCL 高电平期间 SDA 发生正跳变 【从低到高】
scl高电平期间,sda产生一上升沿
 **********************************************************/
void SCCB_Stop(void)
{
  SCCB_SDA_L;
  SCCB_Delay_1us;
SCCB_SCL_H;
SCCB_Delay_5us;
SCCB_SDA_H;
  SCCB_Delay_3us;
}


/**********************************************************
//读一字节 ack: SCCB_SEND_ACK 时应答,SCCB_SEND_NACK 时不应答
 **********************************************************/
u8 SCCB_ReadByte(unsigned char ack) //【非常好】
{
u8 i = 0,Read_Data=0;
  SCCB_SDA_H;
  SCCB_SDA_IN(); //设置SDA为输入  
for(i=0;i<8;i++)          // 循环移入8个位
{
    
SCCB_Delay_1us;          //5us
    SCCB_SCL_L;
    SCCB_Delay_5us;
    SCCB_SCL_H;
SCCB_Delay_5us;
    Read_Data <<= 1;
    
if(SCCB_SDA_READ)        //读SDA
{
      Read_Data++;
}
}
  SCCB_SCL_L;
  SCCB_Delay_3us;      //5us
  SCCB_SDA_OUT(); //设置SDA为输出    
SCCB_Delay_3us;      //5us
  if(ack == SCCB_SEND_ACK)
 SCCB_SDA_L;       //发送应答
  else
    SCCB_SDA_H;       //发送非应答
  
  SCCB_Delay_2us;      //5us
SCCB_SCL_H;
  SCCB_Delay_5us;
  SCCB_SCL_L;
  SCCB_Delay_1us;      //5us
return (Read_Data);
}


/**********************************************************
//向总线写一字节,并返回有无应答
 **********************************************************/
unsigned char SCCB_WriteByte(unsigned char write_data)
{
  unsigned char i;
  for(i=0;i<8;i++)
  {
    if(write_data & 0x80)
     SCCB_SDA_H;
    else
     SCCB_SDA_L; 
    
    SCCB_Delay_1us;
    SCCB_SCL_H;     //置时钟线为高,通知被控器开始接收数据位 
    SCCB_Delay_5us;
    SCCB_SCL_L;
    write_data <<= 1;
     
  }
SCCB_SDA_IN(); //设置SDA为输入
  SCCB_Delay_2us;
  SCCB_SDA_H;
  SCCB_Delay_2us;
  SCCB_SCL_H;
  SCCB_Delay_3us;
  
i=0;
while((SCCB_SDA_READ == 1) && (i<250)) //如果SCCB_SDA=1,表示被控器无应答或损坏
{
i++; //计时开始,
if(i==249) //如果计时到了249,器件还没有应答则自动退出
return (SCCB_STATE_NACK);
}

SCCB_SCL_L;
SCCB_Delay_2us;
SCCB_SDA_OUT(); //设置SDA为输出  
return (SCCB_STATE_ACK);  
}


//写寄存器
//返回值:SCCB_STATE_ACK->成功; SCCB_STATE_NACK->失败.
u8 SCCB_WR_Reg(u8 reg,u8 data)
{
u8 res = SCCB_STATE_NACK;
SCCB_Start(); //启动SCCB传输
res=SCCB_WriteByte(SCCB_ID); //写器件ID
if(SCCB_STATE_NACK == res)
res=1;  
if(SCCB_STATE_NACK == SCCB_WriteByte(reg))
res=1; 
 
if(SCCB_STATE_NACK == SCCB_WriteByte(data))
res=1;
 
SCCB_Stop();  
  return res;
}


//读寄存器
//返回值:读到的寄存器值
u8 SCCB_RD_Reg(u8 reg)
{
u8 val=0;
SCCB_Start(); //启动SCCB传输
printexp(USART1, "DCMI_id",SCCB_WriteByte(SCCB_ID),16) ; //写器件ID  

  //SCCB_WriteByte(reg); //写寄存器地址  
 printexp(USART1, "DCMI_reg",SCCB_WriteByte(reg),16) ;
SCCB_Stop();   
SCCB_Delay_5us;

 

//设置寄存器地址后,才是读
SCCB_Start();
//SCCB_WriteByte(SCCB_ID|0X01); //发送读命令  
printexp(USART1, "SCCB_ID|0X01",SCCB_WriteByte(SCCB_ID|0X01),16) ;
  val=SCCB_ReadByte(SCCB_SEND_NACK); //读取数据
  SCCB_Stop();
printexp(USART1, "SCCB_val",val,16) ;
  return val;
}



//初始化成功返回0,否则返回1
u8 Cam_Init(void)
{
u8 temp;
u16 i=0;
GPIO_InitTypeDef GPIO_InitStructure;
DCMI_InitTypeDef DCMI_InitStructure;
//DMA_InitTypeDef  DMA_InitStructure;

RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE); //DCMI 
//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); //DMA2
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | 
RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE);//使能DCMI的GPIO时钟

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI); //DCMI D0
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI); //DCMI D1
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_DCMI); //DCMI D2
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_DCMI); //DCMI D3
GPIO_PinAFConfig(GPIOE, GPIO_PinSource4, GPIO_AF_DCMI); //DCMI D4
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI); //DCMI D5
GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_DCMI); //DCMI D6
GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_DCMI); //DCMI D7

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOE, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//---------------------------------------控制信号引脚定义---------------------------------------
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4| GPIO_Pin_6| GPIO_Pin_8; //DCMI 2->WRST, 3->RRST, 4->WEN, 6->RCLK, 8->OE(CS)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
//SYSCFG->CMPCR = 0x00000001; //使用IO 补偿单元,
//当GPIO 速度超过50M 的时候要考虑使用此设置
GPIO_Init(GPIOA, &GPIO_InitStructure);
//--------------VSYNC IN ---------------------------------
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //DCMI VSYNC
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //同步信号检测IO
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
//GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//SYSCFG->CMPCR = 0x00000001;
GPIO_Init(GPIOB, &GPIO_InitStructure);
DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Falling;
DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;
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);


/*
  DMA_DeInit(DMA2_Stream1);
  DMA_InitStructure.DMA_Channel = DMA_Channel_1;
  DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = FSMC_LCD_ADDRESS;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  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_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);
*/
  SCCB_Init();         //初始化SCCB 的IO口   
temp = SCCB_WR_Reg(0x12,0x80);
  if(SCCB_STATE_NACK == temp) 
return 1; //复位SCCB  
delay_ms(50); 
//读取产品型号
  temp=SCCB_RD_Reg(0x0b);                               //就是这里,通过SCcB读取时,数据总是0xff,不知道河谷????
printexp(USART1, "DCMI_0X0B",temp,16) ;    //读取的数据发回给电脑查看
if(temp!=0x73) 
return 2;  
  temp=SCCB_RD_Reg(0x0a);   
if(temp!=0x76) 
return 2;
//初始化序列  
for(i=0;i<sizeof(ov7670_init_reg_tbl)/sizeof(ov7670_init_reg_tbl[0])/2;i++)
{
SCCB_WR_Reg(ov7670_init_reg_tbl[0],ov7670_init_reg_tbl[1]);
delay_ms(2);
  }
return 0x00; //OK
}










正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-5-13 11:09:02 | 显示全部楼层
不是SCCB有问题吧?是DCIM方式读取有问题吧?
我们的摄像头经过了AL422B FIFO芯片,不能用摄像头控制器直接去读了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

260

主题

809

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1896
金钱
1896
注册时间
2012-10-28
在线时间
357 小时
 楼主| 发表于 2013-5-13 15:08:55 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原来如此啊,
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2016-7-23
在线时间
2 小时
发表于 2016-7-23 15:14:43 | 显示全部楼层
hpdell 发表于 2013-5-13 15:08
回复【2楼】正点原子:
---------------------------------
原来如此啊,

你解决了吗??我也出现这个问题,初始化老是无法成功,temp值始终为255
回复 支持 反对

使用道具 举报

13

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
405
金钱
405
注册时间
2016-2-2
在线时间
66 小时
发表于 2016-10-18 15:41:51 | 显示全部楼层
正点原子 发表于 2013-5-13 11:09
不是SCCB有问题吧?是DCIM方式读取有问题吧?
我们的摄像头经过了AL422B&nbsp;FIFO芯片,不能用摄像头控制 ...

你好,今天我用V2.2摄像头模块,返回图像数据一直是0xff,,,,
回复 支持 反对

使用道具 举报

7

主题

50

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
216
金钱
216
注册时间
2016-2-24
在线时间
39 小时
发表于 2017-12-5 15:57:12 | 显示全部楼层
顶,我的也是
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 20:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表