|
|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
各位大师麻烦帮我看下这个程序是那里的问题,用stc11f02e做一个测量电机转速的转速表,现在4位数码管显示4个0正常,但一有转速脉冲就乱显基本显示几个固定的数字比如75 1160 3350 6600等,转速很低都乱显,用的是光电传感器,#include <reg51.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
sbit sel0 = P3^2;
sbit sel1 = P3^3;
sbit sel2 = P3^4;
sbit sel3 = P3^7;
sbit HALL_IN = P3^5; //霍尔输入
uchar code seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
#define SEG_BLANK 0xFF
uchar disp_buf[4];
uint rpm = 0;
uint rpm_last = 0;
uchar scan_cnt = 0;
uint time_cnt = 0;
uint pulse_cnt = 0;
uint buf[8];
uchar buf_idx = 0;
bit calc_flag = 0;
bit hall_last = 1;
uchar hall_timer = 0; //消抖计时
#define RPM_MAX 9999
#define STEP_LIMIT 150
#define HALL_TICK 10 //消抖需要的计时刻度
void short_delay(void)
{
uchar i;
for(i=5;i>0;i--);
}
void delay_ms(uint t)
{
uint i,j;
for(i=t;i>0;i--)
for(j=110;j>0;j--);
}
void clear_filter_buf(void)
{
uchar i;
for(i=0;i<8;i++) buf=0;
buf_idx = 0;
}
// T0 2ms定时,数码扫描 + 系统计时 11.0592M
void Timer0_Init(void)
{
TMOD |= 0x01;
TH0 = 0xF8;
TL0 = 0x30;
ET0 = 1;
TR0 = 1;
EA = 1;
}
uint filter(uint val)
{
uint sum=0,i;
buf[buf_idx++] = val;
if(buf_idx>=8) buf_idx=0;
for(i=0;i<8;i++) sum += buf;
return sum>>3;
}
void calc_rpm()
{
uint rpm_tmp;
uint qian,bai,shi,ge;
rpm_tmp = pulse_cnt * 600;
if( (rpm_tmp > rpm_last + STEP_LIMIT) && (rpm_last != 0) )
{
rpm_tmp = rpm_last;
}
else
{
rpm_last = rpm_tmp;
}
rpm = filter(rpm_tmp);
pulse_cnt = 0;
if(rpm > RPM_MAX)
{
disp_buf[0] = SEG_BLANK;
disp_buf[1] = SEG_BLANK;
disp_buf[2] = SEG_BLANK;
disp_buf[3] = SEG_BLANK;
}
else if(rpm == 0)
{
disp_buf[0] = 0;
disp_buf[1] = 0;
disp_buf[2] = 0;
disp_buf[3] = 0;
}
else
{
qian = rpm / 1000;
bai = (rpm / 100) % 10;
shi = (rpm / 10) % 10;
ge = rpm % 10;
disp_buf[0] = qian;
disp_buf[1] = bai;
disp_buf[2] = shi;
disp_buf[3] = ge;
if(disp_buf[0]==0)
{
disp_buf[0]=SEG_BLANK;
if(disp_buf[1]==0)
{
disp_buf[1]=SEG_BLANK;
}
}
}
}
void Timer0_ISR() interrupt 1
{
TH0 = 0xF8;
TL0 = 0x30;
time_cnt++;
//==== 无阻塞计时消抖捕获下降沿,中断里没有延时!====
if(hall_timer > 0)
{
hall_timer--;
}
else
{
if(hall_last == 1 && HALL_IN == 0)
{
pulse_cnt++;
hall_timer = HALL_TICK; //锁定,一段时间内不再响应,防止连续误触发
}
hall_last = HALL_IN;
}
//数码管扫描
sel0 = 1;
sel1 = 1;
sel2 = 1;
sel3 = 1;
P1 = 0x00;
short_delay();
if(disp_buf[scan_cnt] != SEG_BLANK)
P1 = seg[disp_buf[scan_cnt]];
else
P1 = 0x00;
short_delay();
switch(scan_cnt)
{
case 0: sel0 = 0; break;
case 1: sel1 = 0; break;
case 2: sel2 = 0; break;
case 3: sel3 = 0; break;
}
scan_cnt++;
if(scan_cnt>=4) scan_cnt=0;
if(time_cnt>=50)
{
time_cnt=0;
calc_flag = 1;
}
}
void IO_Init(void)
{
P1M1 = 0x00;
P1M0 = 0xFF;
//位选脚推挽输出
P3M1 &= ~((1<<2)|(1<<3)|(1<<4)|(1<<7));
P3M0 |= ((1<<2)|(1<<3)|(1<<4)|(1<<7));
//P3.5 高阻输入,不推挽
P3M1 &= ~(1<<5);
P3M0 &= ~(1<<5);
}
void main(void)
{
pulse_cnt = 0;
time_cnt = 0;
rpm_last = 0;
hall_last = 1;
hall_timer = 0;
clear_filter_buf();
IO_Init();
delay_ms(600);
Timer0_Init();
while(1)
{
if(calc_flag == 1)
{
calc_flag = 0;
calc_rpm();
}
}
}
|
|