献上此程序,仅抛砖引玉
======================================================================================================
该程序由本人设计,已经用于毒蛇定时器测速功能中,测试正常,成功测量到327.8米每秒的子弹速度(我的改火气枪没法打出来速度再高的子弹,探头使用光电阵列)。
======================================================================================================
主要特点及说明:
1 该程序具有快的反应速度,当单片机运行于8MHz时只要信号持续时间不低于0.25us就能被检测到,运行于1Mhz时,信号持续时间不低于2us就能被检测到。
2 使用双管脚进行测量,实践证明具有良好的分辨能力,抗干扰效果极好。
3 使用的是软件查询方式,响应时间比中断迅速。单片机运行于8MHz时误差不大于0.25us,运行于1Mhz时,误差为不大于2us。
4 长时间无信号,自动退出功能。
5 如用于测量子弹速度,单片机运行于8Mhz,间隔取20厘米,子弹长6mm,测量速度最小10米每秒左右,最大速度6500米每秒(假设探测器分辨最小时间是0.25us)。
=======================================================================================================
使用单片机:ATmega32L (其实很容易改到51上运行)
使用资源:T0定时器
/******************************************************************************
单片机运行于2Mhz,经校正。
子弹穿越传感器间隔示意图
--------------------------------------------------------------------------------------
||||||| |||||||
子弹=>
||||||| |||||||
第一个光电阵列 第一个光电阵列
------------------------------------------------------------------------------------------
测量子弹是以低电平驱动的,平时没有穿越那就高电平,测量波形示意图如下:
[s:9]D4 _______ __________________________子弹先挡住第一个光电阵列产生一个低电平
|______|
^
t1
[s:9]D5__________________ ________________子弹先挡住第二个光电阵列又产生一个低电平
|______|
^
t2
测量时间dt=t2-t1
PD4在前,PD5在后,也就是说子弹先产生信号在PD4,然后是PD6
******************************************************************************/
unsigned long BullettimeDetect( void )
{
unsigned long time;
unsigned int round=1;
unsigned char count0=0;
unsigned char d1,p1;
d1 = DDRD; //保存和设置管脚
p1 = PORTD;
[s:9]ORTD &= 0b11001111;
DDRD &= 0b11001111;
TCCR0 = 0x00; //设置定时工作方式
TIMSK &= 0xFE;
TCNT0 = 0x00 ;
TIFR |= 0x01;
/////////////////////////////////////////////////////////////////////
while( PIND&0x10 ); //等待低电平,触发PD4管脚,相当于断开连接,执行这条指令只需要1us@2Mhz(0.5uS@4MHz,0.25uS@8Mhz)
TCCR0 = 0x01; //开始计数,每计数一次表示0.5uS@2Mhz(0.25uS@4MHz,0.125uS@8Mhz)
//如果采用高精度石英晶体,则时间精度会更好。
while( PIND&0x20 ) //等待PD5第二个低电平,执行这条指令只需要1us@2Mhz(0.5uS@4MHz,0.25uS@8Mhz)
{
if( TIFR&0x01 )
{
round++;
TIFR |= 0x01;
if(round==0)break;//超时自动退出,防止死机
}
}
/////////////////////////////////////////////////////////////////////
TCCR0 = 0x00; //停止计数
count0=TCNT0;
if( TIFR&0x01 ) //防止丢失一次溢出
{
round++;
TIFR |= 0x01;
}
time = round-1;//由于从1开始的,所以要减一
time <<=8;
time +=count0;
PORTD=p1; DDRD=d1; //还原管脚设置
TIMSK |= 0x01; //还原定时器状态
TCCR0 = 0x00;
TCNT0 = 0xD9;
OCR0 = 0x27;
return time; //返回测量时间计数值
}
///////////////////////////////时间间隔捕捉驱动程序/////////////////////////////
200字以内,仅用于支线交流,主线讨论请采用回复功能。