磨损度的CCD光电非接触检测技术研究.docx
《磨损度的CCD光电非接触检测技术研究.docx》由会员分享,可在线阅读,更多相关《磨损度的CCD光电非接触检测技术研究.docx(18页珍藏版)》请在冰点文库上搜索。
磨损度的CCD光电非接触检测技术研究
磨损度的CCD光电非接触检测技术研究
中期检查报告
磨损度的CCD光电非接触检测技术研究
项目在分析基本检测原理的基础上,进行基础实验的可行性验证,确定系统设计方案。
通过实践,系统的整体构架设计完成,包括轧辊的模型,CCD传感器的驱动电路设计,二值化电路的设计,数据的简单分析,上位机的界面编写,数据的初级显示。
通过驱动电路,我们可以得到CCD传感器的输出信号,用示波器观察输出的视频信号,可以明显的看到,CCD的输出信号幅值在随光照强度呈线性变化,且反应较为敏感。
多次程序的矫正,得到了驱动CCD的脉冲,使我们对驱动脉冲的理解更为深刻。
得到的信号进行了简单的AD转换,用STC12C5A60S2单片机处理,在1602液晶显示器能显示出来处理的数据。
在应用到CCD的光电信息系统中,首先必须产生正确的驱动脉冲,使CCD每个像元上的电荷信号渐次转移输出,保证CCD正常工作.然后再对CCD的输出信号进行调理和AD转换,完成数据采集.本文根据所选的图像传感器TCD1251UD的时序特点,设计了驱动脉冲的逻辑电路,通过仿真分析和实际测试检验了波形的正确性.并利用单片机的控制,对线阵CCD的输出数据进行快速采样、存储及数据分析处理.
下面是驱动仿真结果:
图1驱动电路图及仿真脉冲
图2脉冲相位关系
从上往下依次为PA、PB、RS、SH。
从示波器上看出:
fPA=1/(50)MHz,其中50为估计的,实际上为48.2左右,而我的单片机速度是上图单片机的24倍,故采用我的单片机时f=1/2MHz。
同样fRS=1MHz
本设计所采用的线阵CCD为东芝公司的TCD1251UD型,该器件是一种高灵敏度、低暗电流、2700像元的二相线性CCD,工作电压为12V。
其中1A,1B分别为驱动时钟的第一相和第二相,2A、2B分别为末极时钟的第一相和第二相,SH为转移脉冲,RS为复位脉冲,这6个脉冲的幅值大小均为+5V,OD为驱动电源电压,其值为+12V,SS是地,OS为信号输出,DOS为补偿输出.其驱动电路由SH、1、2、RS四路脉冲组成。
TCD1251UD的四个驱动脉冲之间的关系如图2所示.转移脉冲SH的脉冲宽度没有要求,其下降沿是每行输出的起始点;时钟脉冲1,末极时钟2是频率相同、占空比均为50%、相位相差90度的两路脉冲,其作用为驱动信号电荷进行定向转移;复位脉冲RS的频率是1、2频率的二倍,它能清除输出极输出一个单元电荷后所剩余电荷,以保证下一个单元电荷电压的正确输出。
四路驱动脉冲的正确驱动下,该图像传感器将产生有效光电信号OS和补偿信号DOS。
1、下图是系统的整体组装图:
图3系统总汇图
包括电源、轧辊模型、驱动电路、CCD传感器、液晶显示
2、轧辊模型
图4轧辊模型
3、系统总电源
图5电源
采用7805、7812自制标准的5V及12V电源。
4、驱动电路
图6驱动板
采用STC12C5A60S2单片机进行编程产生驱动时序
5、CCD传感器
图7TCD1251UDCCD传感器
选择东芝公司的TCD1251UD,这是一种高灵敏度、低暗流的含有2700像元的线阵CCD图像传感器。
6,、输出信号
从图8可以看出转移脉冲OS有尖峰脉冲的出现,因此考虑用滤波电容消除尖峰脉冲,经过滤波之后的波形变坏了,所暂且不进行滤波。
但信号随着光照强度呈线性变化,说明驱动的正确性。
图8OS输出端的原始信号波形
7、信号放大电路
图9差分放大器
CCD输出的有效信号OS是含有经过光积分的有效光电信号,而补偿信号DOS则反映了CCD的暗电流特性,也反映了CCD在复位脉冲的作用下信号传输沟道产生的容性干扰OS和DOS的理想输出波形,易看出两信号被RS容性干扰的相位是相同的,可以利用差分放大器完成信号的放大与抑制共模干扰作用.图9是OS和DOS在AD转换前的信号调理电路
8、信号的A/D转换
图10信号的AD转换显示的数据
STC12C5A单片机里面自带有10位AD转换,通过程序可以把信号进行处理,在1602液晶显示器显示出来。
本文介绍了光学传感器TCD1251UD的驱动电路及数据采集系统的设计方案和实现方法,从实验的结果来看,本设计能使TCD1251UD正常工作,产生稳定的输出信号,同时通过模、数转换电路得到的数据。
完成了中期的目标,为接下来的研究打下了坚实的基础。
附件
驱动程序:
#include
#include
sbitPA=P1^0;//时钟1
sbitPB=P1^1;//时钟2
sbitRS=P1^2;//复位脉冲
sbitSH=P1^3;//转移脉冲
unsignedintvalue_h,value_l;
voidtimerO()interrupt1using2
{
SH=0;
TH0=value_h;
TL0=value_l;
SH=1;
TH0=(65536-6050)/256;
TL0=(65536-6050)%256;
}
voidmain()
{
while
(1)
{
SH=0;
value_h=(65536-6500)/256;
value_l=(65536-6500)%256;
TMOD=0x01;////计数器0。
方式1
TH0=value_h;//
TL0=value_l;//;
EA=1;
ET0=1;
TR0=1;
P1=0x09;////初始状态A
do
{RS=1;
P1++;//状态C
_nop_();//状态D,与状态C相同
RS=0;//状态E
RS=1;//状态F
P1--;//状态G
}
while(_testbit_(RS));//状态H及状态A.状态H与G相同
}
}
AD转换的程序:
#include
#include
#include"adc.c"
sbitRS=P2^0;//寄存器选择位,将RS位定义为P2.0引脚
sbitRW=P2^1;//读写选择位,将RW位定义为P2.1引脚
sbitE=P2^2;//使能信号位,将E位定义为P2.2引脚
sbitBF=P0^7;//忙碌标志位,,将BF位定义为P0.7引脚
sbitS=P3^2;//将S位定义为P3.2引脚
unsignedcharcodedigit[]={"0123456789"};//定义字符数组显示数字
unsignedcharcodestring[]=
{"dianyaAD/DA"
};//定义字符数组显示提示信息
unsignedcharcodesudu[]={"v"};//定义字符数组显示提示信息
unsignedcharcount;//定义变量统计中断累计次数
//定义变量储存秒、分钟和小时
/*****************************************************
函数功能:
延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
voiddelay1ms()
{
unsignedchari,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:
延时若干毫秒
入口参数:
n
***************************************************/
voiddelay(unsignedcharn)
{
unsignedchari;
for(i=0;idelay1ms();
}
/*****************************************************
函数功能:
判断液晶模块的忙碌状态
返回值:
result。
result=1,忙碌;result=0,不忙
***************************************************/
unsignedcharBusyTest(void)
{
bitresult;
RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1;//E=1,才允许读写
_NOP_();//空操作
_NOP_();
_NOP_();
_NOP_();//空操作四个机器周期,给硬件反应时间
result=BF;//将忙碌标志电平赋给result
E=0;//将E恢复低电平
returnresult;
}
/*****************************************************
函数功能:
将模式设置指令或显示地址写入液晶模块
入口参数:
dictate
***************************************************/
voidWriteInstruction(unsignedchardictate)
{
while(BusyTest()==1);//如果忙就等待
RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,
//就是让E从0到1发生正跳变,所以应先置"0"
_NOP_();
_NOP_();//空操作两个机器周期,给硬件反应时间
P0=dictate;//将数据送入P0口,即写入指令或地址
_NOP_();
_NOP_();
_NOP_();
_NOP_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_NOP_();
_NOP_();
_NOP_();
_NOP_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:
指定字符显示的实际地址
入口参数:
x
***************************************************/
voidWriteAddress(unsignedcharx)
{
WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:
将数据(字符的标准ASCII码)写入液晶模块
入口参数:
y(为字符常量)
***************************************************/
voidWriteData(unsignedchary)
{
while(BusyTest()==1);
RS=1;//RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,
//就是让E从0到1发生正跳变,所以应先置"0"
P0=y;//将数据送入P0口,即将数据写入液晶模块
_NOP_();
_NOP_();
_NOP_();
_NOP_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_NOP_();
_NOP_();
_NOP_();
_NOP_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
voidzifu()
{
unsignedchari;
while(string[i]!
='\0')//只要没有显示到字符串的结束标志'\0',就继续
{
delay(5);
WriteData(string[i]);//将第i个字符数组元素写入LCD
i++;//指向下一个数组元素
}
}
/*****************************************************
函数功能:
显示小数点
***************************************************/
voiddisplay_dot(void)
{
WriteData('.');//将小数点的字符常量写入LCD
delay(50);//延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:
显示单位(v)
***************************************************/
voiddisplay_v(void)
{
unsignedchari;
WriteAddress(0x4e);//写显示地址,将在第2行第13列开始显示
i=0;//从第一个字符开始显示
while(sudu[i]!
='\0')//只要没有写到结束标志,就继续写
{
WriteData(sudu[i]);//将字符常量写入LCD
i++;//指向下一个字符
delay(100);//延时1ms给硬件一点反应时间
}
}
/*****************************************************
函数功能:
对LCD的显示模式进行初始化设置
***************************************************/
voidLcdInitiate(void)
{
delay(20);//延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction(0x38);//显示模式设置:
16×2显示,5×7点阵,8位数据接口
delay(10);//延时5ms ,给硬件一点反应时间
WriteInstruction(0x38);
delay(10);
WriteInstruction(0x38);//连续三次,确保初始化成功
delay(10);
WriteInstruction(0x0c);//显示模式设置:
显示开,无光标,光标不闪烁
delay(10);
WriteInstruction(0x06);//显示模式设置:
光标右移,字符不移
delay(10);
WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除
delay(10);
}
voidDisplaySecond(unsignedints)
{
unsignedchara,b,c,d;
a=ADC_Work()/1000;
b=ADC_Work()/100%10;
c=ADC_Work()/10%10;//取整运算,求得十位数字
d=ADC_Work()%10;//取余运算,求得各位数字
delay(5);
WriteAddress(0x45);//写显示地址,将十位数字显示在第2行第11列
delay(5);
WriteData(digit[a]);//将个位数字的字符常量写入LCD
delay(5);
WriteAddress(0x46);//写显示地址,将十位数字显示在第2行第11列
WriteData('.');
delay(5);
WriteData(digit[b]);//将十位数字的字符常量写入LCD
delay(5);
WriteData(digit[c]);//将个位数字的字符常量写入LCD
delay(5);
WriteData(digit[d]);//将十位数字的字符常量写入LCD
WriteAddress(0x4f);
WriteData('v');
}
voidmain()
{
LcdInitiate();
STC_ADC();
display_v;
zifu();
while
(1)
{
DisplaySecond(ADC_Work());
}
}