找回密码
 立即注册

QQ登录

只需一步,快速开始

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

智能小车CCD程序

[复制链接]
跳转到指定楼层
楼主
这个为CCD是镜头程序,CCD看到的为一条线非摄像头看到的矩阵面

下载:
CCD.rar (1.73 KB, 下载次数: 15)



程序预览:
  1. #include "CCD.h"

  2. #define CCD_CLK_PORT   PTE4                     //CLK 引脚定义
  3. #define CCD_SI_PORT    PTE5                     //SI 引脚定义
  4. #define AD_CHANNEL1    ADC0_SE8                 //通道1
  5. #define AD_CHANNEL2    ADC0_SE9                 //通道2
  6. #define EXPOSURE_TIME  10                       //CCD曝光时间
  7. #define CCD_CLK(x)     gpio_set (CCD_CLK_PORT, x)
  8. #define CCD_SI(x)      gpio_set (CCD_SI_PORT,  x)

  9. uint16 ccd_data1[128];                           //CCD1数据
  10. uint16 ccd_data2[128];                           //CCD2数据

  11. uint16 flag0,flag1,flag2,flag3;
  12. void ccd_init(void)     
  13. {      
  14.     adc_init (AD_CHANNEL1);                     
  15.     adc_init (AD_CHANNEL2);                     
  16.     gpio_init(CCD_CLK_PORT,GPO,1);            //CLK
  17.     gpio_init(CCD_SI_PORT,GPO,1);            //SI
  18.    
  19.     port_init_NoALT (CCD_CLK_PORT,PULLUP );
  20.     port_init_NoALT (CCD_SI_PORT,PULLUP );
  21.    
  22.     DisableInterrupts;
  23.    
  24.     pit_init(PIT0, EXPOSURE_TIME*bus_clk_khz);   //定时 100000 个bus时钟 后中断
  25.     set_vector_handler(PIT0_VECTORn,pit_hander); //设置中断复位函数到中断向量表里
  26.     enable_irq(PIT0_IRQn);                       //使能PIT0中断
  27.     EnableInterrupts;
  28. }

  29. //CCD数据采集
  30. void ccd_collect(void)
  31. {
  32.     uint16 i = 0;

  33.     CCD_CLK(1);
  34.     CCD_SI(0);

  35.     CCD_SI(1);
  36.     CCD_CLK(0);   

  37.     CCD_CLK(1);
  38.     CCD_SI(0);   
  39.    
  40.     for(i=0;i<128;i++)
  41.     {
  42.         CCD_CLK(0);   
  43.         ccd_data1[i] = adc_once(AD_CHANNEL1, ADC_12bit)>>1;
  44.         ccd_data2[i] = adc_once(AD_CHANNEL2, ADC_12bit)>>1;
  45.         CCD_CLK(1);
  46.     }

  47. }

  48. int16 calc_diff(int16 x, int16 y)
  49. {
  50.     return(int16)((long)(x-y)*100/(x+y));
  51. }

  52. uint8 flag_left_valid1 = 0,       flag_right_valid1 = 0;
  53. uint8 ccd_left1 = 64,             ccd_right1 = 64;
  54. uint8 ccd_left1_old = 64,         ccd_right1_old = 64;
  55. int16 position1 = 0;              int16 position_old1 = 0;
  56. uint8 efct_width1 = 0;   
  57. uint8 real_width1 = 0;
  58. uint8 real_width1_old = 0;


  59. //搜索的位置
  60. uint8 left_start1 ,left_end1;
  61. uint8 right_start1,right_end1;


  62. void search_line1(void)
  63. {
  64.     int16 i;
  65.     //确定搜索范围
  66.     left_start1 = position1 + 64;
  67.     if(left_start1<10)          left_start1 = 10;
  68.     left_end1 = 5;
  69.    
  70.     right_start1 = position1 + 64;
  71.     if(right_start1>117)        right_start1 = 117;
  72.     right_end1 = 122;
  73.    
  74.     //清除该行标志位
  75.     flag_left_valid1 = 0;
  76.     flag_right_valid1 = 0;
  77.    
  78.     //search left
  79.     ccd_left1 = 5;
  80.     for(i=left_start1; i>=left_end1; i--)
  81.     {
  82.         if(calc_diff(ccd_data1[i],ccd_data1[i-5])>30)
  83.         {
  84.             flag_left_valid1 = 1;ccd_left1 = i-5;ccd_left1_old=ccd_left1;
  85.             break;
  86.         }
  87.     }
  88.    
  89.     //search right
  90.     ccd_right1 = 122;
  91.     for(i=right_start1; i<=right_end1; i++)
  92.     {
  93.         if(calc_diff(ccd_data1[i],ccd_data1[i+5])>30)
  94.         {
  95.             flag_right_valid1 = 1;ccd_right1 = i+5;ccd_right1_old=ccd_right1;
  96.             break;
  97.         }
  98.     }
  99.     //修正边界
  100.     if(flag_left_valid1 && !flag_right_valid1)  
  101.     {
  102.         if( ((2*ccd_left1 + efct_width1)/2 - 64) <0)    flag_left_valid1 = 0;
  103.         position1 = 0;
  104.     }
  105.    
  106.     if(!flag_left_valid1 && flag_right_valid1)  
  107.     {
  108.         if( ((2*ccd_right1 - efct_width1)/2 - 64) >0)    flag_right_valid1 = 0;
  109.         position1 = 0;
  110.     }

  111.     //计算有效宽度
  112.     if(flag_left_valid1 && flag_right_valid1)efct_width1 = ccd_right1 - ccd_left1;
  113.    
  114.       //计算真实宽度
  115.       real_width1 = ccd_right1 - ccd_left1;
  116.   
  117.     //计算坐标
  118.     if(flag_left_valid1 && flag_right_valid1)           position1 = (ccd_left1 + ccd_right1)/2 - 64;
  119.     else if(flag_left_valid1 && !flag_right_valid1)     position1 = (2*ccd_left1 + efct_width1)/2 - 64;
  120.     else if(!flag_left_valid1 && flag_right_valid1)     position1 = (2*ccd_right1 - efct_width1)/2 - 64;
  121.    
  122.    
  123.     ccd_left1_old = ccd_left1;
  124.     ccd_right1_old = ccd_right1;
  125.     real_width1_old = real_width1;
  126.     //存储边界用于下次搜线确定边界
  127.    
  128. }

  129. uint8 flag_left_valid2 = 0,       flag_right_valid2 = 0;
  130. uint8 ccd_left2 = 64,             ccd_right2 = 64;
  131. uint8 ccd_left2_old = 64,         ccd_right2_old = 64;
  132. int16 position2 = 0;        
  133. uint8 efct_width2 = 0;   
  134. uint8 real_width2 = 0;   
  135. uint8 real_width2_old = 0;

  136. //搜索的位置
  137. uint8 left_start2 ,left_end2;
  138. uint8 right_start2,right_end2;

  139. void search_line2(void)
  140. {
  141.     int16 i;

  142.     //确定搜索范围
  143.     left_start2 = position2 + 64;
  144.     if(left_start2<10)   left_start2 = 10;
  145.     left_end2 = 5;
  146.    
  147.     right_start2 = position2 + 64;
  148.     if(right_start2>117)   right_start2 = 117;
  149.     right_end2 = 122;
  150.    
  151.     //清除该行标志位
  152.     flag_left_valid2 = 0;
  153.     flag_right_valid2 = 0;

  154.     //search left
  155.     ccd_left2 = 5;
  156.     for(i=left_start2; i>=left_end2; i--)
  157.     {
  158.         if(calc_diff(ccd_data2[i],ccd_data2[i-5])>30)
  159.         {
  160.           flag_left_valid2 = 1;ccd_left2 = i-5;ccd_left2_old=ccd_left2;
  161.           break;
  162.         }
  163.     }
  164.     //search right
  165.     ccd_right2 = 122;
  166.     for(i=right_start2; i<=right_end2; i++)
  167.     {
  168.         if(calc_diff(ccd_data2[i],ccd_data2[i+5])>30)
  169.           {
  170.             flag_right_valid2 = 1;ccd_right2 = i+5;ccd_right2_old=ccd_right2;
  171.             break;
  172.           }  
  173.     }
  174.     //修正边界
  175.     if(flag_left_valid2 && !flag_right_valid2)  
  176.     {
  177.         if( ((2*ccd_left2 + efct_width2)/2 - 64) <0)    flag_left_valid2 = 0;
  178.         position2 = 0;
  179.     }
  180.    
  181.     if(!flag_left_valid2 && flag_right_valid2)  
  182.     {  
  183.         if( ((2*ccd_right2 - efct_width2)/2 - 64) >0)
  184.           flag_right_valid2 = 0;position2 = 0;
  185.     }
  186.    
  187.     //计算有效宽度
  188.     if(flag_left_valid2 && flag_right_valid2)efct_width2 = ccd_right2 - ccd_left2;

  189.       //计算真实宽度
  190.       real_width2 = ccd_right2 - ccd_left2;

  191.     //计算坐标
  192.     if(flag_left_valid2 && flag_right_valid2)           position2 = (ccd_left2 + ccd_right2)/2 - 64;
  193.     else if(flag_left_valid2 && !flag_right_valid2)     position2 = (2*ccd_left2 + efct_width2)/2 - 64;
  194.     else if(!flag_left_valid2 && flag_right_valid2)     position2 = (2*ccd_right2 - efct_width2)/2 - 64;

  195.     //存储边界用于下次搜线确定边界
  196.     ccd_left2_old = ccd_left2;
  197.     ccd_right2_old = ccd_right2;
  198.     real_width2_old = real_width2;
  199. }
  200. int16 position = 0;
  201. int16 k1,k2;
  202. void calc_road(void)
  203. {
  204.     search_line1();     //搜线
  205.     search_line2();
  206.    
  207.     k1 = real_width1 - 36;
  208.    
  209.     if(k1>45)           {k1 = 20; k2 = 80;}
  210.     else if(k1<=0)      {k1 = 100;k2 = 0;}
  211.     else if(k1<-10)     {k1 = 100; k2 = 0;}
  212.     else
  213.     {
  214.         k1 = k1 * 3/2;
  215.         k1 = 100 - k1;
  216.         k2 = 100 - k1;
  217.        
  218.     }
  219.           //k1 = 100;
  220.         //k2 = 0;
  221.     if(real_width1>100&&real_width2>100)
  222.       position = 2;
  223.     else
  224.     position = position1*k1/100 + position2*k2/100;   
  225. }
复制代码


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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