这个为CCD是镜头程序,CCD看到的为一条线非摄像头看到的矩阵面
下载:
CCD.rar
(1.73 KB, 下载次数: 15)
程序预览:
- #include "CCD.h"
- #define CCD_CLK_PORT PTE4 //CLK 引脚定义
- #define CCD_SI_PORT PTE5 //SI 引脚定义
- #define AD_CHANNEL1 ADC0_SE8 //通道1
- #define AD_CHANNEL2 ADC0_SE9 //通道2
- #define EXPOSURE_TIME 10 //CCD曝光时间
- #define CCD_CLK(x) gpio_set (CCD_CLK_PORT, x)
- #define CCD_SI(x) gpio_set (CCD_SI_PORT, x)
- uint16 ccd_data1[128]; //CCD1数据
- uint16 ccd_data2[128]; //CCD2数据
- uint16 flag0,flag1,flag2,flag3;
- void ccd_init(void)
- {
- adc_init (AD_CHANNEL1);
- adc_init (AD_CHANNEL2);
- gpio_init(CCD_CLK_PORT,GPO,1); //CLK
- gpio_init(CCD_SI_PORT,GPO,1); //SI
-
- port_init_NoALT (CCD_CLK_PORT,PULLUP );
- port_init_NoALT (CCD_SI_PORT,PULLUP );
-
- DisableInterrupts;
-
- pit_init(PIT0, EXPOSURE_TIME*bus_clk_khz); //定时 100000 个bus时钟 后中断
- set_vector_handler(PIT0_VECTORn,pit_hander); //设置中断复位函数到中断向量表里
- enable_irq(PIT0_IRQn); //使能PIT0中断
- EnableInterrupts;
- }
- //CCD数据采集
- void ccd_collect(void)
- {
- uint16 i = 0;
-
- CCD_CLK(1);
- CCD_SI(0);
- CCD_SI(1);
- CCD_CLK(0);
- CCD_CLK(1);
- CCD_SI(0);
-
- for(i=0;i<128;i++)
- {
- CCD_CLK(0);
- ccd_data1[i] = adc_once(AD_CHANNEL1, ADC_12bit)>>1;
- ccd_data2[i] = adc_once(AD_CHANNEL2, ADC_12bit)>>1;
- CCD_CLK(1);
- }
- }
- int16 calc_diff(int16 x, int16 y)
- {
- return(int16)((long)(x-y)*100/(x+y));
- }
- uint8 flag_left_valid1 = 0, flag_right_valid1 = 0;
- uint8 ccd_left1 = 64, ccd_right1 = 64;
- uint8 ccd_left1_old = 64, ccd_right1_old = 64;
- int16 position1 = 0; int16 position_old1 = 0;
- uint8 efct_width1 = 0;
- uint8 real_width1 = 0;
- uint8 real_width1_old = 0;
- //搜索的位置
- uint8 left_start1 ,left_end1;
- uint8 right_start1,right_end1;
- void search_line1(void)
- {
- int16 i;
- //确定搜索范围
- left_start1 = position1 + 64;
- if(left_start1<10) left_start1 = 10;
- left_end1 = 5;
-
- right_start1 = position1 + 64;
- if(right_start1>117) right_start1 = 117;
- right_end1 = 122;
-
- //清除该行标志位
- flag_left_valid1 = 0;
- flag_right_valid1 = 0;
-
- //search left
- ccd_left1 = 5;
- for(i=left_start1; i>=left_end1; i--)
- {
- if(calc_diff(ccd_data1[i],ccd_data1[i-5])>30)
- {
- flag_left_valid1 = 1;ccd_left1 = i-5;ccd_left1_old=ccd_left1;
- break;
- }
- }
-
- //search right
- ccd_right1 = 122;
- for(i=right_start1; i<=right_end1; i++)
- {
- if(calc_diff(ccd_data1[i],ccd_data1[i+5])>30)
- {
- flag_right_valid1 = 1;ccd_right1 = i+5;ccd_right1_old=ccd_right1;
- break;
- }
- }
- //修正边界
- if(flag_left_valid1 && !flag_right_valid1)
- {
- if( ((2*ccd_left1 + efct_width1)/2 - 64) <0) flag_left_valid1 = 0;
- position1 = 0;
- }
-
- if(!flag_left_valid1 && flag_right_valid1)
- {
- if( ((2*ccd_right1 - efct_width1)/2 - 64) >0) flag_right_valid1 = 0;
- position1 = 0;
- }
-
- //计算有效宽度
- if(flag_left_valid1 && flag_right_valid1)efct_width1 = ccd_right1 - ccd_left1;
-
- //计算真实宽度
- real_width1 = ccd_right1 - ccd_left1;
-
- //计算坐标
- if(flag_left_valid1 && flag_right_valid1) position1 = (ccd_left1 + ccd_right1)/2 - 64;
- else if(flag_left_valid1 && !flag_right_valid1) position1 = (2*ccd_left1 + efct_width1)/2 - 64;
- else if(!flag_left_valid1 && flag_right_valid1) position1 = (2*ccd_right1 - efct_width1)/2 - 64;
-
-
- ccd_left1_old = ccd_left1;
- ccd_right1_old = ccd_right1;
- real_width1_old = real_width1;
- //存储边界用于下次搜线确定边界
-
- }
- uint8 flag_left_valid2 = 0, flag_right_valid2 = 0;
- uint8 ccd_left2 = 64, ccd_right2 = 64;
- uint8 ccd_left2_old = 64, ccd_right2_old = 64;
- int16 position2 = 0;
- uint8 efct_width2 = 0;
- uint8 real_width2 = 0;
- uint8 real_width2_old = 0;
- //搜索的位置
- uint8 left_start2 ,left_end2;
- uint8 right_start2,right_end2;
- void search_line2(void)
- {
- int16 i;
- //确定搜索范围
- left_start2 = position2 + 64;
- if(left_start2<10) left_start2 = 10;
- left_end2 = 5;
-
- right_start2 = position2 + 64;
- if(right_start2>117) right_start2 = 117;
- right_end2 = 122;
-
- //清除该行标志位
- flag_left_valid2 = 0;
- flag_right_valid2 = 0;
- //search left
- ccd_left2 = 5;
- for(i=left_start2; i>=left_end2; i--)
- {
- if(calc_diff(ccd_data2[i],ccd_data2[i-5])>30)
- {
- flag_left_valid2 = 1;ccd_left2 = i-5;ccd_left2_old=ccd_left2;
- break;
- }
- }
- //search right
- ccd_right2 = 122;
- for(i=right_start2; i<=right_end2; i++)
- {
- if(calc_diff(ccd_data2[i],ccd_data2[i+5])>30)
- {
- flag_right_valid2 = 1;ccd_right2 = i+5;ccd_right2_old=ccd_right2;
- break;
- }
- }
- //修正边界
- if(flag_left_valid2 && !flag_right_valid2)
- {
- if( ((2*ccd_left2 + efct_width2)/2 - 64) <0) flag_left_valid2 = 0;
- position2 = 0;
- }
-
- if(!flag_left_valid2 && flag_right_valid2)
- {
- if( ((2*ccd_right2 - efct_width2)/2 - 64) >0)
- flag_right_valid2 = 0;position2 = 0;
- }
-
- //计算有效宽度
- if(flag_left_valid2 && flag_right_valid2)efct_width2 = ccd_right2 - ccd_left2;
- //计算真实宽度
- real_width2 = ccd_right2 - ccd_left2;
- //计算坐标
- if(flag_left_valid2 && flag_right_valid2) position2 = (ccd_left2 + ccd_right2)/2 - 64;
- else if(flag_left_valid2 && !flag_right_valid2) position2 = (2*ccd_left2 + efct_width2)/2 - 64;
- else if(!flag_left_valid2 && flag_right_valid2) position2 = (2*ccd_right2 - efct_width2)/2 - 64;
- //存储边界用于下次搜线确定边界
- ccd_left2_old = ccd_left2;
- ccd_right2_old = ccd_right2;
- real_width2_old = real_width2;
- }
- int16 position = 0;
- int16 k1,k2;
- void calc_road(void)
- {
- search_line1(); //搜线
- search_line2();
-
- k1 = real_width1 - 36;
-
- if(k1>45) {k1 = 20; k2 = 80;}
- else if(k1<=0) {k1 = 100;k2 = 0;}
- else if(k1<-10) {k1 = 100; k2 = 0;}
- else
- {
- k1 = k1 * 3/2;
- k1 = 100 - k1;
- k2 = 100 - k1;
-
- }
- //k1 = 100;
- //k2 = 0;
- if(real_width1>100&&real_width2>100)
- position = 2;
- else
- position = position1*k1/100 + position2*k2/100;
- }
复制代码
|