找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STM32驱动摄像头ov7670源程序

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

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

下面是部分源码预览:
  1. /*

  2. 未经过本人许可禁止任何商业用途
  3. */

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

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

  38. }

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

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

  45.   


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

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

  59.   

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

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

  73. }


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




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

  175.         return 0x01; //ok

  176.         
  177. }

  178. ///////////////////
复制代码
  1. /*
  2. 未经过本人许可禁止任何商业用途
  3. */

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

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

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

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

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


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

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

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

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

  102. }

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

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

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

  139.         return (tem);  
  140. }

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

评分

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

查看全部评分

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

使用道具 举报

沙发
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接收的吗?
回复

使用道具 举报

33#
ID:1051190 发表于 2025-1-8 16:24 | 只看该作者
这个资料很好,关于摄像头的资料不多。
回复

使用道具 举报

34#
ID:1145041 发表于 2025-3-8 08:44 | 只看该作者
新手前来学习,感谢分享!!
回复

使用道具 举报

35#
ID:1163695 发表于 2025-12-1 19:05 | 只看该作者
这个程序可以用在正点原子的板子上面吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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