该楼层涉嫌违规被系统折叠隐藏这栋楼,查看这栋楼
我用C语言Keil4上面写着一个程序,用遥控器控制步进电机,通过光阻模块限制步进电机的旋转范围,让遥控器控制步进电机的正反转,停止没有问题。单独让光敏电阻模块以波特率为9600来给出高低电平也没有问题,但现在我将这两个程序模块整合到一起之后,却出现了问题,要么就是遥控器控制步进电机正反转,停止没有问题,要么就是光敏电阻模块以波特率为9600来给出高低电平没有问题,要么就是都有问题,怀疑是两个定时器出现了干扰,但有不确定,我真的不知道该怎么办。以下是我给出的程序。请给我一些建议
#include
#define uchar unsigned char
#define uint unsigned int
unsigned char date;
sbit key1=P1^0;
sbit key2=P1^7;
signed long beats = 0; ///电机转动节拍总数
unsigned char T0RH = 0; //T0重载值高字节
unsigned char T0RL = 0; //T低字节0的低字节
unsigned char dir = 2;
unsigned char light = 1;
unsigned char sta = 0;
extern bit irflag;
extern unsigned char ircode[4];
extern void InitInfrared();
void delay(uint z);
void Initial_com(void);
void ConfigTimer0(unsigned int ms);
void RightRunMotor();
void LeftRunMotor();
void StopRunMotor();
unsigned char ReiverSta();
void main()
{
EA = 1; ///开总中断
InitInfrared(); //初始化红外功能
ConfigTimer0(2); //配置T0定时2ms
ReiverSta();
Initial_com(); if(RI)
{
date=SBUF; ///单片机接受
SBUF=date; ///单片机发送
RI=0;
}
if(TI)
{
TI = 0;
}
if(key2 == 0)
light = 1;
else
light = 0; */
while (1)
{
if (irflag) ///收到红外数据时刷新显示
{
irflag = 0;
switch(sta)
{
case 0:
StopRunMotor();
if(ircode[2] == 0x43)
{
dir = 1;
RightRunMotor();
}
else if(ircode[2] == 0x40)
{
}
else if(ircode[2] == 0x44)
{
}
break;
case 1:
if(ircode[2] == 0x43)
{
dir = 1;
RightRunMotor();
}
else if(ircode[2] == 0x40)
{
dir = 2;
LeftRunMotor();
}
else if(ircode[2] == 0x44)
{
StopRunMotor();
}
break;
case 2:
if(ircode[2] == 0x43)
{
dir = 1;
RightRunMotor();
}
else if(ircode[2] == 0x40)
{
dir = 2;
LeftRunMotor();
}
else if(ircode[2] == 0x44)
{
StopRunMotor();
}
break;
case 3:
StopRunMotor();
if(ircode[2] == 0x43)
{
}
else if(ircode[2] == 0x40)
{
dir = 2;
LeftRunMotor();
}
else if(ircode[2] == 0x44)
{
}
break;
default :break;
}
}
}
}
unsigned char ReiverSta()
{
unsigned char i = 0;
for(i=0; i<4; i )
{
switch(i)
{
case 0:
if((dir == 2) && (light == 1))
sta = 0;
else
break;
case 1:
if((dir == 1) && (light == 0))
sta = 1;
else
break;
case 2:
if((dir == 2) && (light == 0))
sta = 2;
else
break;
case 3:
if((dir == 1) && (light == 1))
sta = 3;
else
break;
}
}
return sta;
}
/* 步进电机启动函数,angle-角度需要转动 */
void RightRunMotor()
{
signed long angle = 360;
ET0 = 0;
beats = (angle * 4076) / 360; ///实测4076拍旋转
ET0 = 1;
}
void LeftRunMotor()
{
signed long angle = -360;
ET0 = 0;
beats = (angle * 4076) / 360; ///实测4076拍旋转
ET0 = 1;
}
/* 步进电机停止函数 */
void StopRunMotor()
{
ET0 = 0;
beats = 0;
ET0 = 1;
}
/*void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void Initial_com(void)
{
A=1; //开总中断
ES=1; //允许串口中断
ET1=1; //允许定时器T1的中断
TMOD=0x20; //定时器T1,在方式2中断产生波特率
PCON=0x00; //SMOD=0
SCON=0x50; // 方式1 由定时器控制
TH1=0xfd; //波特率设置为9600
TL1=0xfd;
TR1=1; //开定时器T1运行控制位
} */
/* 电机转动控制函数 */
void TurnMotor()
{
unsigned char tmp; //临时变量
static unsigned char index = 0; //节拍输出索引
unsigned char code BeatCode[8] = { //步进电机节拍对应的IO控制代码
0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
};
if (beats != 0) //节拍数不为0则产生一个驱动节拍
{
if (beats > 0) //节拍数大于0时正转
{
index++; //正转时节拍输出索引递增
index = index & 0x07; //用&操作实现到8归零
beats--; //正转时节拍计数递减
}
else //节拍数小于0时反转
{
index--; //反转时节拍输出索引递减
index = index & 0x07; //用&操作同样可以实现到-1时归7
beats++; //反转时节拍计数递增
}
tmp = P1; //用tmp把P1口当前值暂存
tmp = tmp & 0xF0; //用&操作清零低4位
tmp = tmp | BeatCode[index]; //用|操作把节拍代码写到低4位
P1 = tmp; //把低4位的节拍代码和高4位的原值送回P1
}
else //节拍数为0则关闭电机所有的相
{
P1 = P1 | 0x0F;
}
}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp; //临时变量
tmp = 11059200 / 12; //定时器计数频率
tmp = (tmp * ms) / 1000; //计算所需的计数值
tmp = 65536 - tmp; //计算定时器重载值
tmp = tmp + 13; //补偿中断响应延时造成的误差
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0为模式1
TH0 = T0RH; //加载T0重载值
TL0 = T0RL;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
}
/* T0中断服务函数,执行数码管扫描显示 */
void InterruptTimer0() interrupt 1
{
TH0 = T0RH; //重新加载重载值
TL0 = T0RL;
TurnMotor(); //执行电机驱动
}