|
|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
各位大师麻烦帮忙看下这个程序是那里的问题,帮忙修改下,本人对程序是个小白这个程序是在网上找的,用来测试电机转速的,现在数码管显示正常只显示个位的0,但有霍尔转信号的时候数码管还是一直显示0,不显示转速。
#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_old = 0;
uint lock_cnt = 0;
//==== 切换参数(滞回防震荡)====
#define SWITCH_RPM 120
#define SWITCH_HYSTER 15
#define RPM_JUMP_LIMIT 40
//==== M/T法参数 ====
uint M_cnt;
uint T_cnt;
bit gate_flag;
bit wait_pulse;
#define GATE_MAX 750
#define TARGET_PULSE 3
//==== T法(周期测速)====
ulong t_period;
bit t_ready;
uint t_rpm_tmp;
uint mt_rpm_tmp;
#define HALL_TICK 8
#define STOP_TIMEOUT 200
#define RPM_MAX 9999
#define T_PERIOD_MAX 1500
uint stop_tick = 0;
uchar stop_flag = 0;
bit hall_last = 1;
uchar hall_timer = 0;
bit tick_2ms = 0; //2ms时标标记,定时器只置这个标志
//指数平滑滤波
uint filter_exp(uint new_val)
{
uint out;
out = (rpm * 7 + new_val * 3)/10;
return out;
}
//突变限幅防抖
uint jump_limit(uint new_val)
{
int diff;
diff = (int)new_val - (int)rpm;
if(diff > RPM_JUMP_LIMIT)
return rpm + RPM_JUMP_LIMIT;
if(diff < -RPM_JUMP_LIMIT)
return rpm - RPM_JUMP_LIMIT;
return new_val;
}
//【核心:滞回选择数据源】
uint select_rpm_src(uint t_val, uint mt_val)
{
if(rpm < (SWITCH_RPM - SWITCH_HYSTER))
{
return t_val;
}
if(rpm > (SWITCH_RPM + SWITCH_HYSTER))
{
return mt_val;
}
return rpm;
}
void calc_rpm(uint t_val, uint mt_val)
{
uint src_rpm;
uint rpm_tmp;
uint qian,bai,shi,ge;
src_rpm = select_rpm_src(t_val, mt_val);
rpm_tmp = jump_limit(src_rpm);
rpm_tmp = filter_exp(rpm_tmp);
rpm = rpm_tmp;
if(rpm == rpm_old)
{
lock_cnt++;
if(lock_cnt > 20) lock_cnt = 0;
}
else
{
lock_cnt = 0;
rpm_old = rpm;
}
if(rpm == 0)
{
disp_buf[0] = SEG_BLANK;
disp_buf[1] = SEG_BLANK;
disp_buf[2] = SEG_BLANK;
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;
if(disp_buf[2] == 0)
{
disp_buf[2] = SEG_BLANK;
}
}
}
}
}
void Timer0_Init(void)
{
TMOD |= 0x01;
TH0 = 0xF8;
TL0 = 0x30;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//定时器只产生2ms标志,不读霍尔!
void Timer0_ISR() interrupt 1
{
TH0 = 0xF8;
TL0 = 0x30;
tick_2ms = 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));
P3M1 &= ~(1<<5);
P3M0 &= ~(1<<5);
}
void disp_scan(void)
{
static uchar scan_cnt = 0;
sel0 = 1; sel1 = 1; sel2 = 1; sel3 = 1;
P1 = 0x00;
if(disp_buf[scan_cnt] != SEG_BLANK)
P1 = seg[disp_buf[scan_cnt]];
else
P1 = 0x00;
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;
}
void main(void)
{
stop_tick = 0;
stop_flag = 0;
M_cnt = 0;
T_cnt = 0;
gate_flag = 1;
wait_pulse = 0;
hall_last = 1;
hall_timer = 0;
rpm_old = 0;
lock_cnt = 0;
t_ready = 0;
t_period = 0;
t_rpm_tmp = 0;
mt_rpm_tmp = 0;
tick_2ms = 0;
calc_rpm(0,0);
IO_Init();
Timer0_Init();
while(1)
{
disp_scan();
//==== 2ms时标处理(定时器标记)====
if(tick_2ms)
{
tick_2ms = 0;
stop_tick ++;
if(t_ready == 0)
{
t_period++;
if(t_period > T_PERIOD_MAX)
{
t_period = 0;
t_ready = 0;
}
}
if(gate_flag == 1)
{
T_cnt ++;
if(T_cnt >= GATE_MAX && wait_pulse == 0)
{
wait_pulse = 1;
}
}
if(hall_timer > 0)
{
hall_timer--;
}
//停机超时归零
if(stop_tick >= STOP_TIMEOUT)
{
if(stop_flag == 0)
{
stop_flag = 1;
stop_tick = 0;
}
else
{
stop_flag = 0;
stop_tick = 0;
M_cnt = 0;
T_cnt = 0;
wait_pulse = 0;
t_ready = 0;
t_period = 0;
t_rpm_tmp = 0;
mt_rpm_tmp = 0;
calc_rpm(0,0);
}
}
}
//==== 主循环轮询霍尔边沿(和测试程序一样,不漏脉冲)====
if(hall_timer == 0)
{
if(hall_last == 1 && HALL_IN == 0)
{
stop_tick = 0;
stop_flag = 0;
//T法计算
if(t_ready == 1)
{
t_ready = 0;
if(t_period > 0)
{
t_rpm_tmp = 60000UL / (t_period * 2UL);
if(t_rpm_tmp > RPM_MAX) t_rpm_tmp = RPM_MAX;
calc_rpm(t_rpm_tmp, mt_rpm_tmp);
}
t_period = 0;
}
else
{
t_ready = 1;
t_period = 0;
}
//M/T脉冲计数
if(gate_flag == 1)
{
M_cnt ++;
if((M_cnt >= TARGET_PULSE) && (wait_pulse == 0))
{
wait_pulse = 1;
}
if(wait_pulse == 1)
{
ulong temp;
temp = (ulong)M_cnt * 30000UL / T_cnt;
if(temp > RPM_MAX) temp = RPM_MAX;
mt_rpm_tmp = (uint)temp;
calc_rpm(t_rpm_tmp, mt_rpm_tmp);
M_cnt = 0;
T_cnt = 0;
wait_pulse = 0;
}
}
hall_timer = HALL_TICK;
}
}
hall_last = HALL_IN;
}
}
#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_old = 0;
uint lock_cnt = 0;
//==== 切换参数(滞回防震荡)====
#define SWITCH_RPM 120
#define SWITCH_HYSTER 15
#define RPM_JUMP_LIMIT 40
//==== M/T法参数 ====
uint M_cnt;
uint T_cnt;
bit gate_flag;
bit wait_pulse;
#define GATE_MAX 750
#define TARGET_PULSE 3
//==== T法(周期测速)====
ulong t_period;
bit t_ready;
uint t_rpm_tmp;
uint mt_rpm_tmp;
#define HALL_TICK 8
#define STOP_TIMEOUT 200
#define RPM_MAX 9999
#define T_PERIOD_MAX 1500
uint stop_tick = 0;
uchar stop_flag = 0;
bit hall_last = 1;
uchar hall_timer = 0;
bit tick_2ms = 0; //2ms时标标记,定时器只置这个标志
//指数平滑滤波
uint filter_exp(uint new_val)
{
uint out;
out = (rpm * 7 + new_val * 3)/10;
return out;
}
//突变限幅防抖
uint jump_limit(uint new_val)
{
int diff;
diff = (int)new_val - (int)rpm;
if(diff > RPM_JUMP_LIMIT)
return rpm + RPM_JUMP_LIMIT;
if(diff < -RPM_JUMP_LIMIT)
return rpm - RPM_JUMP_LIMIT;
return new_val;
}
//【核心:滞回选择数据源】
uint select_rpm_src(uint t_val, uint mt_val)
{
if(rpm < (SWITCH_RPM - SWITCH_HYSTER))
{
return t_val;
}
if(rpm > (SWITCH_RPM + SWITCH_HYSTER))
{
return mt_val;
}
return rpm;
}
void calc_rpm(uint t_val, uint mt_val)
{
uint src_rpm;
uint rpm_tmp;
uint qian,bai,shi,ge;
src_rpm = select_rpm_src(t_val, mt_val);
rpm_tmp = jump_limit(src_rpm);
rpm_tmp = filter_exp(rpm_tmp);
rpm = rpm_tmp;
if(rpm == rpm_old)
{
lock_cnt++;
if(lock_cnt > 20) lock_cnt = 0;
}
else
{
lock_cnt = 0;
rpm_old = rpm;
}
if(rpm == 0)
{
disp_buf[0] = SEG_BLANK;
disp_buf[1] = SEG_BLANK;
disp_buf[2] = SEG_BLANK;
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;
if(disp_buf[2] == 0)
{
disp_buf[2] = SEG_BLANK;
}
}
}
}
}
void Timer0_Init(void)
{
TMOD |= 0x01;
TH0 = 0xF8;
TL0 = 0x30;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//定时器只产生2ms标志,不读霍尔!
void Timer0_ISR() interrupt 1
{
TH0 = 0xF8;
TL0 = 0x30;
tick_2ms = 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));
P3M1 &= ~(1<<5);
P3M0 &= ~(1<<5);
}
void disp_scan(void)
{
static uchar scan_cnt = 0;
sel0 = 1; sel1 = 1; sel2 = 1; sel3 = 1;
P1 = 0x00;
if(disp_buf[scan_cnt] != SEG_BLANK)
P1 = seg[disp_buf[scan_cnt]];
else
P1 = 0x00;
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;
}
void main(void)
{
stop_tick = 0;
stop_flag = 0;
M_cnt = 0;
T_cnt = 0;
gate_flag = 1;
wait_pulse = 0;
hall_last = 1;
hall_timer = 0;
rpm_old = 0;
lock_cnt = 0;
t_ready = 0;
t_period = 0;
t_rpm_tmp = 0;
mt_rpm_tmp = 0;
tick_2ms = 0;
calc_rpm(0,0);
IO_Init();
Timer0_Init();
while(1)
{
disp_scan();
//==== 2ms时标处理(定时器标记)====
if(tick_2ms)
{
tick_2ms = 0;
stop_tick ++;
if(t_ready == 0)
{
t_period++;
if(t_period > T_PERIOD_MAX)
{
t_period = 0;
t_ready = 0;
}
}
if(gate_flag == 1)
{
T_cnt ++;
if(T_cnt >= GATE_MAX && wait_pulse == 0)
{
wait_pulse = 1;
}
}
if(hall_timer > 0)
{
hall_timer--;
}
//停机超时归零
if(stop_tick >= STOP_TIMEOUT)
{
if(stop_flag == 0)
{
stop_flag = 1;
stop_tick = 0;
}
else
{
stop_flag = 0;
stop_tick = 0;
M_cnt = 0;
T_cnt = 0;
wait_pulse = 0;
t_ready = 0;
t_period = 0;
t_rpm_tmp = 0;
mt_rpm_tmp = 0;
calc_rpm(0,0);
}
}
}
//==== 主循环轮询霍尔边沿(和测试程序一样,不漏脉冲)====
if(hall_timer == 0)
{
if(hall_last == 1 && HALL_IN == 0)
{
stop_tick = 0;
stop_flag = 0;
//T法计算
if(t_ready == 1)
{
t_ready = 0;
if(t_period > 0)
{
t_rpm_tmp = 60000UL / (t_period * 2UL);
if(t_rpm_tmp > RPM_MAX) t_rpm_tmp = RPM_MAX;
calc_rpm(t_rpm_tmp, mt_rpm_tmp);
}
t_period = 0;
}
else
{
t_ready = 1;
t_period = 0;
}
//M/T脉冲计数
if(gate_flag == 1)
{
M_cnt ++;
if((M_cnt >= TARGET_PULSE) && (wait_pulse == 0))
{
wait_pulse = 1;
}
if(wait_pulse == 1)
{
ulong temp;
temp = (ulong)M_cnt * 30000UL / T_cnt;
if(temp > RPM_MAX) temp = RPM_MAX;
mt_rpm_tmp = (uint)temp;
calc_rpm(t_rpm_tmp, mt_rpm_tmp);
M_cnt = 0;
T_cnt = 0;
wait_pulse = 0;
}
}
hall_timer = HALL_TICK;
}
}
hall_last = HALL_IN;
}
}
|
|