标题:
智能小车CCD程序
[打印本页]
作者:
3443896565
时间:
2017-4-10 17:45
标题:
智能小车CCD程序
这个为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;
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1