|
各位高手,鄙人新手,用89c52做了个转速计,思路是通过测量两个信号之间的周期的方法来测算转速。具体做法是用外部中断0和定时器0,外部中断作为信号输入端,当外部中断产生第一次跳变为0时,启动定时器0.定时器开始计时1MS,1毫秒满溢出时,TF0清零,在赋初值 同时temp加1,当外部中断再次产生跳变为0时,关闭定时器,得到两个转速信号的时间temp.然后用60000(60秒*1000ms)除以temp得到RPM值,计算后将RPM值送数码管显示。实际试验的时候数码管有时候显示的 RPM是正确的 有时候会显示65535.而在外部中断中程式设计为:第一次收到外部中断信号的时候 LED点亮 外部中断再次收到中断信号的时候要关闭LED,单实际测试的时候RPM数值显示正确的时候LED却是一直点亮的,而显示值为65535的时候 LED灯却是在闪烁,程序或思路中定有不妥之处 恳请高人指点迷津 不胜感激
代代码如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit gewei=P1^7;
sbit shiwei=P1^6;
sbit baiwei=P1^5;
sbit qianwei=P1^4;
sbit wanwei=P1^3;
sbit led1=P2^0;
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e,0xff,};
uchar bai,shi,ge,i,qian,wan;
uint temp,rpm;
uchar l=0;
void init();
void main()
{
init();
while(1)
{
if(TF0==1) //定时器1计时满1MS 溢出
{
TF0=0; //TF0清零
TH0=(65536-960)/256; //定时器重新赋初值 定时1MS
TL0=(65536-960)%256;
temp++; //毫秒值累计
if(temp>=6000) //超过6秒无信号,数码管显示清零
{ //(10RPM以下值为无效值)
temp=0;
rpm=0;
TR0=0;
led1=1;
}
}
wan=rpm/10000%10; //计算万位值
qian=rpm/1000%10; //计算千位值
bai=rpm/100%10; //计算百位值
shi=rpm/10%10; //计算十位值
ge=rpm%10; //计算个位值
P1=0xff; //进入数码管扫描显示RPM值前关闭位显示
switch(l) //依此扫描显示RPM值
{
case 0:l++;P0=table[wan];wanwei=0;break;
case 1:l++;P0=table[qian];qianwei=0;break;
case 2:l++;P0=table[bai];baiwei=0;break;
case 3:l++;P0=table[shi];shiwei=0;break;
case 4:l=0;P0=table[ge];gewei=0;break;
}
}
}
void init() //初始化
{
temp=0;
rpm=0;
i=0;
EA=1;
TMOD=0x01;
EX0=1;
IT0=1;
}
void extimer0() interrupt 0
{
EA=0; //关闭总中断,停止定时器1
if(i==0) //外部中断第一次电平跳变
{
TH0=(65536-960)/256; //定时器重新赋初值 定时1MS
TL0=(65536-960)%256;
temp=0;
TR0=1; //开启定时器1
i=1; //i赋1
led1=0;
}
else //外部中断第二次电平跳变
{
TR0=0; //关闭启定时器1
rpm=(60000/temp); //计算RPM数值
i=0; //i清零
led1=1; //关闭LED灯
}
EA=1; //开启总中断
}
谢谢 !!
|
|