找回密码
 立即注册

QQ登录

只需一步,快速开始

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

17年电赛板球系统STM32源程序

[复制链接]
跳转到指定楼层
楼主
ID:456306 发表于 2019-8-15 22:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
之前准备电赛的时候,找滚球的程序很费劲,找了很久终于找到一个不收费的了
板球系统网上的标配是:
stm32f4+ov2640或7725或7760+液晶彩屏(方便调试),具体的我就不在赘述了,网上帖子很多,这里单纯的分享资源,希望方便有需要的人,
系统基于原子的探索者f4+ov2640,软件二值化.

单片机源程序如下:
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "key.h"
  6. #include "lcd.h"
  7. #include "usmart.h"  
  8. #include "usart2.h"  
  9. #include "timer.h"
  10. #include "ov2640.h"
  11. #include "dcmi.h"
  12. #include "string.h"
  13. #include "pwm.h"

  14. u16 rgb_buf[144][176];        
  15. u16 gray,Have=0,SY=0,time=0;
  16. extern u8 flag;
  17. u16 hang=0,time1=0;
  18. u8 X_MAX,Y_MAX=0;    //小球的坐标信息
  19. u8 X_MAX_LSAT, X_MIN_LSAT, Y_MAX_LSAT, Y_MIN_LSAT=0;   //上一次小球坐标位置信息
  20. u8 X,Y=0;      //小球的质心信息
  21. u8 X_MIN,Y_MIN=180;
  22. unsigned char ax,ay;
  23. int PWM_X,PWM_Y=0;
  24. float Err_X,Err_Y=0;
  25. float Err_X_LAST,Err_Y_LAST=0;
  26. float Aim_X,Aim_Y=0;
  27. float Kp,Ki,Kd=0;

  28. //ALIENTEK 探索者STM32F407开发板 实验35
  29. //摄像头 实验 -库函数版本
  30. //技术支持:www.openedv.com
  31. //淘宝店铺:http://eboard.taobao.com  
  32. //广州市星翼电子科技有限公司  
  33. //作者:正点原子 @ALIENTEK


  34. //JPEG尺寸支持列表
  35. const u16 jpeg_img_size_tbl[][2]=
  36. {
  37.         176,144,        //QCIF
  38.         160,120,        //QQVGA
  39.         352,288,        //CIF
  40.         320,240,        //QVGA
  41.         640,480,        //VGA
  42.         800,600,        //SVGA
  43.         1024,768,        //XGA
  44.         1280,1024,        //SXGA
  45.         1600,1200,        //UXGA
  46. };


  47. void TIM3_Int_Init(u16 arr,u16 psc);
  48. u16 getcolor2(u16 tx,u16 ty) //从LCD读点,转化为灰度值
  49. {
  50.         u16 i,tempcolor,R,G,B,avr;       
  51.         tempcolor=LCD_ReadPoint(tx,ty);
  52.         R = (int) ((tempcolor>>11) * 255.0 / 31.0 + 0.5);
  53.         G = (int) ((tempcolor>>5&0x3f) * 255.0 / 63.0 + 0.5);
  54.         B = (int) ((tempcolor&0x1f) * 255.0 / 31.0 + 0.5);
  55.         avr=(R * 19595 + G * 38469 + B * 7472) >> 16;
  56.         return avr;
  57. }

  58. void search(void)
  59. {
  60.         unsigned char tx,ty,avr[162][134];
  61.         ax=0;
  62.         ay=0;
  63.         for(tx=8;tx<162;tx+=3){
  64.                 for(ty=10;ty<134;ty+=3){
  65.                         if(getcolor2(tx,ty)==255)        //当前点为白色
  66.                         {
  67.                                 if(getcolor2(tx-1,ty-1)==255 &&getcolor2(tx+1,ty+1)==255 &&getcolor2(tx-1,ty+1)==255 && getcolor2(tx+1,ty-1)==255 ){
  68.                                         ax=tx/176.0*58;
  69.                                         ay=ty/144.0*48;
  70.                                 }
  71.                         }
  72.                 }
  73.         }
  74. //        if(ax==0&&ay==0){
  75. //                ax=29;
  76. //                ay=25;
  77. //        }
  78. }

  79. //t最佳阈值,w0背景比例,u0背景均值,w1前景比例,u1前景均值,u整幅图像的均值
  80. u16 GetThreshValue(void)
  81. {
  82.     int pixelNum[256];//图像直方图 共256点
  83.     u16 i,j,color;
  84.     int n, n1, n2;
  85.     int total;//total为总和
  86.     double m1, m2, sum, csum, fmax, sb;//sb类间房差,fmax存储最大方差值
  87.     int k, t, q;
  88.     int threshValue =1;// 阈值
  89.     for(i=0; i<144; i+=3){
  90.         for(j=0; j<176; j+=3){
  91.             color=getcolor2(i,j);//返回各个点的颜色
  92.             pixelNum[color]++;//相应直方图+1
  93.         }
  94.     }
  95.     //直方图平滑化
  96.     for(k=0; k<=255; k++){
  97.         total =0;
  98.         for(t =-2; t <=2; t++){//附近两个灰度做平滑化
  99.             q = k + t;
  100.             if(q <0)//越界处理
  101.                 q =0;
  102.             if(q >255)
  103.                 q =255;
  104.             total = total + pixelNum[q];//total为总和,累计值
  105.         }
  106.         //平滑化,左边两个+中间1个+右边两个
  107.         pixelNum[k]=(int)((float)total /5.0+0.5);
  108.     }
  109.     //求阈值
  110.     sum = csum =0.0;
  111.     n =0;
  112.     //求总的图像的点数和质量矩
  113.     for(k =0; k <=255; k++){
  114.         //x*f(x)每个灰度的值*其点数(归一化后为概率)
  115.         sum +=(double)k *(double)pixelNum[k];
  116.         n += pixelNum[k];//n总点数,归一化后为累积概率
  117.     }
  118.     fmax =-1.0;//sb不可能为负
  119.     n1 =0;
  120.     for(k =0; k <255; k++){//计算一次分割后的sb
  121.         n1 += pixelNum[k];//n1为在当前阈值遍前景图像的总数
  122.         if(n1 ==0){continue;}//没有分出前后景
  123.         n2 = n - n1;//n2为背景图像的点数
  124.         //n2=0为全后景图
  125.         if(n2 ==0){break;}
  126.         csum +=(double)k * pixelNum[k];//前景的灰度值*点数 的总和
  127.         m1 = csum / n1;//m1前景的平均灰度
  128.         m2 =(sum - csum)/ n2;//m2背景的平均灰度
  129.         sb =(double)n1 *(double)n2 *(m1 - m2)*(m1 - m2);//sb类间方差
  130.         if(sb > fmax){//此次类方差>前一次类方差
  131.             fmax = sb;//取最大值
  132.             threshValue = k;//返回阈值
  133.         }
  134.     }
  135.     return threshValue;
  136. }

  137. void senddata(void)
  138. {
  139.                 USART_SendData(USART2,(ax&0x3f));
  140.                 while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);
  141.                 USART_SendData(USART2,(ay|0xc0));
  142.                 while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);
  143. }

  144. int main(void)
  145. {
  146.   u16 i,j;
  147.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  148.         delay_init(168);  //初始化延时函数
  149.         uart_init(115200);                //初始化串口波特率为115200
  150.         usart2_init(42,9600);                //初始化串口2波特率为115200
  151.         //LED_Init();                                        //初始化LED
  152.         LCD_Init();                                        //LCD初始化  
  153.         //KEY_Init();                                        //按键初始化
  154.         TIM3_Int_Init(10000-1,8400-1);//10Khz计数,1秒钟中断一次
  155.        
  156.         //TIM14_PWM_Init(10000-1,168-1);        //重装载值10000,所以PWM频率为 150hz.      //舵机预留
  157.         //TIM11_PWM_Init(10000-1,336-1);        //重装载值10000,所以PWM频率为 150hz.       
  158.        
  159.         //usmart_dev.init(84);                //初始化USMART
  160.         OV2640_Init();
  161.   OV2640_OutSize_Set(176,144);
  162.        
  163. //        OV2640_Light_Mode(0); //白平衡设置 自动
  164. //        OV2640_Auto_Exposure(0); //自动曝光
  165. //        OV2640_Color_Saturation(2); //色度设置
  166. //        OV2640_Brightness(0); //亮度设置
  167.         OV2640_Contrast(4); //对比度设置
  168. //        OV2640_Special_Effects(2); //黑白化

  169.   OV2640_RGB565_Mode();        //RGB565模式
  170.   My_DCMI_Init();                        //DCMI配置
  171.   DCMI_DMA_Init((u32)rgb_buf,sizeof(rgb_buf)/4,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Enable);//DCMI DMA配置
  172.   DCMI_Start();                 //启动传输
  173.         while(1)
  174.         {
  175.                         LCD_SetCursor(0,0);
  176.                         LCD_WriteRAM_Prepare();                //开始写入GRAM
  177.                         for(i=0;i<150;i++){
  178.                                         for(j=0;j<176;j++){
  179.                                                         if(j==175){
  180.                                                                         LCD_SetCursor(0,i+1);  
  181.                                                                         LCD_WriteRAM_Prepare();                //开始写入GRAM
  182.                                                         }
  183.                                                         gray=((rgb_buf[i][j]>>11)*19595+((rgb_buf[i][j]>>5)&0x3f)*38469 +(rgb_buf[i][j]&0x1f)*7472)>>16;
  184.                                                         //gray=((rgb_buf[i][j]>>5)&0x3f)* 255.0 / 63.0 + 0.5;
  185.                                                          if(gray >23){
  186. //                                                                if(i>8&&i<136&&j<160&&j>16){
  187. //                                                                                if(i>X_MAX) X_MAX=i;
  188. //                                                                                if(i<X_MIN) X_MIN=i;
  189. //                                                                                if(j>Y_MAX) Y_MAX=j;
  190. //                                                                                if(j<Y_MIN) Y_MIN=j;                                                                                                                 
  191. //                                                                        }
  192.                                                                 LCD->LCD_RAM=WHITE;       
  193.                                                         }
  194.                                                         else{
  195.                                                                 LCD->LCD_RAM=BLACK;
  196.                                                         }
  197.                                         }
  198.                         }
  199. //                X_MAX_LSAT =        X_MAX;    //更新pid的real坐标信息 清除掉本次坐标用于再次遍历最大值 最小值
  200. //                X_MIN_LSAT =        X_MIN;
  201. //                Y_MAX_LSAT =        Y_MAX;
  202. //                Y_MIN_LSAT =        Y_MIN;   
  203. //                       
  204. //                X_MAX=0;
  205. //                X_MIN=180;
  206. //                Y_MAX=0;
  207. //                Y_MIN=180;
  208. //                       
  209. //                X=(X_MAX_LSAT+X_MIN_LSAT)/2;
  210. //                Y=(Y_MAX_LSAT+Y_MIN_LSAT)/2;
  211.                
  212. //                TIM_SetCompare1(TIM14,9340);        //修改比较值,修改占空比
  213. //                TIM_SetCompare1(TIM11,9300);        //修改比较值,修改占空比
  214.                 search();
  215.                 LCD_ShowxNum(30,210,ax,3,16,0);
  216.                 LCD_ShowxNum(30,230,ay,3,16,0);
  217.                 if(Have==1){
  218.                         senddata();
  219.                         if( ((ax==29||ax==28||ax==30)&&(ay==7||ay==8||ay==9)) || ((ax==11||ax==12||ax==13)&&(ay==7||ay==8||ay==9)) || ((ax==30||ax==31||ax==29)&&(ay==26||ay==27)) )
  220.                                 SY=1;
  221.                         else{
  222.                                 SY=0;
  223.                         }
  224.                 }
  225.                 else{
  226.                         time1=0;
  227.                 }
  228.                 LCD_ShowxNum(80,210,time,3,16,0);//显示当前时间
  229.                 LCD_ShowxNum(80,230,time1,3,16,0);//区域2停留的时间
  230.         }
  231. }

  232. void TIM3_IRQHandler(void)
  233. {
  234.         if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
  235.         {
  236.                 if(Have==1){
  237.                         time++;
  238.                         if(time>60)
  239.                                 time=0;
  240.                 }
  241.                 if(SY==1){
  242.                         time1++;
  243.                 }
  244.                 if(SY==0)
  245.                         time1=0;
  246.                 Kp=3.4;
  247.                 Kd=80.9;

  248.                 Aim_X=72;
  249.                 Aim_Y=88;
  250.                
  251.                 Err_X=X-Aim_X;
  252.                 Err_Y=Y-Aim_Y;
  253.                
  254.                 PWM_X=9340+(Err_X*Kp+(Err_X-Err_X_LAST)*Kd);
  255.                 PWM_Y=9300+(Err_Y*Kp+(Err_Y-Err_Y_LAST)*Kd);
  256.                
  257.                 if(PWM_Y>9370)PWM_Y=9370;
  258.                 if(PWM_Y<9230)PWM_Y=9230;
  259.                
  260.                 if(PWM_X>9410)PWM_X=9410;
  261.                 if(PWM_X<9270)PWM_X=9270;
  262.                
  263.                 Err_X_LAST=Err_X;
  264.                 Err_Y_LAST=Err_Y;
  265.                
  266.                 TIM_SetCompare1(TIM14,PWM_X);        //修改比较值,修改占空比
  267.                 TIM_SetCompare1(TIM11,PWM_Y);        //修改比较值,修改占空比
  268.         }
  269.         TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
  270. }
复制代码

所有资料51hei提供下载:
实验板球系统.7z (375.89 KB, 下载次数: 56)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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