瓦力启动了

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

 

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

 

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

 

/*预处理命令*/

#include  //包含单片机寄存器的头文件

#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(valc180)

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  //包含单片机寄存器的头文件

#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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值