在书上看到的红外线转速仪的程序,想知道如何确定转速测量的范围。求高手相助!
//ICC-AVR application builder : 2007-9-20 10:30:53
// Target : m16
// Crystal: 8.0000Mhz
#include <iom16v.h>
#include <macros.h>
#include "head.h"
#define uchar unsigned char
#define uint unsigned int
#define xtal 8
extern void WaitForEnable(void);
extern void LcdWriteData(uchar W);
extern void LcdWriteCommand(uchar CMD,uchar Attribc);
extern void InitLcd(void);
extern void Display(uchar dd);
extern void DisplayOneChar(uchar x,uchar y,uchar Wdata);
extern void ePutstr(uchar x,uchar y,uchar const *ptr);
uchar Start=0,WorkFlag;
uint WorkTime,DisTime,Counter;
uint DisVal;
uint cnt;
uchar Flag,IntFlag,JS=0;
uint tx,cx;
uint disx[4];
uchar DisFlag=1,EndFlag,BeginFlag=0;
const uchar cs0[]={"ShangHai"};//欢迎界面
const uchar cs1[]={"-Tester-"};//欢迎界面
const uchar cs2[]={"Testing-"};//测试界面
const uchar dsp[]={"RPM: "};//测试界面
//TIMER2 initialize - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value: 1.000mSec (0.0%)
void timer2_init(void)
{
TCCR2 = 0x00; //stop
ASSR = 0x00; //set async mode
TCNT2 = 0x83; //setup
OCR2 = 0x7D;
TCCR2 = 0x04; //start
}
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0xFF;
DDRD = 0xFF;
DDRD = 0x63;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer2_init();
MCUCR = 0x01;
GICR = 0x40;
TIMSK = 0x40; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
/**********************欢迎界面********************/
void display1(void)
{
LcdWriteCommand(0x01,1); //清屏,检测忙信号
ePutstr(0,0,cs0);
ePutstr(0,1,cs1);
}
void display2(void)
{
LcdWriteCommand(0x01,1); //清屏,检测忙信号
ePutstr(0,0,cs2);
ePutstr(0,1,dsp);
}
//****************************************
void Delay_1ms(void) //1mS延时子函数
{ uint i;
for(i=1;i<(uint)(xtal*124);i++)
;
}
//=============================================
void Delay_nms(uint n) //n*1mS延时子函数
{
uint i=0;
while(i<n)
{Delay_1ms();WDR();
i++;
}
}
/**********************主函数*****************************/
void main(void)
{ uchar temp;
float count,time,x;
Delay_nms(400);
init_devices();
InitLcd();
display1(); //显示Test界面
Delay_nms(2000);
display2(); //显示Work状态
DisFlag=1;
/********************************************/
while(1) //无限循环
{ WDR();
if(DisFlag==1)//如果显示标志为1
{
time=(float)tx;count=(float)cx;
x=count/time;x=x*30000;DisVal=(uint)x;//数学计算
disx[3]=(DisVal/1000)%10;disx[2]=(DisVal/100)%10;
disx[1]=(DisVal%100)/10;disx[0]=DisVal%10;
DisplayOneChar(4,1,disx[3]+0x30);//显示数据
DisplayOneChar(5,1,disx[2]+0x30);
DisplayOneChar(6,1,disx[1]+0x30);
DisplayOneChar(7,1,disx[0]+0x30);
DisFlag=0;WorkTime=0;DisTime=0;EndFlag=0;
Start=0;cnt=0;
}
else //否则进行取样
{
do{temp=PIND&0x04;WDR();JS=1;//等待下降沿后下一次测试
if(Counter>1500){Counter=0;JS=0;DisFlag=1;cx=0;goto END;}
}
while(temp==0x04);
BeginFlag=1;Start=1;GICR=0x40;//重开INT0
END:;
}
}
}
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
TCNT2 = 0x83; //reload counter value
SEI();
if(BeginFlag==1)
{
DisTime++;
if(DisTime>1300){DisFlag=1;DisTime=0;BeginFlag=0;} //开显示
}
if(Start==1){WorkTime++;}
if(WorkTime==1000){EndFlag=1;}
if(JS==1)Counter++;
}
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
uchar y;
SEI();
//external interupt on INT0
y=PIND&0x04;
JS=0;Counter=0;
if((Start==1)&&(y==0x00))cnt++;
//**********************
if((Start==1)&&(y==0x04))
{
cnt++;
if(EndFlag==1){tx=WorkTime;cx=cnt;EndFlag=0;
Start=0;GICR=0x00;}//关闭INT0中断
}
}
|