您的位置:首页 > 其它

第一次小小的尝试——舵机控制

2013-11-20 13:40 232 查看
去年第二届机器人擂台赛不知怎么地打了酱油,看到生命童鞋基本上是独立做出了遥控小车——以手机为上位机,通过蓝牙进行串口数据传送,搭建直流稳压模块和以lm298n作为驱动模块(老实说,这些东西我是在这次才懂得,当初忘了在忙啥了,神马都没有主动去了解⊙﹏⊙b汗),对于那会的生命,这些东西独立捣鼓出来完全不是问题,因为现在我觉得我都能勉勉强强做出来(不过估计很多细节需要请教的。。。),除了焊了51单片机的最小系统外,本人的焊工经验基本等于0  =.= 这次比赛的分工着实让我充满动力和成就感! 生命,作为队长,将5个人分工为五个模块:阿杜负责驱动舵机的317驱动模块,子维兄则尝试用Altium Designer画出lm298驱动电路的pcb图,作为备用板,william和生命继续搞机(机械部分).....,而我就负责武器中舵机的控制和选购O(∩_∩)O    这样分工的感觉简直就像是一个项目团队的模块化分工,感觉振奋呐!(前段时间看了《疯狂的程序员》,原谅博主的打鸡血反应~) 由于寒假的时候,曾宅在房间里玩高级流水灯,里面涉及了PWM的应用,因此对舵机的控制程序也有所熟悉。写程序时才发现,一般pwm信号的产生是在while中循环实现的,但是操作小车的时候不可能一直卡在舵机控制函数中,使用了舵机意味着直接进入死循环! 问题困扰了我几天,有空余零散的时间就去想,最后在洗澡中找到了方法!(博主绝对洗干净的..)通过count来控制脉冲数目,while里的条件改为count次数,维持一定时间,如此避免了死循环!因为舵机需要有脉冲输入才能维持角度,但是小车只需要两种状态,一是上抬武器,二是归位,归位无需维持角度,所以重点攻克对象是上抬状态。既然不能通过进入while来产生,那就直接嵌入主程序里! 既然不能并行操作,那我就直接一路串下来! 通过一个flag状态变量,来表示舵机状态,在进入主程序,检查flag,如果为1,则维持脉冲。在switch中的case后设置flag的改变。至此,舵机控制函数完成!(嗷嗷~~~ 骄傲下~~)
接下来贴出源代码以供参考#include<reg52.h>#define uchar unsigned char#define uint unsigned int #define N 5  // 脉冲数uchar count_ms=0,ms1=0; //ms1为0.1ms  uchar flag; // flag为1表示舵机已抬起 sbit Sign_out=P2^0; //舵机信号输出口sbit Test=P2^1;
uchar angle_0=5;    //0.5ms-------------0度uchar angle_45=10;   //1.0ms------------45度;uchar angle_90=15; //1.5ms------------90度;uchar angle_135=18; //2.0ms-----------135度;uchar angle_180=25; //2.5ms-----------180度;
sbit EN1=P1^0;sbit EN2=P1^1;sbit A1=P1^2;sbit A2=P1^3;sbit B1=P1^4; sbit B2=P1^5;
void Time1() interrupt 1{ TH0=(65536-100)/256; TL0=(65536-100)%256;//重新赋值 count_ms++; if(count_ms==1) { count_ms=0;ms1++; }}
void Move(uchar angle)//舵机角度移动{ uchar count=0; while(count<=N) //count记录脉冲数 { TR0=1; if(ms1<=angle) //时间小于angle时,拉高Sign_out Sign_out=1; else Sign_out=0; if(ms1>=200) //总时间长度为20ms,到达时间则关闭定时器,count累加,完成一个脉冲周期 { ms1=0; TR0=0; count++; } }}unsigned char a;void main(){ TMOD=0x21; TH1=0xfd; TL1=0xfd; TH0=(65536-100)/256;   TL0=(65536-100)%256; //二、 装初值 TR1=1; REN=1;//开始接收 SM0=0;//8位UART SM1=1; EA=1;//中断 ES=1; ET0=1;//2 定时器0中断 while(1) { if(flag==1) { Move(angle_135);  //维持舵机上抬的状态 } if(Test==1)a=5; if(Test==0)a=6; switch(a) { case 1:EN1=1;EN2=1;A1=1;A2=0;B1=1;B2=0;//w case 2:EN1=1;EN2=1;A1=0;A2=1;B1=0;B2=1;//s case 3:EN1=1;EN2=1;A1=1;A2=0;B1=0;B2=1;break;//a case 4:EN1=1;EN2=1;A1=0;A2=1;B1=1;B2=0;break;//d case 0:EN1=0;EN2=0;break;//stop case 6:EN1=1;EN2=1;A1=1;A2=0;B1=1;B2=0;Move(angle_0);flag=0;break; //舵机归位 case 5:EN1=1;EN2=1;A1=1;A2=0;B1=1;B2=0;Move(angle_135);flag=1;break;//舵机上抬 case 7:EN1=1;EN2=1;A1=1;A2=0;B1=1;B2=0;break;   } }}void mhp() interrupt 4//串口中断{    RI=0; P1=SBUF; a=SBUF;}

预祝这次比赛拿到奖金!!(Fight!  Iron!,we are Iron Man!)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: