瓦力启动了

2011-12-31


http://player.youku.com/player.php/sid/XMzM4MTYyODQw/v.swf

2011年最后一天,总算有点交待了。虽然走路不稳,但总算是手手脚脚,头颈都可以动了。舵机不稳,底部的舵机调零也不是很准,问题还不少,智能还没开始搞,留着2012年继续完善它吧~

 

顺便说明一下,我这里如果单片机和舵机共用一个电源,只能支持2个舵机,超过2个就不工作了。所以我是单片机和WR703N共用一组4个AA电池,6个舵机共用一组4个AA电池。经过测试,4个2500mAh的电池充满电,同时给WR703N和51单片机供电,开着mjpg-streamer(640X480),总共可以运行5个小时!

 

单片机还是用51,代码如下:

/*预处理命令*/

#include <reg52.h>  //包含单片机寄存器的头文件

#define uchar unsigned char

#define uint unsigned int

 

uchar serVal[2];

uchar hightVotage1, hightVotage2, hightVotage3, hightVotage4, hightVotage5, hightVotage6;

uchar lowVotage1, lowVotage2, lowVotage3, lowVotage4, lowVotage5, lowVotage6;

uchar angleValue1, angleValue2, angleValue3, angleValue4, angleValue5, angleValue6;

sbit steeringGearSignal=P0^0;

sbit steeringGearSigna2=P0^1;

sbit steeringGearSigna3=P0^2;

sbit steeringGearSigna4=P0^3;

sbit steeringGearSigna5=P0^4;

sbit steeringGearSigna6=P0^5;

bit PWMCTL1=0;

bit PWMCTL2=0;

bit PWMCTL3=0;

bit PWMCTL4=0;

bit PWMCTL5=0;

bit PWMCTL6=0;

uchar c0=5;

uchar c90=15;

uchar c180=26;

uchar pwmWidth=205;

 

/********************************************************************

* 名称 : Com_Init()

* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Com_Init()

{

TMOD=0x20;   //用定时器设置串口波特率

TH1=0xFD;   //256-11059200/(32*12*9600)=253 (FD)

TL1=0xFD;//同上

TR1=1;//定时器1开关打开  

REN=1;          //开启允许串行接收位

SM0=0;//串口方式,8位数据

SM1=1;//同上

EA=1;           //开启总中断

ES=1;  //串行口中断允许位

}

/********************************************************************

* 名称 : Timer0Init()

* 功能 : 舵机PWM中断初始化

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Timer0Init()

{

//0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms

//0.1ms初始值 FFA3, (12n/11059200=0.1/1000, n=92, X=65535-92=65443 > FFA3)    

    steeringGearSignal=0; 

steeringGearSigna2=0; 

steeringGearSigna3=0; 

steeringGearSigna4=0; 

steeringGearSigna5=0; 

steeringGearSigna6=0; 

angleValue1=c90;//初始90度

angleValue2=c90;

angleValue3=c90;

angleValue4=c90;

angleValue5=c90;

angleValue6=c90;

TMOD |= 0x01;  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响

TH0=0xFF;      //给定初值,0.1ms中断

TL0=0xA3;

EA=1;            //总中断打开

ET0=1;           //定时器0中断打开

TR0=1;           //定时器0开关打开                                   

}

 

/********************************************************************

* 名称 : SteeringGear()

* 功能 : 舵机PWM中断

* 输入 : 无

* 输出 : 无

***********************************************************************/

void SteeringGear() interrupt 1

{

    TH0=0xFF;    //重置计时器初始值

    TL0=0xA3;//同上

 

    //舵机信号1

     if (PWMCTL1)    //正在输出高电平

    {

        if(++hightVotage1>=angleValue1){//开始输出低电平

            PWMCTL1=!PWMCTL1;

            lowVotage1=0;

            steeringGearSignal=0;

        }

    }else{            //正在输出低电平

        if(++lowVotage1>=(pwmWidth-angleValue1)){//开始输出高电平

            PWMCTL1=!PWMCTL1;

            hightVotage1=0;

            steeringGearSignal=1;

        }

    }

 

    //舵机信号2

     if (PWMCTL2)    //正在输出高电平

    {

        if(++hightVotage2>=angleValue2){//开始输出低电平

            PWMCTL2=!PWMCTL2;

            lowVotage2=0;

            steeringGearSigna2=0;

        }

    }else{            //正在输出低电平

        if(++lowVotage2>=(pwmWidth-angleValue2)){//开始输出高电平

            PWMCTL2=!PWMCTL2;

            hightVotage2=0;

            steeringGearSigna2=1;

        }

    }

    

    //舵机信号3

     if (PWMCTL3)    //正在输出高电平

    {

        if(++hightVotage3>=angleValue3){//开始输出低电平

            PWMCTL3=!PWMCTL3;

            lowVotage3=0;

            steeringGearSigna3=0;

        }

    }else{            //正在输出低电平

        if(++lowVotage3>=(pwmWidth-angleValue3)){//开始输出高电平

            PWMCTL3=!PWMCTL3;

            hightVotage3=0;

            steeringGearSigna3=1;

        }

    }

    

    //舵机信号4

     if (PWMCTL4)    //正在输出高电平

    {

        if(++hightVotage4>=angleValue4){//开始输出低电平

            PWMCTL4=!PWMCTL4;

            lowVotage4=0;

            steeringGearSigna4=0;

        }

    }else{            //正在输出低电平

        if(++lowVotage4>=(pwmWidth-angleValue4)){//开始输出高电平

            PWMCTL4=!PWMCTL4;

            hightVotage4=0;

            steeringGearSigna4=1;

        }

    }

   //舵机信号5

     if (PWMCTL5)    //正在输出高电平

    {

        if(++hightVotage5>=angleValue5){//开始输出低电平

            PWMCTL5=!PWMCTL5;

            lowVotage5=0;

            steeringGearSigna5=0;

        }

    }else{            //正在输出低电平

        if(++lowVotage5>=(pwmWidth-angleValue5)){//开始输出高电平

            PWMCTL5=!PWMCTL5;

            hightVotage5=0;

            steeringGearSigna5=1;

        }

    }

   //舵机信号6

     if (PWMCTL6)    //正在输出高电平

    {

        if(++hightVotage6>=angleValue6){//开始输出低电平

            PWMCTL6=!PWMCTL6;

            lowVotage6=0;

            steeringGearSigna6=0;

        }

    }else{            //正在输出低电平

        if(++lowVotage6>=(pwmWidth-angleValue6)){//开始输出高电平

            PWMCTL6=!PWMCTL6;

            hightVotage6=0;

            steeringGearSigna6=1;

        }

    }

}

 

/********************************************************************

* 名称 :

* 功能 : 舵机控制函数。

* 输入 : 无

* 输出 : 无

***********************************************************************/

 uchar validateMinGearValue(uchar val)

{

    if(val>c0)

val=val-1;

return val;

}

 

 uchar validateMaxGearValue(uchar val)

{

    if(val<c180)

val=val+1;

return val;

}

 

 uchar validateGearValue(uchar val)

{

uchar angVal = val-60;

    if(angVal<c0)

angVal=c0;

if(angVal>c180)

angVal=c180;

return angVal;

}

 

  void SteeringGear1Up()

{

    angleValue1=validateMinGearValue(angleValue1);

}

  void SteeringGear1Down()

{

    angleValue1=validateMaxGearValue(angleValue1);

}

  void SteeringGear2Up()

{

    angleValue2=validateMinGearValue(angleValue2);

}

  void SteeringGear2Down()

{

    angleValue2=validateMaxGearValue(angleValue2);

}

  void SteeringGear3Up()

{

    angleValue3=validateMinGearValue(angleValue3);

}

  void SteeringGear3Down()

{

    angleValue3=validateMaxGearValue(angleValue3);

}

  void SteeringGear4Up()

{

    angleValue4=validateMinGearValue(angleValue4);

}

  void SteeringGear4Down()

{

    angleValue4=validateMaxGearValue(angleValue4);

}

  void SteeringGear5Up()

{

    angleValue5=validateMinGearValue(angleValue5);

}

  void SteeringGear5Down()

{

    angleValue5=validateMaxGearValue(angleValue5);

}

  void SteeringGear6Up()

{

    angleValue6=validateMinGearValue(angleValue6);

}

  void SteeringGear6Down()

{

    angleValue6=validateMaxGearValue(angleValue6);

}

 

 

  void SetSteeringGear1(uchar val)

{

angleValue1=validateGearValue(val);

}

  void SetSteeringGear2(uchar val)

{

angleValue2=validateGearValue(val);

}

  void SetSteeringGear3(uchar val)

{

angleValue3=validateGearValue(val);

}

  void SetSteeringGear4(uchar val)

{

angleValue4=validateGearValue(val);

}

  void SetSteeringGear5(uchar val)

{

angleValue5=validateGearValue(val);

}

  void SetSteeringGear6(uchar val)

{

angleValue6=validateGearValue(val);

}

 

/********************************************************************

* 名称 : ser()

* 功能 : 串口中断接收数据

* 输入 : 无

* 输出 : 无

***********************************************************************/

void ser() interrupt 4

{

serVal[0]=serVal[1];

serVal[1]=SBUF;

RI=0;//串口中断清0

}

 

/*********************************************************************************

** 函数名称 : main(void)

** 函数功能 : 主函数

*********************************************************************************/

void main()

{

    Com_Init();//串口初始化

    Timer0Init();//舵机初始化

while(1)

{

if(serVal[0]=='!'){

switch(serVal[1])

{

case 'A': SteeringGear1Up(); break;

case 'B': SteeringGear1Down(); break;

case 'C': SteeringGear2Up(); break;

case 'D': SteeringGear2Down(); break;

case 'E': SteeringGear3Up(); break;

case 'F': SteeringGear3Down(); break;

case 'G': SteeringGear4Up(); break;

case 'H': SteeringGear4Down(); break;

case 'I': SteeringGear5Up(); break;

case 'J': SteeringGear5Down(); break;

case 'K': SteeringGear6Up(); break;

case 'L': SteeringGear6Down(); break;

default:break; 

}

serVal[0]=0; //清除缓存

}else if(serVal[0]=='"'){

SetSteeringGear1(serVal[1]);

}else if(serVal[0]=='#'){

SetSteeringGear2(serVal[1]);

}else if(serVal[0]=='$'){

SetSteeringGear3(serVal[1]);

}else if(serVal[0]=='%'){

SetSteeringGear4(serVal[1]);

}else if(serVal[0]=='&'){

SetSteeringGear5(serVal[1]);

}else if(serVal[0]=='\''){

SetSteeringGear6(serVal[1]);

}

}

}

 

我曾经想将单片机的程序写的好看一点,代码少一点,重用多一点(程序员的通病),结果怎么调试都不行,后来换了一个“增强型51”的CPU(STC12C5A60S2)居然就跑起来了,可能是代码虽然少了,但效率反而低了,之前的STC89C52的速度比较低,就跑不起来。顺便贴出来,让别人也少走弯路。

STC12C5A60S2可用的单片机程序:

/*预处理命令*/

#include <reg52.h>  //包含单片机寄存器的头文件

#define uchar unsigned char

#define uint unsigned int

 

uchar serVal[]={0,0};

uchar hiVot[]={0,0,0,0,0,0};

uchar loVot[]={0,0,0,0,0,0};

uchar ang[]={15,15,15,15,15,15}; //初始90度

uchar serCtl=0;

uchar code mask1[]={0x01,0x02,0x04,0x08,0x10,0x20};

uchar code mask0[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};

 

/********************************************************************

* 名称 : Com_Init()

* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Com_Init()

{

TMOD |= 0x20;   //用定时器设置串口波特率

TH1=0xFD;   //256-11059200/(32*12*9600)=253 (FD)

TL1=0xFD;//同上

TR1=1;//定时器1开关打开  

REN=1;          //开启允许串行接收位

SM0=0;//串口方式,8位数据

SM1=1;//同上

EA=1;           //开启总中断

ES=1;  //串行口中断允许位*/

}

/********************************************************************

* 名称 : Timer0Init()

* 功能 : 舵机PWM中断初始化

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Timer0Init()

{

//0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms

//(估计)0.1ms初始值 FFA3, (12n/11059200=0.1/1000, n=92.16, X=65535-92=65443 > FFA3)

//(实际)每次中断的间隔是0.09765625ms,0.5ms计数是5,1.5ms计数是15,2.5ms计数是26,20ms计数是205    

TMOD |= 0x01;  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响

TH0=0xFF;      //给定初值,0.09765625ms中断

TL0=0xA3;

EA=1;            //总中断打开

ET0=1;           //定时器0中断打开

TR0=1;           //定时器0开关打开                                   

}

 

/********************************************************************

* 名称 : SteeringGear()

* 功能 : 舵机PWM中断

* 输入 : 无

* 输出 : 无

***********************************************************************/

void SteeringGear() interrupt 1

{

uchar i;

bit ctl;

    TH0=0xFF;//重置计时器初始值

    TL0=0xA3;//同上

for (i = 0; i<6; i++){

ctl=serCtl&mask1[i];//取特定位

//舵机信号i

if (ctl)//正在输出高电平

{

hiVot[i]=hiVot[i]+1;

if(hiVot[i]>=ang[i]){//开始输出低电平

serCtl=serCtl&mask0[i];//特定位 置0

loVot[i]=0;

P0=P0&mask0[i];//特定位 置0

}

}else{//正在输出低电平

loVot[i]=loVot[i]+1;

if(loVot[i]>=(205-ang[i])){//开始输出高电平

serCtl=serCtl|mask1[i];//特定位 置1

hiVot[i]=0;

P0=P0|mask1[i];//特定位 置1

}

}

}

 

}

 

/********************************************************************

* 名称 :SetSteeringGear()

* 功能 : 设置舵机角度。

* 输入 : 无

* 输出 : 无

***********************************************************************/

  void SetSteeringGear(uchar i, uchar val)

{

uchar angVal = val-60; //

    if(angVal<5)

angVal=5;

if(angVal>26)

angVal=26;

ang[i]=angVal;

}

 

/********************************************************************

* 名称 :SteeringGearUp()

* 功能 : 舵机向上转。

* 输入 : 无

* 输出 : 无

***********************************************************************/

  void SteeringGearUp(uchar i)

{

    if(ang[i]>5)

ang[i]=ang[i]-1;

}

 

/********************************************************************

* 名称 :SteeringGearDown()

* 功能 : 舵机向下转。

* 输入 : 无

* 输出 : 无

***********************************************************************/

  void SteeringGearDown(uchar i)

{

    if(ang[i]<26)

ang[i]=ang[i]+1;;

}

 

/********************************************************************

* 名称 : ser()

* 功能 : 串口中断接收数据

* 输入 : 无

* 输出 : 无

***********************************************************************/

void ser() interrupt 4

{

serVal[0]=serVal[1];

serVal[1]=SBUF;

RI=0;//串口中断清0

}

 

/*********************************************************************************

** 函数名称 : main(void)

** 函数功能 : 主函数

*********************************************************************************/

void main()

{

    Com_Init();//串口初始化

    Timer0Init();//舵机初始化

while(1)

{

if(serVal[0]=='!'){

switch(serVal[1])

{

case 'A': SteeringGearUp(0); break;

case 'B': SteeringGearDown(0); break;

case 'C': SteeringGearUp(1); break;

case 'D': SteeringGearDown(1); break;

case 'E': SteeringGearUp(2); break;

case 'F': SteeringGearDown(2); break;

case 'G': SteeringGearUp(3); break;

case 'H': SteeringGearDown(3); break;

case 'I': SteeringGearUp(4); break;

case 'J': SteeringGearDown(4); break;

case 'K': SteeringGearUp(5); break;

case 'L': SteeringGearDown(5); break;

default:break; 

}

serVal[0]=0; //清除缓存

}else if(serVal[0]=='"'){

SetSteeringGear(0,serVal[1]);

}else if(serVal[0]=='#'){

SetSteeringGear(1,serVal[1]);

}else if(serVal[0]=='$'){

SetSteeringGear(2,serVal[1]);

}else if(serVal[0]=='%'){

SetSteeringGear(3,serVal[1]);

}else if(serVal[0]=='&'){

SetSteeringGear(4,serVal[1]);

}else if(serVal[0]=='\''){

SetSteeringGear(5,serVal[1]);

}

}

}

 

上位机借用了网友的源代码,改成6个舵机控制,程序启动的时候就会自动开始socket连接,有几个参数CMD_Servo×_prefix懒得改界面了,直接改ini就得了。程序截图如下:

程序/工程文件/源代码下载:

http://bbs.igee.cn/read.php?tid=5582

http://download.csdn.net/detail/channel_z/4074612


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值