📄 电机测速.c
字号:
#include<reg52.h>
sbit a4=P2^4;
sbit a5=P2^5;
sbit a6=P2^6;
sbit z0=P3^6; //正转口//
sbit z1=P3^7; //反转口//
unsigned char i,j,k,l,m,n;
unsigned char key,count,flag=0,flag_1,flag_2=1,flag_3=0,flag_4=0,num[8];
unsigned int shijian=0,mc=0,t,rps_int=0,time=0,time_1=0,hol=1; //shijian是产生mc个脉冲用的时间;time总时间;rps电机实际速度//
float rps=0.0,v,dv,dv_1,dv_2; //设置的速度v//
void delay(count) //延时count MS//
{
for(i=0;i<count;i++)
for(j=0;j<125;j++);
}
unsigned char KEYZHI() //按键扫描程序//
{
k=0;
while(k==0) //扫描//
{
do
{ P1=0xf0; }
while ((0xf0&P1)==0xf0) ; //有按下?有则跳出do……while循环//
delay(5); //延时,防干扰//
if((0xf0&P1)==0xf0) k=0; //真的按下去了吗?延时后再作判断//
else k=1;
}
P1=0x0f;
switch(P1) //扫描行,得出行号j//
{
case 0x0e: j=0;break;
case 0x0d: j=1;break;
case 0x0b: j=2;break;
case 0x07: j=3;break;
default: break;
}
P1=0xf0; //扫描列,得出列号i//
switch(P1)
{
case 0xe0: i=0;break;
case 0xd0: i=1;break;
case 0xb0: i=2;break;
case 0x70: i=3;break;
default: break;
}
return(i+j*4); //返回键值,供下面作数据处理//
}
void DF() //等待按键释放程序//
{
n=0;
while(n==0)
{
do
{ P1=0x0f; }
while((0x0f&P1)!=0x0f); //等待按键释放,即若没有放开则一直循环//
delay(5); //放开键后消抖//
P1=0x0f;
if((0x0f&P1)!=0x0f) //真的放开了吗?延时后再次判断//
n=0;
else
n=1;
}
}
void Int0(void) interrupt 0 //外部中断0 测脉冲个数//
{
mc++; //脉冲累加//
TR1=1; //定时器1启动//
// if(flag==1) //测周入口//
// {
// if(flag_1==1){TH1=0x00;TL1=0x00;shijian=0;mc=0;flag_1=0;} //第一mc进来 准备测周 时间清零//
//
// else
// {
// TR1=0;rps=1000000/(13.0*((TH1<<8)+TL1));
// dv=v-rps;
// t=t+114*dv;
// rps_int=100*rps;
// num[7]=rps_int%10;
// num[6]=(rps_int/10)%10;
// num[5]=(rps_int/100)%10;
// num[4]=(rps_int/1000)%10;
// }
// }
}
void Int1(void) interrupt 2 //外部中断1 自动//
{
// time_1=0; dv=0; t=13667;
// if(time_1==100) t=12080;
// if(time_1==200) t=50000;
if(flag_4==0) {t=13667;flag_4=1;}
else
{
if(flag_4==1){t=12080;flag_4=2;}
else {t=50000;flag_4==0;}
}
}
void Timer0(void) interrupt 1 //定时器0中断 产生PWM波 使电机转动//
{
switch(l*2+hol)
{
case 0: TH0=(65536-t)>>8; TL0=(65536-t)-(((65536-t)>>8)<<8);z1=0; z0=1; hol=1; break; //正转 高电平//
case 1: TH0=(15536+t)>>8; TL0=(15536+t)-(((15536+t)>>8)<<8);z1=0; z0=0; hol=0; break; //正转 低电平//
case 2: TH0=(65536-t)>>8; TL0=(65536-t)-(((65536-t)>>8)<<8);z0=0; z1=1; hol=1; break; //反转 高电平//
case 3: TH0=(15536+t)>>8; TL0=(15536+t)-(((15536+t)>>8)<<8);z0=0; z1=0; hol=0; break; //反转 低电平//
}
}
void Timer1(void) interrupt 3 //定时器1中断 计时50MS一次//
{
TH1=0x3c;
TL1=0xaf;
shijian=shijian+1;
time_1=time_1+1;
if(shijian==1)
{
// if(mc/2.4<42) { flag=1; flag_1=1;} //低速区 测周//
// else //高速区 测频//
// {
rps=mc/0.65;
rps_int=10*rps;
num[7]=rps_int%10;
num[6]=(rps_int/10)%10;
num[5]=(rps_int/100)%10;
num[4]=(rps_int/1000)%10;
dv=v-rps;
if(flag_3==0){dv_1=dv;flag_3=1;}
else {dv_2=dv;flag_3=0;}
t=t+8*dv+0.7*(dv_1-dv_2);
shijian=0;
mc=0;
// }
}
}
void Timer2(void) interrupt 5 //定时器2中断 选通及显示//
{
TH2=0xf8 ;
TL2=0x2f ;
m=P2;
m=0x70 & m; //m为位选通变量//
switch(m) //扫描显示;a6,a5,a4为下次选通先给P2高位赋值//
{
case 0x60 : P2=num[7];a6=1; a5=1; a4=1; break;
case 0x70 : P2=num[0];a6=0; a5=0; a4=0; break;
case 0x00 : P2=num[1];a6=0; a5=0; a4=1; break;
case 0x10 : P2=num[2];a6=0; a5=1; a4=0; break;
case 0x20 : P2=num[3];a6=0; a5=1; a4=1; break;
case 0x30 : P2=num[4];a6=1; a5=0; a4=0; break;
case 0x40 : P2=num[5];a6=1; a5=0; a4=1; break;
case 0x50 : P2=num[6];a6=1; a5=1; a4=0; break;
}
}
void main()
{ //
TMOD=0X11; //
EA=1; //
EX0=1; //外部中断0打开//
EX1=0; //外部中断1//
IT0=1; // 设置电平触发方式//
ET0=1; //
ET1=1; //
ET2=1; //
TR0=0; //
TR1=0;
TR2=1;
TH0=0xc5;
TL0=0x67;
TH1=0x3c;
TL1=0xaf;
CP_RL2=1;
C_T2=0;
EXEN2=0;
TH2=0xf8 ;
TL2=0x2f ;
for(i=0;i<=7;i++)
num[i]=0;
while(1)
{
P1=0x0f;
key=KEYZHI();
DF();
switch(key)
{
case 10 : l=0;TR0=1;flag_2=0;break;
case 11 : l=1;TR0=1;flag_2=0;break;
case 12 : if(flag_2==1){TR0=1;flag_2=0;}
else {z0=0;z1=0;TR0=0;flag_2=1;}
break;
case 13 : num[0]=0;num[1]=0;num[2]=0;num[3]=0;break;
case 14 : EX1=1;TR0=1;flag_2=0;break;
case 15 : time=time_1/20;
num[0]=(time/60)/10;
num[1]=(time/60)%10;
num[2]=(time%60)/10;
num[3]=(time%60)%10;
break;
default : for(i=0;i<3;i++)
{ j=i+1; num[i]=num[j]; }
num[3]=key; break; //前4个数码管显示设置的速度值//
}
v=100*num[0]+10*num[1]+num[2]+0.1*num[3];
t=226.7*v+11400;
// rps_int=10*rps;
// num[7]=rps_int%10;
// num[6]=(rps_int/10)%10;
// num[5]=(rps_int/100)%10;
// num[4]=(rps_int/1000)%10;
// dv=v-rps;
// t=t+114*dv;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -