基于51单片机的舵机(5路)
一个按键控制正转一个控制反转,共10个按键,然后再用一个按键控制5个舵机同时正转一个舵机同时控制5个舵机反转,共12个按键。
LCD1602显示当前舵机的旋转角度。
注:51单片机的速度比较低,控制精度也很差。本设计的角度不能细调,只能粗调。仅供学习参考
#include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "lcd1602.h"
#define uchar unsigned char
#define uint unsigned int
sbit motor0=P2^3;//第一个电机
sbit motor1=P2^4;//第二个电机
sbit motor2=P2^5;//第三个电机
sbit motor3=P2^6;//第四个电机
sbit motor4=P2^7;//第五个电机
uchar pwm[5]={7,7,7,7,7};//每个电机占空比
uint time=0;//计时变量
uchar sec=0;
uchar disp[]="000 ";
/*******************************************************************************
* 函 数 名 : delay(uint i)
* 函数功能 : 延时
* 输 入 : i
* 输 出 : 无
*******************************************************************************/
void delay(uint i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0Init()
{
TMOD|=0X12;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=106; //给定时器赋初值,定时100us
TL0=106;
TH1=0X3C;//50ms
TL1=0XB0;
ET1=1;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
TR1=1;
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
uchar key_scan()//按键检测
{
uchar i,j;
i=0;
j=0;
P1=0x0f;
if(P1!=0x0f) //检测有无按下
{
switch(P1)//检测行
{
case 0x0e:i=3;break;
case 0x0d:i=2;break;
case 0x0b:i=1;break;
case 0x07:i=0;
}
P1=0xf0;
switch(P1)//检测列
{
case 0xe0:j=13;break;
case 0xd0:j=9;break;
case 0xb0:j=5;break;
case 0x70:j=1;
}
}
return i+j;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
uchar m,i;
uint k;
init_1602();
disp[3]=0xdf;
Timer0Init(); //定时器0初始化
while(1)
{
i=key_scan();//按键检测
if(i==1)//第一个电机正转
{
if(pwm[0]<14)
pwm[0]++;
for(k=0;k<200;k++)//延时
{
delay(100);
}
}
if(i==2)//第一个电机反转
{
if(pwm[0]>7)
pwm[0]--;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
//========================================
if(i==3)//第二个电机正转
{
if(pwm[1]<14)
pwm[1]++;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
if(i==4)//第二个电机反转
{
if(pwm[1]>7)
pwm[1]--;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
//========================================
if(i==5)//第三个电机正转
{
if(pwm[2]<14)
pwm[2]++;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
if(i==6)//第三个电机反转
{
if(pwm[2]>7)
pwm[2]--;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
//========================================
if(i==7)//第四个电机正转
{
if(pwm[3]<14)
pwm[3]++;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
if(i==8)//第四个电机反转
{
if(pwm[3]>7)
pwm[3]--;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
//========================================
if(i==9)//第五个电机正转
{
if(pwm[4]<14)
pwm[4]++;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
if(i==10)//第五个电机反转
{
if(pwm[4]>7)
pwm[4]--;
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
//========================================
if(i==11)//全部电机反转
{
for(m=0;m<5;m++)
{
if(pwm[m]>7)
pwm[m]--;
}
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
if(i==12)//全部电机正转
{
for(m=0;m<5;m++)
{
if(pwm[m]<14)
pwm[m]++;
}
for(k=0;k<200;k++)//延时
{
if(key_scan()==0)
break;
delay(100);
}
}
}
}
/*******************************************************************************
* 函 数 名 : void Timer0() interrupt 1
* 函数功能 : 定时器0中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0() interrupt 1
{
if(time<140)
{
time++;
if(time<pwm[0])//驱动第一个电机
motor0=1;
else
motor0=0;
if(time<pwm[1])//驱动第二个电机
motor1=1;
else
motor1=0;
if(time<pwm[2])//驱动第三个电机
motor2=1;
else
motor2=0;
if(time<pwm[3])//驱动第四个电机
motor3=1;
else
motor3=0;
if(time<pwm[4])//驱动第五个电机
motor4=1;
else
motor4=0;
}
else
{
time=0;
}
}
/*******************************************************************************
* 函 数 名 : void Timer1() interrupt 3
* 函数功能 : 定时器1中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer1() interrupt 3
{
uint i;
if(sec<10)
sec++;
else
{
sec=0;
//显示
i=pwm[0];
i=i-7;
i=i*180/14;
disp[0]=i/100+0x30;
disp[1]=i%100/10+0x30;
disp[2]=i%10+0x30;
write_string(1,0,disp);
i=pwm[1];
i=i-7;
i=i*180/14;
disp[0]=i/100+0x30;
disp[1]=i%100/10+0x30;
disp[2]=i%10+0x30;
write_string(1,6,disp);
i=pwm[2];
i=i-7;
i=i*180/14;
disp[0]=i/100+0x30;
disp[1]=i%100/10+0x30;
disp[2]=i%10+0x30;
write_string(1,11,disp);
i=pwm[3];
i=i-7;
i=i*180/14;
disp[0]=i/100+0x30;
disp[1]=i%100/10+0x30;
disp[2]=i%10+0x30;
write_string(2,0,disp);
i=pwm[4];
i=i-7;
i=i*180/14;
disp[0]=i/100+0x30;
disp[1]=i%100/10+0x30;
disp[2]=i%10+0x30;
write_string(2,6,disp);
}
TH1=0X3C;//50ms
TL1=0XB0;
}