单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STM32F407 OV7670摄像头例程

  [复制链接]
跳转到指定楼层
楼主
砚子儿 发表于 2017-8-6 21:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、该例程为OV7670摄像头例程。

2、使用说明
   (1)工程文件路径:SY-STM32F407 V2程序\SY-STM32F407 V2例程:OV7670摄像头例程\Project\Project.uvproj。
   (2)请使用MDK 4.0以上版本打开,MDK版本过低会导致无法识别工程。
   (3)下载调试工具为JLINK。
   (4)请将串口线(直连串口线)插在板子COM1口上,并打开超级终端或串口助手,配置波特率115200,8位,一个停止位,无校验位。
   (5)HEX文件下载到板子后,使用超级终端或串口调试助手可以看到调试信息。
   (6)插上TFT模块,插上摄像头模块,TFT显示摄像头采集图像,表明例程运行正确。
   
         
3、注意事项
   请务必在下载、调试、运行过程中,保持板子上电、JLINK连接并插在电脑上。

全部资料下载地址:
STM32F407 OV7670摄像头例程.rar (470.73 KB, 下载次数: 302)


stm32部分源码预览:
  1. #include "ov7670.h"
  2. #include "delay.h"
  3. #include "lcd.h"


  4. void Cam_Init(void)
  5. {
  6.           GPIO_InitTypeDef GPIO_InitStructure;
  7.           DCMI_InitTypeDef DCMI_InitStructure;
  8.           DMA_InitTypeDef  DMA_InitStructure;

  9.           RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);//DCMI
  10.           RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);//DMA2
  11.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
  12.                            RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE);//使能DCMI的GPIO时钟
  13.         GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_MCO);//MCO1:PA8
  14.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  15.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  16.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  17.           GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  18.           GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
  19.           GPIO_Init(GPIOA, &GPIO_InitStructure);             
  20.     RCC_MCO2Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_3);

  21.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PE5:PWRDOWN
  22.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  23.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  24.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  25.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  26.     GPIO_Init(GPIOE, &GPIO_InitStructure);
  27.         GPIO_ResetBits(GPIOE, GPIO_Pin_5);//power on

  28.     GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);//DCMI_HSYNC
  29.     GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_PIXCLK
  30.     GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_D5                           
  31.     GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);//DCMI_VSYNC
  32.     GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_DCMI);//DCMI_D6
  33.     GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_D7                           
  34.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_D0
  35.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI);//DCMI_D1                           
  36.     GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_DCMI);//DCMI_D2
  37.     GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_DCMI);//DCMI_D3
  38.     GPIO_PinAFConfig(GPIOE, GPIO_PinSource4, GPIO_AF_DCMI);//DCMI_D4

  39.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  40.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  41.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  42.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  43.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  44.     GPIO_Init(GPIOC, &GPIO_InitStructure);
  45.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
  46.     GPIO_Init(GPIOE, &GPIO_InitStructure);     
  47.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
  48.     GPIO_Init(GPIOB, &GPIO_InitStructure);   
  49.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
  50.     GPIO_Init(GPIOA, &GPIO_InitStructure);                 

  51.           DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
  52.           DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
  53.           DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Falling;
  54.           DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;
  55.           DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_High;
  56.           DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
  57.           DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
  58.           DCMI_Init(&DCMI_InitStructure);
  59.           DMA_DeInit(DMA2_Stream1);
  60.           DMA_InitStructure.DMA_Channel = DMA_Channel_1;  
  61.           DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;       
  62.           DMA_InitStructure.DMA_Memory0BaseAddr = FSMC_LCD_ADDRESS;
  63.           DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  64.           DMA_InitStructure.DMA_BufferSize = 1;
  65.           DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  66.           DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  67.           DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  68.           DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  69.           DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  70.           DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  71.           DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
  72.           DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  73.           DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  74.           DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
  75.           DMA_Init(DMA2_Stream1, &DMA_InitStructure);
  76. }

  77. u8 OV7670_Init(void)
  78. {
  79.           u8 i;
  80.           Cam_Init();
  81.         SCCB_Init();
  82.         OV_Reset();
  83.         delay_ms(5);
  84.         LCD_String(20,50,"Camera ID:",RED);
  85.         LCD_Num(180,50,OV_ReadID(),3,WHITE);//ov7670 ID为0x73
  86.           for(i=0;i<OV7670_REG_NUM;i++)
  87.           {
  88.             if(OV_WriteReg(OV7670_reg[i][0],OV7670_reg[i][1]))return 1;
  89.           }
  90.         return 0;
  91. }

  92. void Cam_Start(void)
  93. {
  94.           LCD_WriteReg(0x03,0x1018);
  95.           LCD_Cursor(0,319);  
  96.           DMA_Cmd(DMA2_Stream1, ENABLE);
  97.           DCMI_Cmd(ENABLE);
  98.           DCMI_CaptureCmd(ENABLE);
  99.           LCD_REG=0x22;
  100. }
  101.                                                                   
  102. void OV7670_HW(u16 hstart,u16 vstart,u16 hstop,u16 vstop)
  103. {
  104.         u8 v;               
  105.         OV_WriteReg(0x17,(hstart>>3)&0xff);//HSTART
  106.         OV_WriteReg(0x18,(hstop>>3)&0xff);//HSTOP
  107.         OV_ReadReg(0x32,&v);
  108.         v=(v&0xc0)|((hstop&0x7)<<3)|(hstart&0x7);
  109.         OV_WriteReg(0x32,v);//HREF
  110.        
  111.         OV_WriteReg(0x19,(vstart>>2)&0xff);//VSTART 开始高8位
  112.         OV_WriteReg(0x1a,(vstop>>2)&0xff);//VSTOP        结束高8位
  113.         OV_ReadReg(0x03,&v);
  114.         v=(v&0xf0)|((vstop&0x3)<<2)|(vstart&0x3);       
  115.         OV_WriteReg(0x03,v);//VREF                                                                                                                                 
  116.         OV_WriteReg(0x11,0x00);
  117. }                                                               
  118. /////////////////////////////////////
  119. void SCCB_Init(void)
  120. {
  121.           GPIO_InitTypeDef  GPIO_InitStructure;
  122.           RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  123.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;  //SCCB_SIC:PB10
  124.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                          //SCCB_SID:PB11
  125.           GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  126.           GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  127.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  128.           GPIO_Init(GPIOB, &GPIO_InitStructure);
  129. }

  130. void SCCB_SID_OUT(void)//设置SCCB_SID为输出
  131. {
  132.           GPIO_InitTypeDef  GPIO_InitStructure;

  133.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;               
  134.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                       
  135.           GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  136.           GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  137.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  138.           GPIO_Init(GPIOB, &GPIO_InitStructure);
  139. }
  140. void SCCB_SID_IN(void)//设置SCCB_SID为输入
  141. {
  142.           GPIO_InitTypeDef  GPIO_InitStructure;

  143.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;               
  144.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;                       
  145.           GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  146.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  147.           GPIO_Init(GPIOB, &GPIO_InitStructure);
  148. }

  149. void SCCB_Start(void)
  150. {
  151.     SCCB_SID_H();     //数据线高电平
  152.     delay_us(50);
  153.     SCCB_SIC_H();           //在时钟线高的时候数据线由高至低
  154.     delay_us(50);
  155.     SCCB_SID_L();
  156.     delay_us(50);
  157.     SCCB_SIC_L();         //数据线恢复低电平,单操作函数必要
  158.     delay_us(50);
  159. }

  160. void SCCB_Stop(void)
  161. {
  162.     SCCB_SID_L();
  163.     delay_us(50);
  164.     SCCB_SIC_H();       
  165.     delay_us(50);  
  166.     SCCB_SID_H();       
  167.     delay_us(50);  
  168. }

  169. void noAck(void)
  170. {       
  171.         SCCB_SID_H();       
  172.         delay_us(50);       
  173.         SCCB_SIC_H();       
  174.         delay_us(50);       
  175.         SCCB_SIC_L();       
  176.         delay_us(50);       
  177.         SCCB_SID_L();       
  178.         delay_us(50);
  179. }

  180. u8 SCCB_Write(u8 m_data)
  181. {
  182.         u8 j,tem;

  183.         for(j=0;j<8;j++) //循环8次发送数据
  184.         {
  185.                 if((m_data<<j)&0x80)SCCB_SID_H();
  186.                 else SCCB_SID_L();
  187.                 delay_us(50);
  188.                 SCCB_SIC_H();       
  189.                 delay_us(50);
  190.                 SCCB_SIC_L();       
  191.                 delay_us(50);
  192.         }
  193.         delay_us(10);
  194.         SCCB_DATA_IN;
  195.         delay_us(50);
  196.         SCCB_SIC_H();       
  197.         delay_us(10);
  198.         if(SCCB_SID_STATE)tem=0;//SDA=1发送失败
  199.         else tem=1;//SDA=0发送成功,返回1
  200.         SCCB_SIC_L();       
  201.         delay_us(50);       
  202.     SCCB_DATA_OUT;
  203.         return tem;  
  204. }

  205. u8 SCCB_Read(void)
  206. {
  207.         u8 read,j;
  208.         read=0x00;
  209.        
  210.         SCCB_DATA_IN;
  211.         delay_us(50);
  212.         for(j=8;j>0;j--) //循环8次接收数据
  213.         {                     
  214.                 delay_us(50);
  215.                 SCCB_SIC_H();
  216.                 delay_us(50);
  217.                 read=read<<1;
  218.                 if(SCCB_SID_STATE)read=read+1;
  219.                 SCCB_SIC_L();
  220.                 delay_us(50);
  221.         }       
  222.     SCCB_DATA_OUT;
  223.         return read;
  224. }

  225. //写OV7670寄存器
  226. u8 OV_WriteReg(u8 regID, u8 regDat)
  227. {
  228.         SCCB_Start();//发送SCCB 总线开始传输命令
  229.         if(SCCB_Write(0x42)==0)//写地址
  230.         {
  231.                 SCCB_Stop();//发送SCCB 总线停止传输命令
  232.                 return 1;//错误返回
  233.         }
  234.         delay_us(10);
  235.           if(SCCB_Write(regID)==0)//积存器ID
  236.         {
  237.                 SCCB_Stop();//发送SCCB 总线停止传输命令
  238.                 return 2;//错误返回
  239.         }
  240.         delay_us(10);
  241.           if(SCCB_Write(regDat)==0)//写数据到积存器
  242.         {
  243.                 SCCB_Stop();//发送SCCB 总线停止传输命令
  244.                 return 3;//错误返回
  245.         }
  246.           SCCB_Stop();//发送SCCB 总线停止传输命令       
  247.           return 0;//成功返回
  248. }

  249. //读OV7660寄存器
  250. u8 OV_ReadReg(u8 regID, u8 *regDat)
  251. {
  252.         //通过写操作设置寄存器地址
  253.         SCCB_Start();
  254.         if(SCCB_Write(0x42)==0)//写地址
  255.         {
  256.                 SCCB_Stop();//发送SCCB 总线停止传输命令
  257.                 return 1;//错误返回
  258.         }
  259.         delay_us(10);
  260.           if(SCCB_Write(regID)==0)//积存器ID
  261.         {
  262.                 SCCB_Stop();//发送SCCB 总线停止传输命令
  263.                 return 2;//错误返回
  264.         }
  265.         SCCB_Stop();//发送SCCB 总线停止传输命令       
  266.         delay_us(10);       
  267.         //设置寄存器地址后,才是读
  268.         SCCB_Start();
  269.         if(SCCB_Write(0x43)==0)//读地址
  270.         {
  271.                 SCCB_Stop();//发送SCCB 总线停止传输命令
  272.                 return 3;//错误返回
  273.         }
  274.         delay_us(10);
  275.           *regDat=SCCB_Read();//返回读到的值
  276.           noAck();//发送NACK命令
  277.           SCCB_Stop();//发送SCCB 总线停止传输命令
  278.           return 0;//成功返回
  279. }

  280. void OV_Reset(void)
  281. {
  282.         OV_WriteReg(0x12,0x80);
  283. }

  284. u8 OV_ReadID(void)
  285. {
  286.         u8 temp;
  287.         OV_ReadReg(0x0b,&temp);
  288.           return temp;
  289. }
复制代码


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

使用道具 举报

沙发
yhj416606438 发表于 2018-2-14 08:33 | 只看该作者
谢谢分享!!!!!
回复

使用道具 举报

板凳
梦园心田 发表于 2018-10-3 20:33 | 只看该作者
可以用吗
回复

使用道具 举报

地板
 发表于 2018-10-6 15:54 | 只看该作者
感谢分享
回复

使用道具 举报

5#
马克老兄 发表于 2018-10-7 16:29 | 只看该作者
感谢楼主分享例程
回复

使用道具 举报

6#
caonimaaaaa 发表于 2018-11-19 14:55 | 只看该作者
啊!非常感谢
回复

使用道具 举报

7#
李秀莲 发表于 2019-3-18 17:06 | 只看该作者
为什么按照例程烧写进板子后,LCD没有图像显示
回复

使用道具 举报

8#
zh21107066 发表于 2019-4-13 09:14 | 只看该作者
多谢楼主,下来试试
回复

使用道具 举报

9#
leemor 发表于 2019-5-6 18:44 | 只看该作者
谢谢分享 正在学习中,很有用
回复

使用道具 举报

10#
310139033 发表于 2019-7-13 21:22 | 只看该作者
感谢楼主分享,真的需要
回复

使用道具 举报

11#
木子一 发表于 2019-7-29 17:51 | 只看该作者
谢谢大佬
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机 联系QQ:125739409;技术交流QQ群582644647

Powered by 单片机教程网

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