📄 p1.c
字号:
#include<reg52.h>
#include<intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned char
uchar IC_0,IC_1; //用于中断计数的变量
uchar flag; //标志,flag=1,INT0超前INT1;flag=0,INT0落后INT1;
uchar counter0=0; //TIMER0的中断计数变量,
uint timecount0=0; //
float circle_syn,circle_speed; //同步信号的周期,速度信号的周期;
float error_P; //两信号的相位差。
float critia_CP; //周期和相位的标准差;critia_C=circle_syn/2000百分之一,相差0.01ms的时间
uchar PWM=0x32; //占空比 PWM
uchar FPWM;
sbit out=P2^0;
uchar i,j;
/*********************************************************
延时函数
*********************************************************/
void Delay(uint num)//延时函数
{
while( --num );
}
void delayms(uchar ms)
{
uchar i;
while(ms--)
for(i=0;i<120;i++)
;
}
/********************************
/mian()函数
/*******************************/
main()
{
P1=0xff;
P2=0xff;
P3=0xff;
P3=0x00;
counter0=0;
timecount0=0;
TMOD=0x11;
TH0=0xff; //定时器0用来产生100HZ(0.1ms)的PWM波;
TL0=0xb2;
TH1=0x00; //定时器1用来计算同步信号的周期circle_syn,并受INT0和INT1的双重控制;
TL1=0x00;
T2CON=0x00; //定时器2用来计算速度信号的周期circle_speed, 不会让定时器2溢出
TH2=0x00;
TL2=0x00;
IT0=0; //下降沿触发 INT0中断
IT1=0; //下降沿触发 INT1中断
PX0=1;
EX1=1;
EX0=1;
EA=1;
ET0=1;
TR0=1;
TR1=0;
TR2=0;
while(1)
{
if(timecount0<50) //每20S周期的前5秒开INT0的中断允许,获取同步信号的周期 circle_syn;
EX0=1;
else
EX0=0;
//critia_CP=circle_syn/200.0; //取同步信号周期1/2000为标准差0.1ms
critia_CP=100.0;
if(fabs(circle_syn-circle_speed)>critia_CP)
{
if(circle_syn<circle_speed) //转速不够快,频率还不够大
{PWM++; Delay(500);}
else
{PWM--; Delay(500); }
}
else //此时两信号周期基本一致
{
if(error_P>critia_CP)
{
PWM++;
for(i=0;i<(error_P/2);i++) ;
PWM--;
for(j=0;j<(error_P/2);j++) ;
}
Delay(500);;
}
/*******************************************************************************************************/
/* if(circle_speed>circle_syn) //转速信号频率低, 加速
{ PWM++;Delay(2000);}
if((circle_speed-circle_syn)>50)
{PWM++;play();Delay(2000);}
//if((circle_speed-circle_syn)<150)
// FPWM=PWM; //固定此pwm值
// Delay(3000000);
}
while(fabs(circle_speed-circle_syn)<50)
{FPWM=PWM;Delay(2000);}
if(circle_speed<circle_syn) //转的快了 减速
{
PWM=FPWM;play();Delay(2000);
}
if(error_P>30)
{
PWM=FPWM+1; for(i=0;i<(error_P/2);i++) ;
PWM--; for(j=0;j<(error_P/2);j++) ;
PWM=FPWM;
}
*/
}
delayms(300);
}
/******************************************
/TIMER0 中断处理函数 中断号 1
/******************************************/
void Time0(void) interrupt 1 //
{
TH0=0xff; //0.1ms 定时
TL0=0xb2;
counter0++;
if(counter0<=PWM)
out=0;
else
out=1;
if(counter0==100) //10ms 到 为一个周期
{
counter0=0;
timecount0++;
}
if(timecount0==2000)
timecount0=0;
}
/******************************************
/TIMER1 中断处理函数 中断号 3 不能让timer1 产生中断
/******************************************/
void Time1(void) interrupt 3
{ TR1=0;
TH1=0x00; //初始化
TL1=0x00;
TR1=1;
}
/******************************************
/TIMER2 中断处理函数 中断号 5 不能让timer2 产生中断
/******************************************/
void Timer2() interrupt 5
{ TR2=0;
TF2=0; //清TF2标志
TH2=0x00;
TL2=0x00;
TR2=1;
}
/******************************************
/INT0 中断处理函数 中断号 0 获取同步信号的下降沿
/******************************************/
void INT_0(void) interrupt 0
{
IC_0++;
if(IC_0>IC_1)
flag=1;
else
flag=0;
switch(IC_0)
{
case 1: TR1=1; break;
case 2: TR1=0; circle_syn=TH1*256+TL1; TH1=0x00; TL1=0x00; break;
case 3: { if(flag==1) //同步信号超前,则启动定时器1
TR1=1;
else
{TR1=0;
error_P=TH1*256+TL1; //同步信号滞后时,可算出相位差error_P;
}
break;
}
case 4: TH1=0x00; TL1=0x00; IC_0=0; break;
default: break;
}
}
/******************************************
/INT1 中断处理函数 中断号 2 获取速度信号的下降沿,始终中断允许
/******************************************/
void INT_1(void) interrupt 2
{
IC_1++;
switch(IC_1)
{
case 1:TR2=1; break;
case 2:TR2=0; circle_speed=TH2*256+TL2; TH2=0x00; TL2=0x00; break;
case 3: {while(EX0==1) //只有INT0和INT1一起都中断允许的时候才执行
{
if(flag==0) //速度信号超前,方可控制 定时器1
TR1=1;
else
{
TR1=0;
error_P=TH1*256+TL1; //计算出两信号的相位差
}
}
;
break;
}
case 4: TH1=0x00; TL1=0x00; IC_1=0; break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -