stc89c52在keil中用C编程,写入 P1=0; 后程序运行结果就有错误,去掉P1=0;后就正常了,为什么?

#include<reg51.h>
//电机驱动物理接口
sbit M1EN = P1^0;
sbit M1A = P1^1;
sbit M1B = P1^2;
sbit M2EN = P1^3;
sbit M2A = P1^4;
sbit M2B = P1^5;
//马达测速信号线的物理接口定义
sbit mtspd1_sig = P1^6;
sbit mtspd2_sig = P1^7;
/*避障传感器接口
sbit OBS
*/
//中断中要使用的全局变量,用以计算中断次数
unsigned char flag2=0;
unsigned char flag1=0;
//占空比;数值为0~9
unsigned char duty_ratio1=0;
unsigned char duty_ratio2=0;
//初始化:包括对两个定时器的初始化,用来产生pwm信号;初始化各管脚;
void init_source()
{
//计数器初始化,两个计数器均工作在模式2,计数范围为156~256(100)
TMOD=0x22;
TL0=156;
TH0=156;
TL1=156;
TH1=156;
//各管脚初始化,初值都为零
/* P0=0;
P1=0xff;
P2=0;
P3=0;
*/
//对测速信号管脚初始化高电平
mtspd1_sig=1;
mtspd2_sig=1;
//开计数器
TR0=1;
TR1=1;
}
//计数器0中断子程序,为moto1提供pwm信号
void timer0(void) interrupt 1
{
if(flag1==0)
{
M1EN=1;
}
if( flag1 == duty_ratio1 )
{
M1EN=0;
}
flag1++;
if( flag1 >= 9 )
{
flag1=0;
}

}
//计数器1中断子程序,为moto2提供pwm信号
void timer1(void) interrupt 3
{
if(flag2==0)
{
M2EN=1;
}
if( flag2 == duty_ratio2 )
{
M2EN=0;
}
flag2++;
if( flag2 >= 9 )
{
flag2=0;
}

}
//moto速度设置,参数s1、s2范围为-9~+9,小于0时表示马达反转,大于0时表示马达正转
void speed_set(int s1, int s2)
{
if( s1>0 && s1<10)
{
M1A=1;
M1B=0;
duty_ratio1=s1;
}
if( s1<0 && s1>-10 )
{
M1A=0;
M1B=1;
duty_ratio1=-s1;
}
if( s2>0 && s2<10)
{
M2A=1;
M2B=0;
duty_ratio2=s2;
}
if( s2<0 && s2>-10 )
{
M2A=0;
M2B=1;
duty_ratio2=-s2;
}
}
//根据码盘转动速度,得到小车一侧行驶速度
//假设自加操作占用一个机器周期,速度公式为148000/t(机器周期) cm/s
float get_mtspd1()
{
int flag;
int t;
flag = mtspd1_sig;
while( flag == mtspd1_sig);
flag = mtspd1_sig ;
while( flag == mtspd1_sig)
{
t++;
}
flag = mtspd1_sig;
while( flag == mtspd1_sig )
{
t++;
}
return ( 148000/t );
}
float get_mtspd2()
{
int flag;
int t;
flag = mtspd2_sig;
while( flag == mtspd2_sig);
flag = mtspd2_sig ;
while( flag == mtspd2_sig)
{
t++;
}
flag = mtspd2_sig ;
while( flag == mtspd2_sig )
{
t++;
}
return ( 148000/t );
}
void main()
{
init_source();
speed_set(0,7);
}
这个是可以用的版本,PWM控制小车电机,废话不多说了
具体看init_source()函数里的 各管脚初始化 ,把下面那个注释号去掉运行结果就会出错!为什么?
void init_source()
{
//计数器初始化,两个计数器均工作在模式2,计数范围为156~256(100)
TMOD=0x22;
TL0=156;
TH0=156;
TL1=156;
TH1=156;
//各管脚初始化,初值都为零
/* 把这里的注释号去掉,就会有错
P0=0;
P1=0xff;
P2=0;
P3=0;
*/
//对测速信号管脚初始化高电平
mtspd1_sig=1;
mtspd2_sig=1;
//开计数器
TR0=1;
TR1=1;
}

void main()
{
init_source();
speed_set(0,7);
}
这种写法会让单片机反复执行这两句,也就是会不断的初始化.
建议写成这种结构
void main()
{
初始化代码();
while(1)
{
speed_set(0,7);
}
}

PS:P1 = 0;写法是正确的.
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-01-18
因为P1不认得十进制,要用十六进制赋值。比如要想把0送到P1口,应该这样写P1=0x00;你上面的意思是p1口低电平有效,要想把端口清零从零开始,就要把P1口全部变为高电平,即P1的8个脚二六进制为11111111,十六进制就应该是0xff。