標(biāo)題: STM32F407 OV7670攝像頭例程 [打印本頁]

作者: 硯子兒    時(shí)間: 2017-8-6 21:16
標(biāo)題: STM32F407 OV7670攝像頭例程
1、該例程為OV7670攝像頭例程。

2、使用說明
   (1)工程文件路徑:SY-STM32F407 V2程序\SY-STM32F407 V2例程:OV7670攝像頭例程\Project\Project.uvproj。
   (2)請(qǐng)使用MDK 4.0以上版本打開,MDK版本過低會(huì)導(dǎo)致無法識(shí)別工程。
   (3)下載調(diào)試工具為JLINK。
   (4)請(qǐng)將串口線(直連串口線)插在板子COM1口上,并打開超級(jí)終端或串口助手,配置波特率115200,8位,一個(gè)停止位,無校驗(yàn)位。
   (5)HEX文件下載到板子后,使用超級(jí)終端或串口調(diào)試助手可以看到調(diào)試信息。
   (6)插上TFT模塊,插上攝像頭模塊,TFT顯示攝像頭采集圖像,表明例程運(yùn)行正確。
   
         
3、注意事項(xiàng)
   請(qǐng)務(wù)必在下載、調(diào)試、運(yùn)行過程中,保持板子上電、JLINK連接并插在電腦上。

全部資料下載地址:
STM32F407 OV7670攝像頭例程.rar (470.73 KB, 下載次數(shù): 480)


stm32部分源碼預(yù)覽:
  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時(shí)鐘
  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        結(jié)束高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)//設(shè)置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)//設(shè)置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();     //數(shù)據(jù)線高電平
  152.     delay_us(50);
  153.     SCCB_SIC_H();           //在時(shí)鐘線高的時(shí)候數(shù)據(jù)線由高至低
  154.     delay_us(50);
  155.     SCCB_SID_L();
  156.     delay_us(50);
  157.     SCCB_SIC_L();         //數(shù)據(jù)線恢復(fù)低電平,單操作函數(shù)必要
  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++) //循環(huán)8次發(fā)送數(shù)據(jù)
  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發(fā)送失敗
  199.         else tem=1;//SDA=0發(fā)送成功,返回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--) //循環(huán)8次接收數(shù)據(jù)
  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();//發(fā)送SCCB 總線開始傳輸命令
  229.         if(SCCB_Write(0x42)==0)//寫地址
  230.         {
  231.                 SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
  232.                 return 1;//錯(cuò)誤返回
  233.         }
  234.         delay_us(10);
  235.           if(SCCB_Write(regID)==0)//積存器ID
  236.         {
  237.                 SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
  238.                 return 2;//錯(cuò)誤返回
  239.         }
  240.         delay_us(10);
  241.           if(SCCB_Write(regDat)==0)//寫數(shù)據(jù)到積存器
  242.         {
  243.                 SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
  244.                 return 3;//錯(cuò)誤返回
  245.         }
  246.           SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令       
  247.           return 0;//成功返回
  248. }

  249. //讀OV7660寄存器
  250. u8 OV_ReadReg(u8 regID, u8 *regDat)
  251. {
  252.         //通過寫操作設(shè)置寄存器地址
  253.         SCCB_Start();
  254.         if(SCCB_Write(0x42)==0)//寫地址
  255.         {
  256.                 SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
  257.                 return 1;//錯(cuò)誤返回
  258.         }
  259.         delay_us(10);
  260.           if(SCCB_Write(regID)==0)//積存器ID
  261.         {
  262.                 SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
  263.                 return 2;//錯(cuò)誤返回
  264.         }
  265.         SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令       
  266.         delay_us(10);       
  267.         //設(shè)置寄存器地址后,才是讀
  268.         SCCB_Start();
  269.         if(SCCB_Write(0x43)==0)//讀地址
  270.         {
  271.                 SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
  272.                 return 3;//錯(cuò)誤返回
  273.         }
  274.         delay_us(10);
  275.           *regDat=SCCB_Read();//返回讀到的值
  276.           noAck();//發(fā)送NACK命令
  277.           SCCB_Stop();//發(fā)送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. }
復(fù)制代碼



作者: yhj416606438    時(shí)間: 2018-2-14 08:33
謝謝分享。。。!
作者: 夢(mèng)園心田    時(shí)間: 2018-10-3 20:33
可以用嗎
作者:     時(shí)間: 2018-10-6 15:54
感謝分享

作者: 馬克老兄    時(shí)間: 2018-10-7 16:29
感謝樓主分享例程
作者: caonimaaaaa    時(shí)間: 2018-11-19 14:55
啊!非常感謝
作者: 李秀蓮    時(shí)間: 2019-3-18 17:06
為什么按照例程燒寫進(jìn)板子后,LCD沒有圖像顯示
作者: zh21107066    時(shí)間: 2019-4-13 09:14
多謝樓主,下來試試
作者: leemor    時(shí)間: 2019-5-6 18:44
謝謝分享 正在學(xué)習(xí)中,很有用
作者: 310139033    時(shí)間: 2019-7-13 21:22
感謝樓主分享,真的需要
作者: 木子一    時(shí)間: 2019-7-29 17:51
謝謝大佬
作者: dan2451093708    時(shí)間: 2020-2-4 17:53
你好,請(qǐng)問此例程是運(yùn)行在什么硬件環(huán)境的呢?比如正點(diǎn)原子探索者開發(fā)板嗎?是使用的正點(diǎn)原子的OV7670攝像頭(帶FIFO)嗎?顯示屏用的幾寸屏呢?
作者: aaaaaa。    時(shí)間: 2020-3-2 09:39
樓主,你這個(gè)程序的功能是什么
作者: xxx224    時(shí)間: 2020-8-13 16:43
有沒有道友調(diào)試成功的,為啥我lcd顯示不出來




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1