舵机问题请教各位前辈
时间:10-02
整理:3721RD
点击:
用51定时输出pwm; 红外对管检测; 舵机不能正确转动 是什么原因 是延时的问题还是什么问题 延时一般按照什么给;
程序如下:
/*51单片机控制小车 红外对管循迹*/
#include<reg52.h>
#define TH1_TL1 (65536-92) //设定定时器1中断的间隔时长
#define TH0_TL0 (65535-92) //设定定时器1中断的间隔时长
#define uchar unsigned char
uchar DIJ_sd = 40;//电机初始速度
uchar DIJ_count = 0;//电机速度比较用的临时变量
uchar DIJ_time_delay; //电机延时变量
uchar DUJ_jd=18; //舵机初始角度90
uchar DUJ_count=0; //电机角度值比较零时变量
uchar DUJ_time_delay; //舵机延时变量
bit Flag_turn = 1; //电机正反转标志位,1正转,0反转
bit Flag_duj; //舵机一个脉冲结束标记
sbit PWM1=P1^1; //PWM 通道 1,反转脉冲
sbit PWM2=P1^2; //PWM 通道 2,正转脉冲
sbit PWM3=P1^3; //PWM通道3,舵机脉冲
unsigned char DG;
/*sbit D1=P2^0; //8个红外对管检测
sbit D2=P2^1;
sbit D3=P2^2;
sbit D4=P2^3;
sbit D5=P2^4;
sbit D6=P2^5;
sbit D7=P2^6;
sbit D8=P2^7; */
/************函数声明**************/
void DIJ_delay(uchar x); //电机延时函数
void DUJ_delay(uchar x); //舵机延时函数
void Delay(uchar x); //延时xms
void Timer_init(void); //定时器初始化函数
void DUJ_change(uchar x); //转弯函数
void Hongwai(void); //红外对管自动循迹变速函数
/******延时处理******/
void DIJ_delay(uchar x)
{
DIJ_time_delay=x;
while(DIJ_time_delay);
}
void DUJ_delay(uchar x)
{
DUJ_time_delay=x;
while(DUJ_time_delay);
}
void Delay(uchar x)
{
uchar i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
/***********定时器初始化***********/
void Timer_init(void)
{
TMOD=0x11; //定时器0工作于方式1
TH1=TH1_TL1/256;
TL1=TH1_TL1%256;
TH0=TH0_TL0/256;
TL0=TH0_TL0%256;
TR0=1;
TR1=1;
ET0=1;
ET1=1;
EA=1;
}
/**************定时器1(电机)中断处理******************/
void Timer1(void) interrupt 3
{
TR1 = 0;//设置定时器初值期间,关闭定时器
TL1 = TH1_TL1 % 256;
TH1 = TH1_TL1 / 256 ;//定时器装初值
TR1 = 1;
if(DIJ_time_delay != 0)//延时函数用
{
DIJ_time_delay--;
}
if(Flag_turn == 1)//电机正转
{
PWM1 = 0;
if(DIJ_count++ <DIJ_sd)
{
PWM2 = 1;
}
else
{
PWM2 = 0;
}
DIJ_count=DIJ_count%100;
}
else //电机反转
{
PWM2 = 0;
if(DIJ_count++ < DIJ_sd)
{
PWM1 = 1;
}
else
{
PWM1 = 0;
}
DIJ_count=DIJ_count%100;
}
}
/******定时器0(舵机)中断函数*******/
void Timer0() interrupt 1
{
TR0=0;
TH0=TH0_TL0/256;
TL0=TH0_TL0%256;
TR0=1;
if(DUJ_time_delay != 0)//延时函数用
{
DUJ_time_delay--;
}
if(DUJ_count++<DUJ_jd) //判断0.1ms次数是否小于角度标识
PWM3=1; //是,pwm输出高电平
else
PWM3=0; //否,输出低电平
if(DUJ_count>=200) //次数始终保持为200,即保持周期为20ms
{
DUJ_count=0;
Flag_duj=1;
}
}
/***********转弯函数*******/
void DUJ_change(uchar x)
{
DUJ_jd=x;
//DUJ_delay(10);
Delay(20);
}
/*****红外对管自动循迹变速函数****/
void Hongwai()
{
switch(DG)
{
case 0x00: //直走
// Flag_duj=0;
DUJ_change(18);
// while(Flag_duj!=1);
break;
case 0x08: //右拐22.5 速度
// Flag_duj=0;
DUJ_change(17);
// while(Flag_duj!=1);
break;
case 0x0c: // 右拐22.5 速度
// Flag_duj=0;
DUJ_change(17);
// while(Flag_duj!=1);
break;
case 0x0e: // 右拐45 速度
// Flag_duj=0;
DUJ_change(16);
// while(Flag_duj!=1);
break;
case 0x0f: // 右拐45 速度
// Flag_duj=0;
DUJ_change(16);
// while(Flag_duj!=1);
break;
case 0x80: // 左拐22.5 速度
// Flag_duj=0;
DUJ_change(19);
// while(Flag_duj!=1);
break;
case 0xc0: // 左拐22.5 速度
// Flag_duj=0;
DUJ_change(19);
// while(Flag_duj!=1);
break;
case 0xe0: // 右拐45 速度
// Flag_duj=0;
DUJ_change(20);
// while(Flag_duj!=1);
break;
case 0xf0: // 右拐22.5 速度
// Flag_duj=0;
DUJ_change(20);
// while(Flag_duj!=1);
break;
default:
// Flag_duj=0;
DUJ_change(18);
// while(Flag_duj!=1);
break;
}
}
/**********主函数*********/
void main()
{ P2=0xff;
DG=P2;
Timer_init();
/*do
{ P2=0xff;
DG=P2; ;
Hongwai();
}while(DG!=0xff);*/
while(1)
{
DG=P2; ;
Hongwai();
}
}
程序如下:
/*51单片机控制小车 红外对管循迹*/
#include<reg52.h>
#define TH1_TL1 (65536-92) //设定定时器1中断的间隔时长
#define TH0_TL0 (65535-92) //设定定时器1中断的间隔时长
#define uchar unsigned char
uchar DIJ_sd = 40;//电机初始速度
uchar DIJ_count = 0;//电机速度比较用的临时变量
uchar DIJ_time_delay; //电机延时变量
uchar DUJ_jd=18; //舵机初始角度90
uchar DUJ_count=0; //电机角度值比较零时变量
uchar DUJ_time_delay; //舵机延时变量
bit Flag_turn = 1; //电机正反转标志位,1正转,0反转
bit Flag_duj; //舵机一个脉冲结束标记
sbit PWM1=P1^1; //PWM 通道 1,反转脉冲
sbit PWM2=P1^2; //PWM 通道 2,正转脉冲
sbit PWM3=P1^3; //PWM通道3,舵机脉冲
unsigned char DG;
/*sbit D1=P2^0; //8个红外对管检测
sbit D2=P2^1;
sbit D3=P2^2;
sbit D4=P2^3;
sbit D5=P2^4;
sbit D6=P2^5;
sbit D7=P2^6;
sbit D8=P2^7; */
/************函数声明**************/
void DIJ_delay(uchar x); //电机延时函数
void DUJ_delay(uchar x); //舵机延时函数
void Delay(uchar x); //延时xms
void Timer_init(void); //定时器初始化函数
void DUJ_change(uchar x); //转弯函数
void Hongwai(void); //红外对管自动循迹变速函数
/******延时处理******/
void DIJ_delay(uchar x)
{
DIJ_time_delay=x;
while(DIJ_time_delay);
}
void DUJ_delay(uchar x)
{
DUJ_time_delay=x;
while(DUJ_time_delay);
}
void Delay(uchar x)
{
uchar i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
/***********定时器初始化***********/
void Timer_init(void)
{
TMOD=0x11; //定时器0工作于方式1
TH1=TH1_TL1/256;
TL1=TH1_TL1%256;
TH0=TH0_TL0/256;
TL0=TH0_TL0%256;
TR0=1;
TR1=1;
ET0=1;
ET1=1;
EA=1;
}
/**************定时器1(电机)中断处理******************/
void Timer1(void) interrupt 3
{
TR1 = 0;//设置定时器初值期间,关闭定时器
TL1 = TH1_TL1 % 256;
TH1 = TH1_TL1 / 256 ;//定时器装初值
TR1 = 1;
if(DIJ_time_delay != 0)//延时函数用
{
DIJ_time_delay--;
}
if(Flag_turn == 1)//电机正转
{
PWM1 = 0;
if(DIJ_count++ <DIJ_sd)
{
PWM2 = 1;
}
else
{
PWM2 = 0;
}
DIJ_count=DIJ_count%100;
}
else //电机反转
{
PWM2 = 0;
if(DIJ_count++ < DIJ_sd)
{
PWM1 = 1;
}
else
{
PWM1 = 0;
}
DIJ_count=DIJ_count%100;
}
}
/******定时器0(舵机)中断函数*******/
void Timer0() interrupt 1
{
TR0=0;
TH0=TH0_TL0/256;
TL0=TH0_TL0%256;
TR0=1;
if(DUJ_time_delay != 0)//延时函数用
{
DUJ_time_delay--;
}
if(DUJ_count++<DUJ_jd) //判断0.1ms次数是否小于角度标识
PWM3=1; //是,pwm输出高电平
else
PWM3=0; //否,输出低电平
if(DUJ_count>=200) //次数始终保持为200,即保持周期为20ms
{
DUJ_count=0;
Flag_duj=1;
}
}
/***********转弯函数*******/
void DUJ_change(uchar x)
{
DUJ_jd=x;
//DUJ_delay(10);
Delay(20);
}
/*****红外对管自动循迹变速函数****/
void Hongwai()
{
switch(DG)
{
case 0x00: //直走
// Flag_duj=0;
DUJ_change(18);
// while(Flag_duj!=1);
break;
case 0x08: //右拐22.5 速度
// Flag_duj=0;
DUJ_change(17);
// while(Flag_duj!=1);
break;
case 0x0c: // 右拐22.5 速度
// Flag_duj=0;
DUJ_change(17);
// while(Flag_duj!=1);
break;
case 0x0e: // 右拐45 速度
// Flag_duj=0;
DUJ_change(16);
// while(Flag_duj!=1);
break;
case 0x0f: // 右拐45 速度
// Flag_duj=0;
DUJ_change(16);
// while(Flag_duj!=1);
break;
case 0x80: // 左拐22.5 速度
// Flag_duj=0;
DUJ_change(19);
// while(Flag_duj!=1);
break;
case 0xc0: // 左拐22.5 速度
// Flag_duj=0;
DUJ_change(19);
// while(Flag_duj!=1);
break;
case 0xe0: // 右拐45 速度
// Flag_duj=0;
DUJ_change(20);
// while(Flag_duj!=1);
break;
case 0xf0: // 右拐22.5 速度
// Flag_duj=0;
DUJ_change(20);
// while(Flag_duj!=1);
break;
default:
// Flag_duj=0;
DUJ_change(18);
// while(Flag_duj!=1);
break;
}
}
/**********主函数*********/
void main()
{ P2=0xff;
DG=P2;
Timer_init();
/*do
{ P2=0xff;
DG=P2; ;
Hongwai();
}while(DG!=0xff);*/
while(1)
{
DG=P2; ;
Hongwai();
}
}
