刚接触单片机没多久,弄了一个实验,用红外避障模块,控制一个舵机转指定的角度(代码是从网上找的)。正常情况下当检测到红外信号时,舵机转到90度,没有检测到就转到0度。问题出在延时那里,用了延时后,当检测到信号舵机转到90度,没有信号后却不能回归0度了。用 Keil uVision5调试程序是正常执行的,会经过延时函数到达servo = PWM(5)。百思不得其解,请各位帮忙看看,是代码有问题么?用的单片机是STC15F104W,stc-isp版本是v6.88i,代码编写用的 Keil uVision5。
#include <STC15F104E.H>
#define PWM_T 200 //产生中断的时间,因为是24MHz,200即100微妙(0.1毫秒)
int PWM_count0 = 0; //进入中断的次数
int PWM_count1 = 0; //与上面的类似,用于计数
int PWM_F = 0; //一个用于计时的标志,作用类似定时器的TF0、TF1
int YS = 0;
sbit servo = P3^3; //舵机信号线所连接的IO口
sbit ceju=P3^2; // 红外检测信号
int count; //中断次数变量
bit flag = 0; //标志时间结束
void PWM_Start() //PWM初始化函数,打开了定时器0
{ EA = 1;
ET0 = 1;
TMOD |= 0x01;
TR0 = 1;
TH0 = (65536-PWM_T)/256;
TL0 = (65536-PWM_T)%256;
}
int PWM(int PWM_value) //控制PWM输出的子函数
{ if(PWM_count0 <= PWM_value)
{ return 1;
}
else { return 0;
}
}
void Delay1000ms() //@24.000MHz STC官方的例子
{
unsigned char i, j, k;
i = 92;
j = 50;
k = 238;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{ PWM_Start(); //PWM开始运行
while(1) {
if(ceju == 0)
{ servo = PWM(15); //旋转至90°
}
else
{
//Delay1000ms(); //这一句保留就会出问题
servo = PWM(5); //旋转至0°
}
}
}
void Timer0() interrupt 1
{ TH0 = (65536-PWM_T)/256;
TL0 = (65536-PWM_T)%256;
PWM_count0++;
if(PWM_count0 == 200) //过了20ms,完成了一个PWM周期
{ PWM_count0 = 0; //清零,重新开始计数
PWM_count1++;
if(PWM_count1 == 50) //PWM_count0清零了50次,也就是说过了20ms*50=1000ms=1s
{ PWM_count1 = 0; //清零,重新开始计数
PWM_F = 1; //标志置1,说明已经过了2s
}
}
}