找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6061|回復(fù): 5
打印 上一主題 下一主題
收起左側(cè)

程序更新!STM32+OV7670+IL9325找球(黑底紅球)帶2路PWM(PID)程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:225718 發(fā)表于 2017-8-12 14:54 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 zhangpro666 于 2017-8-13 11:13 編輯

呃...看到大家都在電賽,自己暑假無聊玩一下,如果大家覺得有用就拿去吧。用的是啟光電子的STM32,OV7670,ILI9325,理論上核心板通過跳線都可以實現(xiàn)。



原理圖:


stm32主程序:
  1. /*
  2. OV7670模塊 STM32函數(shù)

  3. 選用STM32F103RBT6芯片   
  4. TFT驅(qū)動IC為  R61505V

  5.   程序中 用到的TFT 為 我們店的 2.4寸TFT  驅(qū)動芯片為 R61505V        
  6.   TFT用到的GPIO  PB為數(shù)據(jù)口        PC.6  CS   PC.7  RS          PC.8  WR   PC.9  RD        PC.10 RES
  7.   此函數(shù) 用寄存器方式配置GPIO  在TFT的數(shù)據(jù) 命令腳配置上用的是寄存器  這樣能大幅度提高輸出速度

  8. 攝像頭方面
  9. 攝像頭 數(shù)據(jù)口 為PA口  AO-A7
  10. SCL    PC11
  11. SDA    PC12
  12. OE           PC3                 //片選信號(OE)
  13. WRST   PC4                 //寫指針復(fù)位
  14. RRST   PC2                 //讀指針復(fù)位
  15. RCLK   PC1                 //讀數(shù)據(jù)時鐘
  16. WEN           PC5                 //寫入FIFO使能
  17. VSY           PD2           //同步信號檢測IO

  18. 整個程序流程介紹

  19. 初始化TFT   
  20. 初始化ov7670  ov7670是通過SCCB 初始化的  即 SCL 和SDA就可以初始化OV7670  SDA SCL類似于I2C效果
  21.               所以在調(diào)模塊前 一定要確定OV7670是否已經(jīng)初始化
  22. 開啟中斷 判斷幀數(shù)據(jù)是否接收
  23. 死循環(huán) 讀取并顯示 攝像數(shù)據(jù)

  24.            
  25. */

  26. #include  "stm32f10x.h"
  27. #include  "delay.h"
  28. #include  "led.h"
  29. #include  "tft.h"
  30. #include  "led.h"
  31. #include "ov7670.h"
  32. #include  "gui.h"
  33. #include "usart.h"
  34. #include  "PID.h"

  35. #define KEY0  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_9)        
  36. #define KEY1  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)

  37. void coordinate_output(void);


  38. extern u8 ov_sta;        //幀次數(shù) 置位標(biāo)志位
  39. struct{
  40. u8 photo;
  41. u8 pub_buf[14401];//120*120
  42. char buf[200];
  43. }CAM;



  44. //更新LCD顯示
  45. void camera_refresh(void)
  46. {
  47.         u32 j;
  48.          u16 color,n565Color;
  49.         u8 cRed=0,cBlue=0,cGreen=0;         
  50.         
  51.         TFT_SCAN(5);   //設(shè)置TFT掃描方向 為從下到上 從右到左
  52.         Address_set(60,0,179,119,0,0);                   //設(shè)置顯示范圍        
  53.         if(ov_sta==2)                                //判斷緩存區(qū)是否存好攝像數(shù)據(jù)
  54.         {
  55.                   
  56.                 OV7670_RRST_0;                                //開始復(fù)位讀指針
  57.                 OV7670_RCK_0;
  58.                 OV7670_RCK_1;
  59.                 OV7670_RCK_0;               
  60.                 OV7670_RRST_1;                                //復(fù)位讀指針結(jié)束
  61.                 OV7670_RCK_1;  
  62.                
  63.                 TFT_RS_1;                 //寫數(shù)據(jù)線拉高                為提高寫入速度

  64.                 //此用法 是將 下面寫數(shù)據(jù)的步驟完全拆開  主要是為了提高顯示速度  (下面注釋部分為參考部分)
  65.                      
  66.                 for(j=0;j<14400;j++)                           //分辨率為240x320   每個顏色點要兩個字節(jié) 所以 240x320x2=76800  ?
  67.                 {                        
  68.                         OV7670_RCK_0;                                 //每一次時鐘跳變 讀一次數(shù)據(jù)
  69.                         color=GPIOC->IDR&0XFF;        //讀數(shù)據(jù)   讀取顏色高字節(jié)數(shù)據(jù)
  70.                         OV7670_RCK_1;
  71.                         color<<=8;                                   //左移8位  將高字節(jié)移到高8位  為接收低8位字節(jié)做準(zhǔn)備
  72.                         OV7670_RCK_0;
  73.                         color|=GPIOC->IDR&0XFF;        //讀數(shù)據(jù)   讀取顏色低字節(jié)數(shù)據(jù) 并轉(zhuǎn)化為16位 565 顏色數(shù)據(jù)
  74.                         OV7670_RCK_1;
  75.                   cRed = ((color & 0xf800)>>11);
  76.                         CAM.pub_buf[j]=cRed;
  77.                   n565Color = (cRed << 11) + (cGreen << 5) + (cBlue << 0);                 
  78.             GPIOB->ODR=n565Color;                           //對TFT并口快速寫數(shù)據(jù)
  79.       TFT_WR_0;                                                                      //開始寫入
  80.       TFT_WR_1;
  81.                 }  
  82.                  coordinate_output();
  83.                 EXTI_ClearITPendingBit(EXTI_Line2);  //清除LINE8上的中斷標(biāo)志位
  84.                 ov_sta=0;                                        //開始下一次采集
  85.         }
  86. }
  87. u16 blight=15;//亮度判斷更改這里
  88. void coordinate_output(void)
  89. {
  90.         u16 i,j,k;
  91.         xmax=ymax=0;
  92.         xmin=ymin=119;
  93.         for(i=0;i<120;i++)
  94.         {
  95.                   for(j=0;j<120;j++)
  96.                         {
  97.                                             if(CAM.pub_buf[(i*120)+j]>=blight)
  98.                   {
  99.                                                                                  if(i>1&&i<119&&j<119&&j>1)//如果i值大于8且小于136(限制小球在8~136行),同理,限制小球在16~160列
  100.                                                                                  {
  101.                                                                                             if(j>xmax) {xmax=j;} //不斷更新邊緣,直到找到小球的直徑
  102.                                                                                              if(j<xmin) {xmin=j;}//不斷更新邊緣,直到找到小球的直徑
  103.                                                 
  104.                                                                                             if(i>ymax) {ymax=i;}//不斷更新邊緣,直到找到小球的直徑
  105.                                                                                              if(i<ymin) {ymin=i;}//不斷更新邊緣,直到找到小球的直徑                                                                                         
  106.                                                                                  }
  107.                   }
  108.                         }
  109.         }
  110.         for(k=0;k<14400;k++)
  111.         {
  112.                 CAM.pub_buf[k]=0x00;
  113.         }
  114.         x=(xmax+xmin)/2;
  115.         y=(ymax+ymin)/2;
  116.         if(x<1){x=1;}
  117.         if(x>119){x=119;}
  118.         if(y<1){y=1;}
  119.         if(y>119){y=119;}
  120.         if(x!=0&&y!=0)
  121.         {        
  122. //        GUI_sprintf_hzstr16x(20,200,"                                        ",Red,White);
  123.                 sprintf(CAM.buf,"X:%d   ",x);
  124.                 GUI_sprintf_hzstr16x(20,200,CAM.buf,Red,White);
  125.                 sprintf(CAM.buf,"Y:%d   ",y);
  126.                 GUI_sprintf_hzstr16x(80,200,CAM.buf,Red,White);
  127.                 printf("X:%d",x);
  128.                 printf("Y:%d",y);
  129.                 printf("\r\n");
  130.         }
  131. }

  132. void disp_picture(void)
  133. {
  134.         u16 i,j=0;
  135.         u16 COLOR;
  136.         u8 aRed=0,aBlue=0,aGreen=0;
  137.         coordinate_output();
  138.         
  139.         TFT_SCAN(5);
  140.         Address_set(60,0,179,119,0,0);        
  141.         TFT_RS_1;               

  142.         for(i=0;i<14400;i++)                           
  143.                 {                        
  144.                         aRed=CAM.pub_buf[i];
  145.                   printf("%d        ",aRed);
  146.                         j++;
  147.                         if(j>=120){printf("\r\n");j=0;}               
  148.                   COLOR = (aRed << 11) + (aGreen << 5) + (aBlue << 0);
  149.             GPIOB->ODR=COLOR;                           //對TFT并口快速寫數(shù)據(jù)
  150.       TFT_WR_0;                                                                      //開始寫入
  151.       TFT_WR_1;               
  152.                 }               
  153.          
  154.                 EXTI_ClearITPendingBit(EXTI_Line2);
  155.                
  156. }

  157. int main(void)
  158. {
  159. u8 lightmode=2,saturation=3,brightness=2,contrast=2;
  160. u8 effect=0,flag=0;
  161.           delay_init();                     //延時函數(shù)初始化
  162.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                        
  163.           Lcd_Init();                         //LCD  初始化
  164.          LED_Init();                  
  165.           uart_init(115200);
  166.          TIM2_Int_Init(1,1799);
  167.           TFT_CS(0);                         //打開LCD片選使能
  168.       GUI_Clear(White);                //清屏

  169.                   while(OV7670_Init())//初始化OV7670
  170.         {
  171.             GUI_sprintf_hzstr16x(20,150,"OV7670 Error!!            ",Blue,White);
  172.                 delay_ms(200);
  173.                 printf("OV7670 ERROR!!!!!\r\n");
  174.         }

  175.           GUI_Clear(White);                //清屏                初始化成功后 紅色清屏

  176.                 CAM.photo=0;
  177. //         delay_ms(1500);
  178.          //攝像頭 參數(shù)設(shè)置  屏蔽后為默認(rèn)效果                    
  179.         OV7670_Light_Mode(lightmode);
  180.         OV7670_Color_Saturation(saturation);
  181.         OV7670_Brightness(brightness);
  182.         OV7670_Contrast(contrast);
  183.          OV7670_Special_Effects(effect);         

  184.         EXTI2_Init();                                           //初始化中斷線
  185.         OV7670_Window_Set(10,174,120,120);
  186.         OV7670_CS=0;               
  187.           while(1)                                                           //死循環(huán)顯示 攝像數(shù)據(jù)
  188.           {
  189.                 camera_refresh();
  190. //                 test_motor();
  191.           }
  192. }

復(fù)制代碼

全部資料下載地址:
STM32找球.rar (429.95 KB, 下載次數(shù): 60)
紫電a原理圖.pdf (102.27 KB, 下載次數(shù): 30)


評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:225718 發(fā)表于 2017-8-12 14:59 | 只看該作者
支持坐標(biāo)1~119
回復(fù)

使用道具 舉報

板凳
ID:225718 發(fā)表于 2017-8-13 11:12 | 只看該作者

  1. <p>#include "pid.h"
  2. #include "usart.h"
  3. #include "led.h"</p><p>int x,y,xmax,ymax,xmin,ymin;</p><p>
  4. struct{</p><p>int setspeed;
  5. int actspeed;
  6. int err;  
  7. int err_last;   
  8. int err_next;      
  9. float Kp,Ki,Kd;
  10. float integral;
  11. int incrementSpeed;</p><p>}pid;</p><p>void PID_init(void)
  12. {
  13. pid.setspeed=0;
  14. pid.actspeed=60;
  15. pid.err=0;
  16. pid.Kp=0.25;  //這里調(diào)節(jié)P參數(shù)
  17. pid.Ki=0.25;  //這里調(diào)節(jié)I參數(shù)
  18. pid.Kd=0.21;  //這里調(diào)節(jié)D參數(shù)
  19. }
  20. int PID_adjustment(int speed,int act) //PID處理函數(shù),輸入X、Y到目標(biāo)的距離  輸出應(yīng)該移動的距離
  21. {
  22. pid.setspeed=speed;
  23. pid.actspeed=act;
  24. pid.err=pid.setspeed-pid.actspeed;
  25. pid.incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);
  26. // pid.actspeed+=pid.incrementSpeed;
  27. pid.err_last=pid.err_next;
  28.     pid.err_next=pid.err;

  29. return pid.incrementSpeed;
  30. }</p><p>void DIST_TO_PWM(int dist,u8 zhou) //距離轉(zhuǎn)換 輸入 距離 方向 軸 直接調(diào)整
  31. {
  32.    if(zhou==0)//X軸
  33.    {
  34.     timer1=30+dist*0.2;  //這里調(diào)整X軸,注意!如果X軸反了,把+改成-
  35. //    printf("PIDPWMX:%d",timer1);
  36. //    printf("\r\n");
  37.    }
  38.    if(zhou==1)//Y軸
  39.    {
  40.     timer2=30+dist*0.2;  //這里調(diào)節(jié)Y軸,注意!如果Y軸反了,把+改成-
  41. //    printf("PIDPWMY:%d",timer2);
  42. //    printf("\r\n");
  43.    }
  44. }
  45. void zuobiao_process(u16 ux,u16 uy)//輸入目標(biāo)的坐標(biāo)
  46. {
  47. int xdist,ydist,dist;//x、y離坐標(biāo)的距離
  48. xdist=ux-x;
  49. ydist=uy-y;
  50. dist=PID_adjustment(0,xdist);
  51. if(dist>50){dist=50;} //限制距離調(diào)節(jié)在50
  52. // printf("PIDx:%d",dist);
  53. if(dist<0){DIST_TO_PWM(dist,0);}//處理X軸
  54. if(dist>0){DIST_TO_PWM(dist,0);}
  55. if(dist==0){timer1=30;}
  56. dist=PID_adjustment(0,ydist);
  57. if(dist>50){dist=50;}  //限制距離調(diào)節(jié)在50
  58. // printf("PIDy:%d",dist);
  59. // printf("\r\n");
  60. if(dist!=0){DIST_TO_PWM(dist,1);}//處理Y軸
  61. if(dist==0){timer2=30;}
  62. }

  63. </p>
復(fù)制代碼

程序更新!誰說STM32F103慢?黑底找球+兩路PWM舵機輸出(帶PID),可以在程序里面調(diào)節(jié)PID大小,實測輸出FPS:20左右!


截屏_20170813_105441.jpg (900.13 KB, 下載次數(shù): 102)

截屏_20170813_105441.jpg

PID V1.00.rar

4.99 MB, 下載次數(shù): 25, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報

地板
ID:138247 發(fā)表于 2019-4-4 16:19 | 只看該作者

謝謝分享。。。。。。。。。
回復(fù)

使用道具 舉報

5#
ID:138247 發(fā)表于 2019-4-4 16:23 | 只看該作者

謝謝分享。。。。
回復(fù)

使用道具 舉報

6#
ID:110257 發(fā)表于 2019-4-5 06:51 | 只看該作者
謝謝分享�。�!
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表