這個為CCD是鏡頭程序,CCD看到的為一條線非攝像頭看到的矩陣面
0.png (48.92 KB, 下載次數: 85)
下載附件
2017-4-11 19:34 上傳
下載:
CCD.rar
(1.73 KB, 下載次數: 15)
2017-4-10 17:43 上傳
點擊文件名下載附件
CCD 下載積分: 黑幣 -5
程序預覽:
- #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;
- }
復制代碼
|