高级会员 
  
	- 积分
 - 839
 
        - 金钱
 - 839 
 
       - 注册时间
 - 2020-11-13
 
      - 在线时间
 - 135 小时
 
 
 
 | 
 
 
 楼主 |
发表于 2021-11-6 15:45:03
|
显示全部楼层
 
 
 
 
#include "gc0308.h" 
#include "IIC3.h" 
#include "string.h" 
#include "main.h" 
uint8_t ov_sta=0;  //帧数 
 
// 初始化序列参数 
const uint8_t ov7670_init_reg_[][2]=  
  {    
        /*以下为OV7670 QVGA RGB565参数  */ 
    {0xfe, 0x80},          //软件复位 
    {0xfe, 0x00},          //页0 
 
    {0x1a, 0x16},          //电源 
    {0x25, 0x0f},          //引脚输出允许0f            //ff 
    {0x14, 0x11},          //翻转镜像10               //01 
    {0x28, 0x11},          //不分频11                 // 
 
    {0x1d, 0x08},          //使用内部DA250 08         // 
    {0x29, 0xa3},          //By pass模式RawRGB a3      // 
    {0x26, 0x02},          //同步信号极性控制 高有效 下降沿 哎 就在这出的问题                 
                 
    //Window模式 Windowing配出窗口0x05~0x0C 先设成640x480 再抽取1/2 
{0x24, 0xa6},                 //输出格式RGB565 a6   //86 c6 e6ok 
{0xd2, 0x94},         //打开AEC 90 
 
{0xfe, 0x01},          //页1 
{0x53,0x82},                         
{0x54, 0x22}, 
{0x55, 0x00}, 
 
{0x56, 0x00}, 
 
{0x57, 0x00}, 
 
{0x58, 0x00}, 
 
{0x59, 0x00}, 
///////////////////////////////////////////////////////////////////////         
};  
 
uint8_t Camera_Init(void) 
{          
        uint16_t i=0,len=0; 
        uint8_t temp=0;  
//        FIFO_OE(0);       //camera 片选 
  if(IIC3_WR_Reg(0xfe,0x80))  //复位SCCB         
          return 1;              
        HAL_Delay(50);   
        //读取产品型号 
         temp=IIC3_RD_Reg(0x00);   //读设备id  正确应答0x9b 
        if(temp!=0x9b) 
                return 2;   
        //初始化序列         
  len=sizeof(ov7670_init_reg_)/sizeof(ov7670_init_reg_[0]);         //二维数组的长度 
        for(i=0;i<len;i++) 
        { 
                   IIC3_WR_Reg(ov7670_init_reg_[0],ov7670_init_reg_[1]);  //初始化0308 写入参数 
 
  } 
        OV_VSYNC_exit_line8_config(); 
         return 0x00;         //ok 
 
}  
 
 
 
 
 
void Camera_refresh(void) 
{ 
        uint16_t j=0, i; 
         uint16_t color=0, color2=0, color1=0;                 
        if(g_sysSetting.mixLevel == 4) 
        { 
                ov_sta=0; 
                return; 
        } 
         
        if(ov_sta>=2)     //有帧中断更新? 
        {    
                FIFO_OE(0);       //camera 片选 
                FIFO_WEN(0); 
         
                FIFO_RRST(0);                                //开始复位读指针  
                FIFO_RCLK(0); 
                FIFO_RCLK(1); 
                FIFO_RCLK(0); 
                FIFO_RRST(1);                                //复位读指针结束  
                FIFO_RCLK(1); 
    //原0 du 1  
                for(i = 0; i < CAMA_YPIX; i ++)        //240 
                { 
                        for(j=0;j<CAMA_XPIX;j++)        //320 
                        {                                   
                                 FIFO_RCLK(0); 
                                 color1=GPIOI->IDR&0XFF;           //读数据        高? 
                                 FIFO_RCLK(1); 
 
                                 FIFO_RCLK(0);           
                                 color2=GPIOI->IDR&0XFF;         //读数据   低? 
                                 FIFO_RCLK(1);   
                                 
                                 color=(color2<<8)|(color1); 
                                 //picSrcBuf[j/240][j%240] = color; 
                        //        cameraBuf[j/240][j%240] = color; 
                                // videoBuf[320-j/240][j%240] = color; 
                                //videoBuf[j/320][j%320] = color; 
                                videoBuf[j] = color; 
                                //picSrcBuf[j] = color; 
                        }   
                }         
                        FIFO_OE(1);       //camera 片选 
                   ov_sta=0;                      //清零帧中断标记 
        }  
}         
 
 
 
void OV_VSYNC_exit_line8_config(void) 
{ 
  GPIO_InitTypeDef GPIO_InitStruct = {0}; 
         
        GPIO_InitTypeDef GPIO_InitStructure; 
  __HAL_RCC_GPIOI_CLK_ENABLE(); 
  GPIO_InitStruct.Pin = OV_VSYNC_Pin; 
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; 
  GPIO_InitStruct.Pull = GPIO_NOPULL; 
  HAL_GPIO_Init(OV_VSYNC_GPIO_Port, &GPIO_InitStruct); 
         
} 
 
//////////////////////////////// 
#include "IIC3.h" 
 
#define IIC_SPEED        1 
//IIC3起始信号 
//当时钟为高的时候,数据线的高到低,为IIC3起始信号 
//在激活状态下,SDA和SCL均为低电平 
void IIC3_Start(void) 
{ 
          SDA_OUT;         //输出模式 
    IIC3_SDA(1);     //数据线高电平            
    IIC3_CLK(1);            //在时钟线高的时候数据线由高至低 
    HAL_Delay(IIC_SPEED);    //50MS  
    IIC3_SDA(0); 
    HAL_Delay(IIC_SPEED);          
          IIC3_CLK(0);            // 钳住iic总线 准备发送或接受数据           数据线恢复低电平,单操作函数必要           
          HAL_Delay(IIC_SPEED);          
} 
 
//IIC3停止信号 
//当时钟为高的时候,数据线的低到高,为IIC3停止信号 
//空闲状况下,SDA,SCL均为高电平 
void IIC3_Stop(void) 
{ 
          SDA_OUT;         //输出模式 
    IIC3_SDA(0); 
    HAL_Delay(IIC_SPEED);         
          IIC3_CLK(1);         
    HAL_Delay(IIC_SPEED);  
    IIC3_SDA(1); 
    HAL_Delay(IIC_SPEED); 
} 
 
//产生NA信号 
void ICC_No_Ack(void) 
{ 
        HAL_Delay(IIC_SPEED); 
        IIC3_SDA(1);  
        IIC3_CLK(1);         
        HAL_Delay(IIC_SPEED); 
        IIC3_CLK(0);         
        HAL_Delay(IIC_SPEED); 
        IIC3_SDA(0); 
        HAL_Delay(IIC_SPEED); 
} 
//IIC3,写入一个字节 
//返回值:0,成功;1,失败. 
//0100 0010 
uint8_t IIC3_WR_Byte(uint8_t dat) 
{ 
        uint8_t j,res;         
        SDA_OUT; 
        for(j=0;j<8;j++) //循环8次发送数据 
        { 
                if(dat&0x80) 
                        IIC3_SDA(1);         
                else  
                        IIC3_SDA(0); 
                dat<<=1; 
                HAL_Delay(IIC_SPEED); 
                IIC3_CLK(1);         
                HAL_Delay(IIC_SPEED); 
                IIC3_CLK(0);          
                HAL_Delay(IIC_SPEED);                          
        }                          
        SDA_IN;                        //设置SDA为输入  
        HAL_Delay(IIC_SPEED); 
 
        IIC3_CLK(1);                        //接收第九位,以判断是否发送成功 
        HAL_Delay(IIC_SPEED); 
 
        if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_8))     //出错 
                res=1;  //SDA=1发送失败,返回1 
        else  
                res=0;         //SDA=0发送成功,返回0 
        IIC3_CLK(0);                  
        SDA_OUT;         //设置SDA为输出     
        HAL_Delay(IIC_SPEED);          
        return res;   
}          
//IIC3 读取一个字节 
//在SCL的上升沿,数据锁存 
//返回值:读到的数据 
uint8_t IIC3_RD_Byte(void) 
{ 
        uint8_t temp=0,j;     
        SDA_IN;                          //设置SDA为输入   
        for(j=8;j>0;j--)           //循环8次接收数据 
        {                                
                HAL_Delay(IIC_SPEED); 
 
                IIC3_CLK(1); 
                temp=temp<<1; 
                if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_8)) 
                        temp++;    
                HAL_Delay(IIC_SPEED); 
 
                IIC3_CLK(0); 
                HAL_Delay(IIC_SPEED);          
        }         
        SDA_OUT;                      //设置SDA为输出     
        return temp; 
}                                                              
//写寄存器 
//返回值:0,成功;1,失败. 
uint8_t IIC3_WR_Reg(uint8_t reg,uint8_t data) 
{ 
        uint8_t res=0; 
        IIC3_Start();                                         //启动IIC3传输 
        if(IIC3_WR_Byte(IIC3_ID)) 
                res=1;        //写器件ID           
        HAL_Delay(IIC_SPEED); 
          if(IIC3_WR_Byte(reg)) 
                        res=1;                //写寄存器地址           
          HAL_Delay(IIC_SPEED); 
          if(IIC3_WR_Byte(data)) 
                        res=1;         //写数据          
          IIC3_Stop();           
          return        res; 
}                                                               
//读寄存器 
//返回值:读到的寄存器值 
uint8_t IIC3_RD_Reg(uint8_t reg) 
{ 
        uint8_t val=0; 
        IIC3_Start();                                     //启动IIC3传输 
        IIC3_WR_Byte(IIC3_ID);                //写器件ID           
        HAL_Delay(IIC_SPEED);          
 
  IIC3_WR_Byte(reg);                        //写寄存器地址           
        HAL_Delay(IIC_SPEED);         
   
        IIC3_Stop();    
        HAL_Delay(IIC_SPEED);         
         
        //设置寄存器地址后,才是读 
        IIC3_Start(); 
        IIC3_WR_Byte(IIC3_ID|0X01);        //发送读命令           
        HAL_Delay(4*IIC_SPEED); 
 
          val=IIC3_RD_Byte();                         //读取数据 
          ICC_No_Ack(); 
          IIC3_Stop(); 
          return val; 
} 
 
// SDA 输出模式  
void IIC3_SDA_OUT_Mode(void) 
{         
                GPIO_InitTypeDef GPIO_InitStruct = {0};                 
                GPIO_InitStruct.Pin = GPIO_PIN_8; 
                GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 
                GPIO_InitStruct.Pull = GPIO_PULLUP; 
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 
//                GPIO_InitStruct.Alternate = GPIO_AF4_I2C3; 
                HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); 
} 
// SDA 输入模式 
void IIC3_SDA_IN_Mode(void) 
{         
                GPIO_InitTypeDef GPIO_InitStruct = {0};                 
                GPIO_InitStruct.Pin = GPIO_PIN_8; 
                GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 
                GPIO_InitStruct.Pull = GPIO_PULLUP; 
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 
//                GPIO_InitStruct.Alternate = GPIO_AF4_I2C3; 
                HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); 
} 
void delay_nop(unsigned int time) 
{ 
//        int p=200; 
        while(time--) 
                 {  
                 
        __nop(); 
                 } 
} 
/////////////////////////////////// 
 
void EXTI9_5_IRQHandler(void) 
{ 
  /* USER CODE BEGIN EXTI9_5_IRQn 0 */ 
 
  /* USER CODE END EXTI9_5_IRQn 0 */ 
  /* USER CODE BEGIN EXTI9_5_IRQn 1 */ 
 
  /* USER CODE END EXTI9_5_IRQn 1 */ 
        { 
 
                __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_8);    //??3y?D???à¨o?? 
                if(ov_sta<2) 
                { 
                         if(ov_sta==0)           //|ì¨2¨°????¨a?2??ê??a¨o????¨o?¨°???¨oy?Y 
                         { 
                                 FIFO_OE(0);       //camera 片选 
                                 FIFO_WRST(0);       //?′??D′???? 
                                 FIFO_WRST(1); 
                                 FIFO_WEN(1);        //高电平有效 
                                  
                         } 
                         else if(ov_sta==1)  
                         { 
                                 FIFO_WEN(0);      //???1D??¨¨?fifo 
                                 FIFO_WRST(0);     //?????D?????? 
//                                 FIFO_WRST(1); 
 
 
                         } 
                         ov_sta++; 
 
                } 
                 
        } 
} 
 
 
 
 
 |   
 
 
 
 |