小R科技-WIFI机器人网·机器人创意工作室

 找回密码
 立即注册
查看: 19808|回复: 13

51单片机超高精度6路舵机控制程序

[复制链接]
发表于 2012-8-18 09:24:34 | 显示全部楼层 |阅读模式
/*预处理命令*/
#include <reg52.h>  //包含单片机寄存器的头文件
#define uchar unsigned char
#define uint unsigned int
P0M1=0X00;
P0M0=0XFF;//设置P0 为强推挽输出

sbit servo0=P0^0;
sbit servo1=P0^1;
sbit servo2=P0^2;
sbit servo3=P0^3;
sbit servo4=P0^4;
sbit servo5=P0^5;
sbit servo6=P0^6;
sbit servo7=P0^7;

uchar serVal[2];
uint pwm[]={1382,1382,1382,1382,1382,1382,1382,1382}; //初始90度,(实际是1382.4,取整得1382)
uchar pwm_flag=0;
uint code ms0_5Con=461; //0.5ms计数 (实际是460.8,取整得461)
uint code ms2_5Con=2304; //2.5ms计数

/********************************************************************
* 功能 : 串口初始化,晶振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;  //串行口中断允许位
}
/********************************************************************
* 功能 : 舵机PWM中断初始化
***********************************************************************/
void Timer0Init()
{
//0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms
//2.5 ms初始值 F700, (12n/11059200=2.5/1000, n=2304, X=65536-2304=63232 > F700)  
TMOD |= 0x01;  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=-ms2_5Con>>8;      //给定初值,17ms中断
TL0=-ms2_5Con;
EA=1;            //总中断打开
ET0=1;           //定时器0中断打开
TR0=1;           //定时器0开关打开                                   
}

/********************************************************************
* 功能 : 舵机PWM中断, //舵机控制函数 周期为20ms 一个循环20MS  = 8*2.5ms
***********************************************************************/
void SteeringGear() interrupt 1
{
    switch(pwm_flag)
    {
        case 1:  servo0=1; TH0=-pwm[0]>>8; TL0=-pwm[0]; break;
        case 2:  servo0=0; TH0=-(ms2_5Con-pwm[0])>>8; TL0=-(ms2_5Con-pwm[0]); break;
case 3:  servo1=1; TH0=-pwm[1]>>8; TL0=-pwm[1]; break;
        case 4:  servo1=0; TH0=-(ms2_5Con-pwm[1])>>8; TL0=-(ms2_5Con-pwm[1]); break;   
case 5:  servo2=1; TH0=-pwm[2]>>8; TL0=-pwm[2]; break;
        case 6:  servo2=0; TH0=-(ms2_5Con-pwm[2])>>8; TL0=-(ms2_5Con-pwm[2]); break;
case 7:  servo3=1; TH0=-pwm[3]>>8; TL0=-pwm[3]; break;
        case 8:  servo3=0; TH0=-(ms2_5Con-pwm[3])>>8; TL0=-(ms2_5Con-pwm[3]); break;
case 9:  servo4=1; TH0=-pwm[4]>>8; TL0=-pwm[4]; break;
        case 10: servo4=0; TH0=-(ms2_5Con-pwm[4])>>8; TL0=-(ms2_5Con-pwm[4]); break;
        case 11: servo5=1; TH0=-pwm[5]>>8; TL0=-pwm[5]; break;
        case 12: servo5=0; TH0=-(ms2_5Con-pwm[5])>>8; TL0=-(ms2_5Con-pwm[5]); break;
case 13: servo6=1;TH0=-pwm[6]>>8; TL0=-pwm[6]; break;                     
        case 14: servo6=0;TH0=-(ms2_5Con-pwm[6])>>8; TL0=-(ms2_5Con-pwm[6]); break;  
        case 15: servo7=1;TH0=-pwm[7]>>8;  TL0=-pwm[7]; break;      
        case 16: servo7=0;TH0=-(ms2_5Con-pwm[7])>>8; TL0=-(ms2_5Con-pwm[7]); break;
default: TH0=0xff; TL0=0x80; pwm_flag=0;         
  }
    pwm_flag++;
}

  void SetSteeringGear(uchar i, uchar val)
{
uint a = (val+46)*10;
    if(a<ms0_5Con)
a=ms0_5Con;
if(a>ms2_5Con)
a=ms2_5Con;
pwm[i]=a;
serVal[0]=255; //清除缓存
}

  void SteeringGearUp(uchar i)
{
    if(pwm[i]>ms0_5Con)
pwm[i]=pwm[i]-10;
}

  void SteeringGearDown(uchar i)
{
    if(pwm[i]<ms2_5Con)
pwm[i]=pwm[i]+10;
}

/********************************************************************
* 功能 : 串口中断接收数据
***********************************************************************/
void ser() interrupt 4
{
serVal[0]=serVal[1];
serVal[1]=SBUF;
RI=0;//串口中断清0
}

/*********************************************************************************
** 函数功能 : 主函数
*********************************************************************************/
void main()
{
bit started=0; //路由是否已经启动完毕
    Com_Init();//串口初始化
    Timer0Init();//舵机初始化

while(1)
{
if(serVal[0]=='w' && serVal[1]=='d'){
started=1; //路由启动最后会出现:ar71xx-wdt,由此判断路由已经启动
}

if(started)
{
if(serVal[0]==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]=255; //清除缓存
}else if(serVal[0]==1){
SetSteeringGear(0,serVal[1]);
}else if(serVal[0]==2){
SetSteeringGear(1,serVal[1]);
}else if(serVal[0]==3){
SetSteeringGear(2,serVal[1]);
}else if(serVal[0]==4){
SetSteeringGear(3,serVal[1]);
}else if(serVal[0]==5){
SetSteeringGear(4,serVal[1]);
}else if(serVal[0]==6){
SetSteeringGear(5,serVal[1]);
}
}
}
}

评分

参与人数 1金钱 +2 收起 理由
liuviking + 2 很给力!

查看全部评分

回复

使用道具 举报

发表于 2012-8-18 10:14:37 | 显示全部楼层
笨笨 你好给力哦!!!以后真得多多请教下你的C了!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-18 12:32:25 | 显示全部楼层
电控 发表于 2012-8-18 10:14
笨笨 你好给力哦!!!以后真得多多请教下你的C了!!!

这是从原来的硬盘中找到的程序
回复 支持 反对

使用道具 举报

发表于 2012-8-18 19:43:34 | 显示全部楼层
非常感谢。学习一下
回复 支持 反对

使用道具 举报

发表于 2012-9-14 14:09:43 | 显示全部楼层
非常感谢,学习一下.
回复 支持 反对

使用道具 举报

发表于 2012-9-30 14:30:11 | 显示全部楼层
学习了 谢谢
回复 支持 反对

使用道具 举报

发表于 2012-10-25 15:18:13 | 显示全部楼层
不错,收藏下
回复 支持 反对

使用道具 举报

发表于 2012-11-9 11:21:13 | 显示全部楼层
大侠,能不能精简一下,叫它只控制六路舵机啊!!!!谢谢啦,,想做一个六自由度的机器人。
回复 支持 反对

使用道具 举报

发表于 2012-12-15 15:17:56 | 显示全部楼层
非常感谢。学习一下
回复 支持 反对

使用道具 举报

发表于 2012-12-16 20:06:56 | 显示全部楼层
看帖顶贴!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

新品特惠推荐上一条 /2 下一条

QQ|QQ技术咨询1|QQ技术咨询2|商务合作微信1:xiaorgeek001|商务合作微信2:XiaoRGEEK|诚聘英才|Archiver|手机版|小R科技-WIFI机器人网·机器人创意工作室 ( 粤ICP备15000788号-6 )

GMT+8, 2024-11-22 23:37 , Processed in 1.087295 second(s), 20 queries .

Powered by XiaoR GEEK X3.4

© 2014-2021 XiaoR GEEK

快速回复 返回顶部 返回列表