打印

STC12单片机驱动OV7670摄像头读取ID出错

[复制链接]
4864|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
MJM_WSY|  楼主 | 2013-5-26 17:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

void sccb_isda ()                                         //设置输入为高阻
{
//sbit  SCCB_SDA    =     P0^4;                                   // 数 据 线
//sbit  SCCB_SCL    =     P0^6;                                   // 时 钟 线
  P0M1=0x04;                                 /* 0001 0000    <第五位>*/
  P0M0=0x40;                                 /* 0100 0000    <第五位>*/
       
}

void sccb_osda ()                                         //设置输入为高阻
{
//sbit  SCCB_SDA    =     P0^4;                                   // 数 据 线
//sbit  SCCB_SCL    =     P0^6;                                   // 时 钟 线
  P0M1=0x00;          /* 0000 0000 */
  P0M0=0x14;          /* 0001 1000 */
       
}

//SCCB起始信号
//当时钟为高的时候,数据线的高到低,为SCCB起始信号
//在激活状态下,SDA和SCL均为低电平
void SCCB_Start(void)
{
        sccb_osda ();            //设定为输出模式
        SCCB_SCL=1;                    // 在 时 钟 线 高 的 时 候 数 据 线 由 高 至 低         
        SCCB_SDA=1;                         //数据线电平拉高
        Delay_US (5);                         //持续时间最少1.5US
        SCCB_SDA=0;                            // 数据线电平置为低
        Delay_US (5);                         //持续时间最少1.5US
        SCCB_SCL=0;            //数据线恢复低电平,单操作函数必要       
       
}


//SCCB停止信号
//当时钟为高的时候,数据线的低到高,为SCCB停止信号
//空闲状况下,SDA,SCL均为高电平
void SCCB_Stop(void)
{
        sccb_osda ();            //设定为输出模式
        SCCB_SCL=0;       
    SCCB_SDA=0;
    Delay_US (5);
        SCCB_SCL=1;       
        Delay_US (50);                         //持续时间最少1.5US
    SCCB_SDA=1;       
         Delay_US (50);

}  
//产生NA信号
void SCCB_No_Ack(void)
{
        sccb_osda ();            //设定为输出模式
        SCCB_SDA=1;       
        SCCB_SCL=1;       
                 Delay_US (50);
        SCCB_SCL=0;       
        SCCB_SDA=0;       
}
//SCCB,写入一个字节
//返回值:0,成功;1,失败.
INT8U SCCB_WR_Byte(INT8U dat)
{
        INT8U j,res;

        sccb_osda ();            //设定为输出模式         
        for(j=0;j<8;j++) //循环8次发送数据
        {
                if(dat&0x80)
                    SCCB_SDA=1;       
             else
                    SCCB_SDA=0;
                dat<<=1;
                Delay_US (50);
                SCCB_SCL=1;       
                Delay_US (50);
                SCCB_SCL=0;                  
        }                         
        Delay_US (10);
                
        sccb_isda ();           /*设定为输入模式*/
        SCCB_SCL=1;                        //接收第九位,以判断是否发送成功
        Delay_US (5000);

        if(SCCB_SDA)res=1;  //SDA=1发送失败,返回1
        else res=0;         //SDA=0发送成功,返回0
        Delay_US (10);
        SCCB_SCL=0;                 
        return res;  
}         
//SCCB 读取一个字节
//在SCL的上升沿,数据锁存
//返回值:读到的数据
INT8U  SCCB_RD_Byte(void)
{
   INT8U  temp=0,j;   
        /*设定为输入模式*/
        sccb_isda ();
        for(j=8;j>0;j--)         //循环8次接收数据
        {                               
                  Delay_US (10);
                SCCB_SCL=1;
                temp=temp<<1;
                Delay_US (10);
                if(SCCB_SDA==1)temp++;
                else temp|=0x00;   
                Delay_US (10);  
                SCCB_SCL=0;
        }       

        return temp;
}                                                             
//写寄存器
//返回值:0,成功;1,失败.
INT8U  SCCB_WR_Reg(INT8U reg,INT8U Data)
{
        INT8U  res=0;                                        //返回值的记录

        SCCB_Start();                                         //启动SCCB传输

        if(SCCB_WR_Byte(SCCB_ID))res=1;        //写器件ID 判断是否写入成功
        /*如果写入成功返回【0】,如果写入不成功则是返回【1】*/          
        Delay_US (300);   
          if(SCCB_WR_Byte(reg))res=2;                //写寄存器地址          
        Delay_US (300);   
          if(SCCB_WR_Byte(Data))res=3;         //写数据         
          SCCB_Stop();          
          return        res;
}                                                              
//读寄存器
//返回值:读到的寄存器值                   ///////////////////////
INT8U  SCCB_RD_Reg(INT8U  reg)
{
        INT8U  val=0;
        INT8U  flag=0;
        SCCB_Start();                                 //启动SCCB传输
   Delay_US (50);         
        if(SCCB_WR_Byte(0X42))return 0x21;                //表示写入数据  
   Delay_US (50);         
    if(SCCB_WR_Byte(reg)) return 0x22;                //地址是否错误
         
   Delay_US (300);
             
        SCCB_Stop();   
        Delay_US (100);   

        //设置寄存器地址后,才是读

        SCCB_Start();

        Delay_US (100);

//        do{
//        flag = SCCB_WR_Byte(0X43);        // 发 送  读 命 令
        /*写入成功返回【0】*/
        /*写入失败返回【1】*/
        /*判断   什么时候返回0;否则一直写下去*/
//        }while(flag!=0);

        if(SCCB_WR_Byte(0X43))return 0x23;        /*发送读取寄存器的指令*/
        Delay_US (300);   
          val=SCCB_RD_Byte();                         //读取数据
  
          SCCB_No_Ack();
  
          SCCB_Stop();
          return val;
}
/*复位SCCB总线*/
/*返回值类型:对应上表*/
/*返回:错误,正确  0,1,*/
INT8U  Init_SCCB (void)
{
  if(SCCB_WR_Reg(0x12,0x80))           /*0X12通用控制位  0X80复位总线         返回0表示写入成功*/
     return SCCB_INIT_ERROR;           //复位SCCB;                  //
  else
     return SCCB_INIT_OK   ;           //复位SCCB         返回0表示初始化成功       
}

INT8U Init_OVCamer (void)
{
   INT8U temp=0;
   if(Init_SCCB ()!=0)                       /*复位SCCB总线*/
   {
     return SCCB_ERROR ;                     /*错误直接返回【3】*/
   }
   /*读取产品型号 */
   temp=SCCB_RD_Reg(0x0B);
   //if(SCCB_RD_Reg(0x0a)!=0x73)
    //return ID_ERROR;                                                 /*错误返回【4】*/
        //return SCCB_RD_Reg(0x0a);
       
        //temp=temp;   
        //if(SCCB_RD_Reg(0x0a)!=0x76)
        //{
        //return OV_RETURN1;            //0x76
         //}
        return temp;//SCCB_OK;                              /*正确返回【0】*/
}

这是代码

问题是:每次到了读取器件ID  都是返回一个写入不成功。这是为什么呢?摄像头是没有问题的,我在STM32上用一点问题也没有!temp=SCCB_RD_Reg(0x0B);
这一句的返回值有21H 22H 23H
21H:表示-设定为写入,错误
22H:表示-写入地址,  错误
23H:表示-设定为读取,错误

有老师做过这种东西么?求教!

相关帖子

沙发
MJM_WSY|  楼主 | 2013-5-26 19:31 | 只看该作者
没有人,碰见过么?……求救啊大哥们

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

367

帖子

2

粉丝