你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F1的OV7725摄像头经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-15 21:05
最近做项目需要用到OV7725,于是花了些时间研究。由于OV7725对于工作频率的要求较高,因此使用带FIFO的摄像头模块。代码参考自正点原子官方。


OV7725资源
引脚说明
以下时关于十八个引脚的说明(来自正点原子的用户手册)

20200323141056716.png

其中,OV_SCL和OV_SDA组成SCCB,即串行摄像头控制总线,它的通信机制类似于IIC,有使用过IIC总线的较容易理解。OV_VSYNC为帧同步信号,该引脚产生信号时,意味着一帧数据传输完成后,下一帧数据传输即将开始(这里,从OV7725传输至FIFO)。FIFO_D[7:0] 是FIFO的数据引脚,用于数据传输。当发生帧同步信号时,复位FIFO_WRST写指针信号,使能FIFO_WEN写使能信号,则OV7725开始往FIFO写数据,并置位帧中断标志位(该标志位在读数据完成后被清零),保证FIFO的数据被读取完成之前不会被覆盖,具体见下面的中断服务程序。帧中断标志位有效时,就复位RIFO_RRST读指针信号,然后在每个FIFO_RCLK读时钟信号,使用STM32去读取FIFO_D[7:0] 的数据。FIFO_OE片选信号在初始化之后就拉低,使之有效。

寄存器
这是来自datasheet的寄存器描述,看手册,英文很重要:

20200323135602683.png

这些寄存器在代码里表现为一堆宏定义
  1.   /*OV7725寄存器宏定义*/
  2. #define GAIN      0x00
  3. #define BLUE      0x01
  4. #define RED       0x02
  5. #define GREEN     0x03
  6. #define BAVG      0x05
  7. #define GAVG      0x06
  8. …………
复制代码

模块初始化
引脚定义

  1. //D0~D7:PA0~PA7       VSYNC:PA8
  2. //WRST:PB13  RRST:PB14  OE:PB5  RCLK:PB6  WEN:PB7  SDA:PB8  SCL:PB9   
  3. #define OV7725_VSYNC    PAin(8)                        
  4. #define OV7725_WRST                PBout(13)               
  5. #define OV7725_WREN                PBout(7)               
  6. #define OV7725_RCK_H        GPIOB->BSRR=1<<6
  7. #define OV7725_RCK_L        GPIOB->BRR=1<<6
  8. #define OV7725_RRST                PBout(14)         
  9. #define OV7725_CS                PBout(5)  
复制代码
  1. #define SCCB_SCL                    PBout(9)                 //SCL
  2. #define SCCB_SDA                    PBout(8)                 //SDA         

  3. #define SCCB_READ_SDA            PBin(8)                  //ÊäÈëSDA   
复制代码


我使用的是杜邦线连接如,IO口是自己重新定义的(全使用普通IO即可),STM32F1系列的PB3,PB4,PA13,PA14,PA15用于JTAG,如果有使用到其中的引脚,需要进行特殊配置,具体可参考网上更多教程。当时使用PB3,PB4作为SCCB的引脚,出现问题才发现这个原因。

初始化
写寄存器的函数,寄存器的配置都是通过这个函数
  1. u8 SCCB_WR_Reg(u8 reg,u8 data)
  2. {
  3.         u8 res=0;
  4.         SCCB_Start();                          //启动SCCB传输                 
  5.         if(SCCB_WR_Byte(SCCB_ID))res=1;        //写器件ID,为0x42
  6.         delay_us(100);
  7.           if(SCCB_WR_Byte(reg))res=1;                //写寄存器地址,直接写对应的寄存器地址
  8.         delay_us(100);
  9.           if(SCCB_WR_Byte(data))res=1;         //写数据,根据寄存器功能写对应数据
  10.           SCCB_Stop();         
  11.           return        res;
  12. }                          
复制代码

将要配置的寄存器地址和对应的值,存在一个二维数组里边
  1. //初始化寄存器系列及其对应的值
  2. const u8 ov7725_init_reg_tb1[][2]=
  3. {   
  4.         /*输出窗口设置*/
  5.         {CLKRC,     0x00}, //clock config
  6.         {COM7,      0x06}, //VGA RGB565
  7.         {HSTART,    0x3f}, //水平起始位置
  8.         {HSIZE,     0x50}, //水平尺寸
  9.         {VSTRT,     0x03}, //垂直其实位置
  10.         ......
复制代码

初始化时,在循环语句调用写寄存器的函数,依次写入寄存器的地址和对应的值,即可完成寄存器的配置
  1.   //初始化OV7725,采用QVGA分辨率(320*240)  
  2.         for(i=0;i<sizeof(ov7725_init_reg_tb1)/sizeof(ov7725_init_reg_tb1[0]);i++)
  3.         {                                                               
  4.                    SCCB_WR_Reg(ov7725_init_reg_tb1[i][0],ov7725_init_reg_tb1[i][1]);
  5.          }
复制代码

帧中断和数据处理
发生帧中断时
  1. u8 ov_sta;        //帧中断标记
  2. //中断处理函数
  3. void EXTI9_5_IRQHandler(void)
  4. {                                
  5.         if(EXTI_GetITStatus(EXTI_Line8)==SET)//是8线的中断
  6.         {      
  7.                 if(ov_sta==0)
  8.                 {
  9.                         OV7725_WRST=0;        //复位写指针                 
  10.                         OV7725_WRST=1;       
  11.                         OV7725_WREN=1;        //允许写入FIFO          
  12.                         ov_sta++;                //帧中断加1
  13.                 }else OV7725_WREN=0;//禁止写入FIFO
  14.         }
  15.         EXTI_ClearITPendingBit(EXTI_Line8);  //清除中断标志位                                          
  16. }
复制代码

数据处理
  1. if(ov_sta)//判断是否有帧中断发生
  2. {
  3.         OV7725_RRST=0;                  //复
  4.         OV7725_RCK_L;         //位
  5.         OV7725_RCK_H;         //读
  6.         OV7725_RCK_L;         //指
  7.         OV7725_RRST=1;                  //针
  8.         OV7725_RCK_H;
  9.         for(i=0;i<OV7725_WINDOW_HEIGHT;i++)//循环语句读取FIFO的数据
  10.         {
  11.                 for(j=0;j<OV7725_WINDOW_WIDTH;j++)
  12.                 {
  13.                         //将数据填入相应缓冲区
  14.                         ......
  15.                 }
  16.         }
  17.         ov_sta=0;  //清零帧中断标志
  18. }
复制代码

以上是对于OV7725的初步理解,还有很多不懂的地方,后续有进一步研究再补充
————————————————
版权声明:hu_hong_hao
如有侵权请联系删除



收藏 评论0 发布时间:2023-5-15 21:05

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版