找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14910|回复: 32
打印 上一主题 下一主题
收起左侧

STM32驱动摄像头ov7670源程序

  [复制链接]
跳转到指定楼层
楼主

本摄像头ov7670驱动程序已经通过本人的验证可以正常运行,不同的stm32开发板只需要修改引脚即可使用,所有内容打包下载:
stm32驱动摄像头ov7670源程序.rar (4.82 MB, 下载次数: 629)

下面是部分源码预览:
  1. /*
  2. wangguanfu@163.com
  3. 未经过本人许可禁止任何商业用途
  4. */

  5. #include "Sensor.h"
  6. #include "delay.h"
  7. #include "Sensor_config.h"
  8. #include "stm32f10x.h"
  9. extern const char OV7670_reg[OV7670_REG_NUM][2];

  10. ////////////////////////////
  11. //功能:提供时钟
  12. //guanfu_wang
  13. /*
  14. void XCLK_init_ON(void)//没有用到的函数
  15. {
  16.   
  17.     GPIO_InitTypeDef GPIO_InitStructure;
  18.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  19.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  20.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  21.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
  22.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  23.     RCC_MCOConfig(RCC_MCO_HSE  );//hsi
  24. }
  25. */
  26. /////////////////////////////
  27. //VSYNC GPIO INIT
  28. //guanfu_wang
  29. void Sensor_GPIO_Init(void)//
  30. {
  31.   
  32.   GPIO_InitTypeDef GPIO_InitStructure;
  33.    // Enable GPIOC  clock
  34.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  35.   GPIO_InitStructure.GPIO_Pin =  Sensor_VSYNC_BIT;
  36.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;////上拉
  37.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  38.   GPIO_Init(GPIOC, &GPIO_InitStructure);

  39. }

  40. //////////////////////////////////////////////////
  41. ////函数功能:中断配制
  42. //guanfu_wang

  43. void Sensor_Interrupts_Config(void)//VSYNC 中断
  44. {
  45.   NVIC_InitTypeDef NVIC_InitStructure;

  46.   


  47.   /* Configure one bit for preemption priority */
  48.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  49.   

  50.     /* Configure one bit for preemption priority */
  51.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  52.   
  53.   /* Enable the EXTI9_5 Interrupt */
  54.   NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
  55.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  56.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  57.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  58.   NVIC_Init(&NVIC_InitStructure);
  59.   

  60.   

  61. }
  62. ////////////////////////////////////////////////////////////////////////
  63. void Sensor_EXTI_Config(void)//VSYNC 中断
  64. {
  65.   EXTI_InitTypeDef EXTI_InitStructure;
  66.   

  67.   GPIO_EXTILineConfig(GPIO_PORT_SOURCE_VSYNC_CMOS, GPIO_PIN_SOURCE_VSYNC_CMOS);
  68.   EXTI_InitStructure.EXTI_Line = EXTI_LINE_VSYNC_CMOS;
  69.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  70.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  71.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  72.   EXTI_Init(&EXTI_InitStructure);
  73.   EXTI_GenerateSWInterrupt(EXTI_LINE_VSYNC_CMOS);

  74. }


  75. ///////////////////////////////////////////////////////////////////////////
  76. //功能:写OV7660寄存器
  77. //返回:1-成功        0-失败
  78. //guanfu_wang
  79. unsigned char wr_Sensor_Reg(unsigned char regID, unsigned char regDat)
  80. {
  81.                 startSCCB();//发送SCCB 总线开始传输命令
  82.         if(0==SCCBwriteByte(0x42))//写地址
  83.         {
  84.                 stopSCCB();//发送SCCB 总线停止传输命令
  85.                 return(0);//错误返回
  86.         }
  87.         delay_us(20);
  88.           if(0==SCCBwriteByte(regID))//积存器ID
  89.         {
  90.                 stopSCCB();//发送SCCB 总线停止传输命令
  91.                 return(0);//错误返回
  92.         }
  93.         delay_us(20);
  94.           if(0==SCCBwriteByte(regDat))//写数据到积存器
  95.         {
  96.                 stopSCCB();//发送SCCB 总线停止传输命令
  97.                 return(0);//错误返回
  98.         }
  99.           stopSCCB();//发送SCCB 总线停止传输命令
  100.         
  101.           return(1);//成功返回
  102. }
  103. ////////////////////////////
  104. //功能:读OV7660寄存器
  105. //返回:1-成功        0-失败
  106. //guanfu_wang
  107. unsigned char rd_Sensor_Reg(unsigned char regID, unsigned char *regDat)
  108. {
  109.         //通过写操作设置寄存器地址
  110.         startSCCB();
  111.         if(0==SCCBwriteByte(0x42))//写地址
  112.         {
  113.                 stopSCCB();//发送SCCB 总线停止传输命令
  114.                 return(0);//错误返回
  115.         }
  116.         delay_us(20);
  117.           if(0==SCCBwriteByte(regID))//积存器ID
  118.         {
  119.                 stopSCCB();//发送SCCB 总线停止传输命令
  120.                 return(0);//错误返回
  121.         }
  122.         stopSCCB();//发送SCCB 总线停止传输命令
  123.         
  124.         delay_us(20);
  125.         
  126.         //设置寄存器地址后,才是读
  127.         startSCCB();
  128.         if(0==SCCBwriteByte(0x43))//读地址
  129.         {
  130.                 stopSCCB();//发送SCCB 总线停止传输命令
  131.                 return(0);//错误返回
  132.         }
  133.         delay_us(20);
  134.           *regDat=SCCBreadByte();//返回读到的值
  135.           noAck();//发送NACK命令
  136.           stopSCCB();//发送SCCB 总线停止传输命令
  137.           return(1);//成功返回
  138. }




  139. /* Sensor_init() */
  140. //返回1成功,返回0失败
  141. //guanfu_wang
  142. unsigned char Sensor_init(void)
  143. {
  144.         unsigned char temp;
  145.         
  146.         unsigned int i=0;
  147.    //      XCLK_init_ON();//开启MCO功能 提供时钟给CMOS传感器
  148.         //uchar ovidmsb=0,ovidlsb=0;
  149.         Sensor_GPIO_Init();
  150.         SCCB_GPIO_Config();//io init..
  151.         
  152.         temp=0x80;
  153.         if(0==wr_Sensor_Reg(0x12, temp)) //Reset SCCB
  154.         {
  155.           return 0 ;//错误返回
  156.         }
  157.         Delay(1);
  158.         if(0==rd_Sensor_Reg(0x0b, &temp))//读ID
  159.         {
  160.                 return 0 ;//错误返回
  161.         }
  162.       
  163.          if(temp==0x73)//OV7670
  164.          {
  165.            for(i=0;i<OV7670_REG_NUM;i++)
  166.            {
  167.                 if( 0==wr_Sensor_Reg(OV7670_reg[i][0],OV7670_reg[i][1]))
  168.                 {
  169.                         return 0;//错误返回
  170.                 }
  171.             }
  172.            
  173.           Sensor_EXTI_Config();
  174.           Sensor_Interrupts_Config();
  175.         }

  176.         return 0x01; //ok

  177.         
  178. }

  179. ///////////////////
复制代码
  1. /*
  2. wangguanfu@163.com
  3. 未经过本人许可禁止任何商业用途
  4. */

  5. #include "sccb.h"
  6. #include "delay.h"
  7. #include "stm32f10x.h"
  8. /*
  9. -----------------------------------------------
  10.    功能: 初始化模拟SCCB接口
  11.    参数: 无
  12. 返回值: 无
  13. -----------------------------------------------
  14. */
  15. void SCCB_GPIO_Config(void)
  16. {
  17.   GPIO_InitTypeDef GPIO_InitStructure;
  18.    /* Enable GPIOC  clock */
  19.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  20.   GPIO_InitStructure.GPIO_Pin =  SCCB_SIC_BIT|SCCB_SID_BIT;
  21.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  22.   GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
  23.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  24.   
  25. }
  26. void SCCB_SID_GPIO_OUTPUT(void)
  27. {
  28.   GPIO_InitTypeDef GPIO_InitStructure;
  29.    /* Enable GPIOC  clock */
  30.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  31.   GPIO_InitStructure.GPIO_Pin =  SCCB_SID_BIT;
  32.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  33.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  34.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  35. }
  36. void SCCB_SID_GPIO_INPUT(void)
  37. {
  38.   GPIO_InitTypeDef GPIO_InitStructure;
  39.    /* Enable GPIOC  clock */
  40.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  41.   GPIO_InitStructure.GPIO_Pin =  SCCB_SID_BIT;
  42.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉 若无外部上拉电阻 必须内部有上拉
  43.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  44.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  45. }

  46. /*
  47. -----------------------------------------------
  48.    功能: start命令,SCCB的起始信号
  49.    参数: 无
  50. 返回值: 无
  51. -----------------------------------------------
  52. */
  53. void startSCCB(void)
  54. {
  55.     SCCB_SID_H();     //数据线高电平
  56.     delay_us(50);

  57.     SCCB_SIC_H();           //在时钟线高的时候数据线由高至低
  58.     delay_us(50);

  59.     SCCB_SID_L();
  60.     delay_us(50);

  61.     SCCB_SIC_L();         //数据线恢复低电平,单操作函数必要
  62.     delay_us(50);


  63. }
  64. /*
  65. -----------------------------------------------
  66.    功能: stop命令,SCCB的停止信号
  67.    参数: 无
  68. 返回值: 无
  69. -----------------------------------------------
  70. */
  71. void stopSCCB(void)
  72. {
  73.     SCCB_SID_L();
  74.     delay_us(50);

  75.     SCCB_SIC_H();        
  76.     delay_us(50);
  77.   

  78.     SCCB_SID_H();        
  79.     delay_us(50);
  80.    
  81. }

  82. /*
  83. -----------------------------------------------
  84.    功能: noAck,用于连续读取中的最后一个结束周期
  85.    参数: 无
  86. 返回值: 无
  87. -----------------------------------------------
  88. */
  89. void noAck(void)
  90. {
  91.         
  92.         SCCB_SID_H();        
  93.         delay_us(50);
  94.         
  95.         SCCB_SIC_H();        
  96.         delay_us(50);
  97.         
  98.         SCCB_SIC_L();        
  99.         delay_us(50);
  100.         
  101.         SCCB_SID_L();        
  102.         delay_us(50);

  103. }

  104. /*
  105. -----------------------------------------------
  106.    功能: 写入一个字节的数据到SCCB
  107.    参数: 写入数据
  108. 返回值: 发送成功返回1,发送失败返回0
  109. -----------------------------------------------
  110. */
  111. unsigned char SCCBwriteByte(unsigned char m_data)
  112. {
  113.         unsigned char j,tem;

  114.         for(j=0;j<8;j++) //循环8次发送数据
  115.         {
  116.                 if((m_data<<j)&0x80)
  117.                 {
  118.                         SCCB_SID_H();        
  119.                 }
  120.                 else
  121.                 {
  122.                         SCCB_SID_L();        
  123.                 }
  124.                 delay_us(50);
  125.                 SCCB_SIC_H();        
  126.                 delay_us(50);
  127.                 SCCB_SIC_L();        
  128.                 delay_us(2);

  129.         }
  130.         //delay_us(50);
  131.         SCCB_SID_IN;/*设置SDA为输入*/
  132.         delay_us(10);
  133.         SCCB_SIC_H();        
  134.         delay_us(80);
  135.         if(SCCB_SID_STATE){tem=0;}   //SDA=1发送失败,返回0}
  136.         else {tem=1;}   //SDA=0发送成功,返回1
  137.         SCCB_SIC_L();        
  138.         delay_us(50);        
  139.         SCCB_SID_OUT;/*设置SDA为输出*/

  140.         return (tem);  
  141. }

  142. /*
  143. -----------------------------------------------
  144.    功能: 一个字节数据读取并且返回
  145.    参数: 无
  146. 返回值: 读取到的数据
  147. -----------------------------------------------
  148. */
  149. unsigned char SCCBreadByte(void)
  150. {
  151.         unsigned char read,j;
  152.         read=0x00;
  153.         
  154.         SCCB_SID_IN;/*设置SDA为输入*/
  155.         delay_us(50);
  156.         for(j=8;j>0;j--) //循环8次接收数据
  157.         {                     
  158.                 //delay_us(100);
  159.                 SCCB_SIC_H();
  160.                 delay_us(50);
  161.                 read=read<<1;
  162.                 if(SCCB_SID_STATE)
  163.                 {
  164.                         read=read+1;
  165.                 }
  166.                 SCCB_SIC_L();
  167.                 delay_us(50);
  168.         }        
  169.         SCCB_SID_OUT;/*设置SDA为输出*/
  170.         return(read);
  171. }
复制代码

评分

参与人数 2黑币 +10 收起 理由
sq524594846 + 5
Ayanami——Rei + 5 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏19 分享淘帖 顶7 踩
回复

使用道具 举报

沙发
ID:169681 发表于 2017-3-10 16:50 | 只看该作者
这个资料来的太及时了!!
回复

使用道具 举报

板凳
ID:184406 发表于 2017-3-29 15:59 | 只看该作者
这个资料很好,关于摄像头的资料不多
回复

使用道具 举报

地板
ID:201854 发表于 2017-5-17 16:54 | 只看该作者
不错,谢谢分享了!!!!!
回复

使用道具 举报

5#
ID:219592 发表于 2017-7-14 10:22 | 只看该作者
我想看看 但是积分不够   
回复

使用道具 举报

6#
ID:224495 发表于 2017-8-3 19:24 | 只看该作者
同积分不够
回复

使用道具 举报

7#
ID:224871 发表于 2017-8-5 03:52 | 只看该作者
SBBC.C中 SCCB_SID_L()的GPIOB->BRR这个是什么寄存器,在32手册上无法找到,只在串口中才有BRR这个寄存器
回复

使用道具 举报

8#
ID:194871 发表于 2017-8-5 12:08 | 只看该作者
谢谢楼主
回复

使用道具 举报

9#
ID:225118 发表于 2017-8-6 09:40 | 只看该作者
好像学习啊
回复

使用道具 举报

10#
ID:225449 发表于 2017-8-7 13:54 | 只看该作者
感谢,不过积分不够啊
回复

使用道具 举报

11#
ID:205446 发表于 2017-9-26 09:09 | 只看该作者
国内就少开源的精神
回复

使用道具 举报

12#
ID:229527 发表于 2017-9-28 14:01 | 只看该作者
厉害了,值得学习!
回复

使用道具 举报

13#
ID:235925 发表于 2017-9-28 21:08 | 只看该作者
这个资料很好,关于摄像头的资料不多
回复

使用道具 举报

14#
ID:241034 发表于 2017-10-19 19:18 | 只看该作者
非常好
回复

使用道具 举报

15#
ID:241273 发表于 2017-10-20 15:14 | 只看该作者
这是不是正点原子的资料a
回复

使用道具 举报

16#
ID:254958 发表于 2017-11-29 13:01 来自手机 | 只看该作者
好啊,非常有用
回复

使用道具 举报

17#
ID:233062 发表于 2018-1-23 10:34 | 只看该作者
楼主你好,你用的摄像头是自带FIFO的OV7670吗?
回复

使用道具 举报

18#
ID:111339 发表于 2018-2-18 19:20 | 只看该作者
引脚是如何连接的呢?
回复

使用道具 举报

19#
ID:68875 发表于 2018-2-19 00:18 | 只看该作者
good job!!!
回复

使用道具 举报

20#
ID:284925 发表于 2018-2-23 11:38 | 只看该作者
想看,积分不够
回复

使用道具 举报

21#
ID:285281 发表于 2018-2-24 20:55 | 只看该作者
赚赚积分! 想看!
回复

使用道具 举报

22#
ID:310833 发表于 2018-4-28 21:20 | 只看该作者
可不可以给个引脚连接?1371177469@qq.com
回复

使用道具 举报

23#
ID:371712 发表于 2018-11-17 09:40 | 只看该作者
楼主这个摄像头引脚是几个,有直接以VCC GND RX TX 连出的串口摄像头的吗?直接以串口形式输出
回复

使用道具 举报

24#
ID:435355 发表于 2018-12-21 19:37 | 只看该作者
楼主用的摄像头带有fifo吗
回复

使用道具 举报

25#
ID:457096 发表于 2018-12-28 10:46 | 只看该作者
刚好要用这东西
回复

使用道具 举报

26#
ID:267330 发表于 2019-1-23 08:42 | 只看该作者
这个资料很好,关于摄像头的资料不多
回复

使用道具 举报

27#
ID:271847 发表于 2019-5-12 23:42 | 只看该作者
谢谢,学习了
回复

使用道具 举报

28#
ID:474606 发表于 2019-5-13 11:11 | 只看该作者
感谢楼主的热心分享
回复

使用道具 举报

29#
ID:317628 发表于 2019-5-16 16:21 | 只看该作者
资料已下载。等配件回来试试
回复

使用道具 举报

30#
ID:515069 发表于 2019-7-18 16:52 | 只看该作者
绝世好帖
回复

使用道具 举报

31#
ID:56665 发表于 2019-7-19 16:22 | 只看该作者
有原理图就好了。
回复

使用道具 举报

32#
ID:584195 发表于 2023-11-12 14:42 | 只看该作者
太感谢了,这个是基于普通IO接收的吗?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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