这是个超声波测距的程序,太长了。我就贴出相关的程序出来。其中红色的部分不是很理解。为什么是65536-(ICP_lastValue+1+ICP_value )。
//==========================定时器1初始化子程序=============================
void timer1_init(void)
{
TCNT1 = 0x00; //定时0ms的初始值
TCCR1A = 0x00;
TCCR1B = 0x42; //上升沿捕获,时钟8预分频
}
//============================设备初始化子程序==============================
void init_devices(void)
{
timer1_init();
InitLcd(); //LCD初始化
TIMSK = 0x20; //使能T/C1的捕获中断
SREG = 0x80; //使能总中断
}
//=============启动超声波发送==================
void send(void)
{
unsigned char k;
Trig = 1; //触发口拉高电平
for(k=0;k<50;k++); //延时大于10us
Trig = 0; //触发口拉低电平
}
//==================主函数=====================
void main(void)
{
DDRA=0xff;PORTA=0x00;
DDRB=0xff;PORTB=0x00;
DDRC=0xff;PORTC=0xff;
DDRD=0x00;PORTD=0xff; //初始化I/O口,其中ICP1口(PD6)必须设置成输入形式
init_devices(); //设备初始化
ePutstr(0,0,str0); //第一行显示红外数据宽度(格式)
while(1)
{
send(); //启动一次超声波发送
delay_nms(10);
DisplayOneChar(12,0,times%10+0x30); //显示距离的个位
delay_nms(10);
DisplayOneChar(11,0,(times/10)%10+0x30); //显示距离的十位
delay_nms(10);
DisplayOneChar(10,0,times/100+0x30); //显示距离的百位
delay_nms(50);
}
}
//===================中断函数(定时器1输入捕获中断)=============================
#pragma vector = TIMER1_CAPT_vect
__interrupt void TIMER1_CAPT_Server(void)
{
if(TCCR1B_Bit6==1) //若捕获的是上升沿
{
ICP_lastValue=ICR1; //读取ICP输入捕捉上升沿的发生时刻
TCCR1B_Bit6 = 0; //改为下降沿捕获
}
else //若捕获的是下降沿
{
ICP_value=ICR1; //读取ICP输入捕捉下降沿的发生时刻
TCCR1B_Bit6 = 1; //改为上升沿捕获
if(ICP_lastValue>ICP_value)
times=0xffff-ICP_lastValue+1+ICP_value;
else
times=ICP_value-ICP_lastValue; //计算高电平的宽度
times=times/58; //把us换算成cm
}
}
|