hweiyu 发表于 2010-12-12 16:19:26

大家帮忙看一下这个程序,在调试助手上怎样驱动电机

大家帮忙看一下以下程序,如果我想要这两个电机同时正转或反转,在串口调试助手上应该怎么样输入十六进制的编码,编码是什么?谢谢!
//调其中的speed,即时调整占空比,调t即是调周期的长短
/*
串口通信协议
=<值>.
P2=255.//设定P2端口值
P1.//返回P1端口值
P20=1//设定指定端口电平       
D7=500.//设置舵机7的角度
M1=-100.//设置电机1的速度
M.//得到电机0电机1的速度
M1.//得到电机1的速度

P端口
D舵机
M电机


*/
/* 晶振采用11.0592M,产生的PWM的频率约为91Hz */
#include<reg52.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>//类型转换
#include <intrins.h>//位操作   

#define uchar unsigned char
#define uint unsigned int
sfr T2MOD= 0xC9;

sbit        P0_0 = P0^0;//舵机控制
sbit        P0_1 = P0^1;
sbit        P0_2 = P0^2;
sbit        P0_3 = P0^3;
sbit        P0_4 = P0^4;
sbit        P0_5 = P0^5;
sbit        P0_6 = P0^6;
sbit        P0_7 = P0^7;

sbit        P1_0 = P1^0;//键盘输入
sbit        P1_1 = P1^1;
sbit        P1_2 = P1^2;
sbit        P1_3 = P1^3;
sbit        P1_4 = P1^4;
sbit        P1_5 = P1^5;
sbit        P1_6 = P1^6;
sbit        P1_7 = P1^7;

sbit        P2_0 = P2^0;//开关控制
sbit        P2_1 = P2^1;
sbit        P2_2 = P2^2;
sbit        P2_3 = P2^3;
sbit        P2_4 = P2^4;
sbit        P2_5 = P2^5;
sbit        P2_6 = P2^6;
sbit        P2_7 = P2^7;

sbit        P3_0 = P3^0;//串口RXD
sbit        P3_1 = P3^1;//串口TXD
sbit        P3_2 = P3^2;//正转
sbit        P3_3 = P3^3;//直流电机PWM0
sbit        P3_4 = P3^4;//反转
sbit        P3_5 = P3^5;//正转/* L298的Input 1 */
sbit        P3_6 = P3^6;//直流电机PWM1/* L298的Enable A */
sbit        P3_7 = P3^7;//反转/* L298的Input 2 */

/********************直流电机驱动部分start************************/

uchar t=0; /* 中断计数器 */
uchar m1=0,m2=0; /* 电机1速度值 */
uchar tmp1,tmp2; /* 电机当前速度值 */
uchar tmp11,tmp22; /* 电机当前速度值 */
/********************舵机控制start************************/
uint t0_0,t0_1,t0_2,t0_3,t0_4,t0_5,t0_6,t0_7;//舵机PWM信号脉宽控制
uint order1;
uint PWM=2700;//舵机PWM信号周期
uint t1=0;/* 中断计数器1 */
/********************串品start************************/
#define INBUF_LEN 16 //数据长度
unsigned char inbuf1;
unsigned char len;

/********************舵机控制end************************/

/* 电机控制函数 index-电机号(0,1); speed-电机速度(-100—100) */
void motor(uchar index, char speed)
{
        if(speed>=-100 && speed<=100)
        {
                if(index==0) /* 电机1的处理 */
                {        
                        tmp11=speed;
                        m1=abs(speed); /* 取速度的绝对值 */
                        if(speed<0) /* 速度值为负则反转 */
                        {
                                P3_2=0;
                                P3_4=1;
                        }
                        else /* 不为负数则正转 */
                        {
                                P3_2=1;
                                P3_4=0;
                        }
                }
                if(index==1) /* 电机2的处理 */
                {
                        tmp22=speed;
                        m2=abs(speed); /* 取速度的绝对值 */
                        if(speed<0) /* 速度值为负则反转 */
                        {
                                P3_5=0;
                                P3_7=1;
                        }
                        else /* 不为负数则正转 */
                        {
                                P3_5=1;
                                P3_7=0;
                        }
                }
        }
}

void delay(uint j) //简易延时函数
{
        for(j;j>0;j--);
}

/********************直流电机驱动部分定时器************************/

void timer0() interrupt 1 using 1 /* T0中断服务程序 */
{        
        if(t==0) /* 1个PWM周期完成后才会接受新数值 */
        {
                tmp1=m1;
                tmp2=m2; //
        }
        if(t<tmp1)
                P3_3=1;
        else
                P3_3=0; /* 产生电机1的PWM信号 */

        if(t<tmp2)
                P3_6=1;
        else
                P3_6=0; /* 产生电机1的PWM信号 */

        t++;
        if(t>=100)
                t=0; /* 1个PWM信号由100次中断产生 */
        TF0=0;/* reset interrupt flag 复位中断标志位*/
}


/********************直流电机驱动部分END************************/

/********************直流电机驱动部分定时器************************/
void timer1() interrupt 5 //using 2 /* T2中断服务程序 */
{         switch(order1)
        {
                case 1:        P0_0=1;TH2=-t0_0/256;TL2=-t0_0%256;break;
                case 2: P0_0=0;TH2=-(PWM-t0_0)/256;TL2=-(PWM-t0_0)%256;break;
                case 3: P0_1=1;TH2=-t0_1/256;TL2=-t0_1%256;break;
                case 4: P0_1=0;TH2=-(PWM-t0_1)/256;TL2=-(PWM-t0_1)%256;break;
                case 5: P0_2=1;TH2=-t0_2/256;TL2=-t0_2%256;break;
                case 6: P0_2=0 ;TH2=-(PWM-t0_2)/256;TL2=-(PWM-t0_2)%256;break;
                case 7: P0_3=1;TH2=-t0_3/256;TL2=-t0_3%256;break;
                case 8: P0_3=0;TH2=-(PWM-t0_3)/256;TL2=-(PWM-t0_3)%256;break;
                case 9:P0_4=1;TH2=-t0_4/256;TL2=-t0_4%256;break;
                case 10: P0_4=0;TH2=-(PWM-t0_4)/256;TL2=-(PWM-t0_4)%256;break;
                case 11: P0_5=1;TH2=-t0_5/256;TL2=-t0_5%256;break;
                case 12: P0_5=0;TH2=-(PWM-t0_5)/256;TL2=-(PWM-t0_5)%256;break;
                case 13: P0_6=1;TH2=-t0_6/256;TL2=-t0_6%256;break;
                case 14: P0_6=0;TH2=-(PWM-t0_6)/256;TL2=-(PWM-t0_6)%256;break;
                case 15: P0_7=1;TH2=-t0_7/256;TL2=-t0_7%256;break;
                case 16: order1=0;P0_7=0;TH2=-(PWM-t0_7)/256;TL2=-(PWM-t0_7)%256;order1=0;break;                
                default : order1=0;
        }
        order1++;
        TF2=0;/* reset interrupt flag 复位中断标志位*/
}


/********************直流电机驱动部分END************************/
/********************串口通信部分Start************************/


//向串口发送一个字符
void SEND_CHAR( unsigned char ch)
{
        SBUF=ch;
        while (TI== 0 );
        TI= 0;/* reset interrupt flag 复位中断标志位*/
}
/*
//向串口发送一个字符串,strlen为该字符串长度
void SEND_STRING( unsigned char *str, unsigned int strlen)
{
        unsigned int k= 0 ;
        do
        {
                SEND_CHAR(*(str + k));
                k++;
        } while (k < strlen);
}
*/
void UART_SER(void) interrupt 4 using 0
{
        unsigned char ch;
        unsigned char i;
        uint val;
        unsigned char tmp;

        if(RI==1)
        {
                ch=SBUF;
                RI=0;
       
                if(ch==0x2E||ch==0x0A)//终止位
                {
                        inbuf1=ch;
                        //SEND_STRING(inbuf1,INBUF_LEN);//返回字串
                        if (inbuf1==0x50 && inbuf1==0x3D)//P=        端口控制
                        {       
                                memcpy(tmp,inbuf1+3,len-3);
                                val = atoi(tmp);
                                if(inbuf1==0x30){P0=val;}
                                if(inbuf1==0x31){P1=val;}
                                if(inbuf1==0x32){P2=val;}
                                if(inbuf1==0x33){P3=val;};//有串口在不能控制
                        }

                        if (inbuf1==0x50 && inbuf1==0x3D)//P=        端口电平控制
                        {       
                                if(inbuf1==0x30){
                                        ch=P0;
                                        if (inbuf1==0x31){P0 =ch |_crol_(0x01,inbuf1-0x30);        }
                                        else{P0 =ch &_crol_(0xFE,inbuf1-0x30);        }
                                }
                                if(inbuf1==0x31){
                                        ch=P1;
                                        if (inbuf1==0x31){P1 =ch |_crol_(0x01,inbuf1-0x30);        }
                                        else{P1 =ch &_crol_(0xFE,inbuf1-0x30);        }
                                }
                                if(inbuf1==0x32){
                                        ch=P2;
                                        if (inbuf1==0x31){P2 =ch |_crol_(0x01,inbuf1-0x30);        }
                                        else{P2 =ch &_crol_(0xFE,inbuf1-0x30);        }
                                }
                                if(inbuf1==0x33){
                                        ch=P3;
                                        if (inbuf1==0x31){P3 =ch |_crol_(0x01,inbuf1-0x30);        }
                                        else{P3 =ch &_crol_(0xFE,inbuf1-0x30);        }
                                }
                        }

                        if (inbuf1==0x50 && inbuf1==0x00)//P        得到端口状态
                        {       
                                if(inbuf1==0x30){ch=P0;}
                                if(inbuf1==0x31){ch=P1;}
                                if(inbuf1==0x32){ch=P2;}
                                if(inbuf1==0x33){ch=P3;}
                       
                                SEND_CHAR(ch);
                        }
                        if (inbuf1==0x44 && inbuf1==0x3D)//D=        舵机PWM控制 成功返回0x01
                        {
                                memcpy(tmp,inbuf1+3,len-3);
                                val = atoi(tmp);
                                if(inbuf1==0x30){t0_0=val;}
                                if(inbuf1==0x31){t0_1=val;}
                                if(inbuf1==0x32){t0_2=val;}
                                if(inbuf1==0x33){t0_3=val;}
                                if(inbuf1==0x34){t0_4=val;}
                                if(inbuf1==0x35){t0_5=val;}
                                if(inbuf1==0x36){t0_6=val;}
                                if(inbuf1==0x37){t0_7=val;}
                       
                        }

                        if (inbuf1==0x44 && inbuf1==0x3D)//D= 是否打开舵机PWM控制
                        {
                                if (inbuf1==0x31){
                                        TR2=1;
                                }else{
                                        TR2=0;
                                }
                                SEND_CHAR(0x01);
                        }

                        if (inbuf1==0x4D && inbuf1==0x3D)//M=[-100 +100] 电动机控制 成功返回电机转速
                        {
                                memcpy(tmp,inbuf1+3,len-3);
                                val = atoi(tmp);

                                motor(inbuf1-0x30,val);               

                        }

                        if (inbuf1==0x4D && inbuf1!=0x3D)//M 返回电机转速
                        {
                                if(inbuf1==0x30)
                                        SEND_CHAR(tmp11+100);
                                else if(inbuf1==0x31)
                                        SEND_CHAR(tmp22+100);
                                else{
                                        SEND_CHAR(tmp11+100);
                                        SEND_CHAR(tmp22+100);
                                }
                        }

               
                        //清空字串
                        for (i=0;i<INBUF_LEN;i++)
                        {
                                inbuf1=0;
                                tmp=0;
                        };
                        len=0;

                }else{
                        if(len>INBUF_LEN)len=0;
                        inbuf1=ch;
                        len++;
                };
                RI=0;
               
        }

        if(TI)TI=0;/* reset interrupt flag 复位中断标志位*/

}



/********************串口通信部分end************************/



/********************主程序Start************************/
void main()
{
//uchar i;
//unsigned char ch;
/*
EA;        允许单片机总中断
ES;        允许串口中断
ET1;        允许T1溢出中断
EX1;        允许外部中断1
ET0;        允许T0溢出中断
EX0;        允许外部中断0
PT1=0;//中断优先
*/
        delay(1000);
        P0=0x00;
        //P1=0x00;
        P2=0x00;
        //P3=0x00;

        //1电机的T0
        TMOD=0x22; //设定T0的工作模式为2
        TH0=0x9B;//0x9B; //装入定时器的初值65536-50000us    //定时101us
        TL0=0x9B;//0x9B;
        EA=1; // 开中断
        ET0=1; // 定时器0允许中断
        TR0=1; // 启动定时器0

        //2初始化串口的T1

        SCON=0x50; //串行工作方式1,允许接收数据
//        TMOD=0x22; //定时器T1 ,方式2,自动重装的8位定时器
        PCON=0x80; //波特率00不加倍 80加陪9600
        TH1=0xFD; //波特率为19200      
        TL1=0xFD;
        EA=1;//开中断
        ES=1; //串行口中断允许位
        TR1=1; //定时器开启1
        len=0;//收到字串的维数

        //3舵机的T2
        T2MOD &= 0xFC; /* T2OE=0;定时器2输出不允许 */
        T2MOD |= 0x01; /* DCEN=1;可以设置为向上/下计数:此程序中为向上达到0xff时溢出*/
        EXF2=0; /* reset flag 定时器2外部标志位清除*/
        TCLK=0;RCLK=0; /* disable baud rate generator 不用于波特率发生器*/
        EXEN2=0; /* ignore events on T2EX 视T2EX(P1.1)端信号无效*/
        TH2=-1500/256;//0x36; /* Init msb_value 填入初始化值*/
        TL2=-1500%256;//0x36; /* Init lsb_value */
        RCAP2H=-1500/256; /* reload msb_value重载值 */
        RCAP2L=-1500%256; /* reload lsb_value */
        C_T2=0; /* timer mode 定时模式*/
        CP_RL2=0; /* reload mode 重载模式*/
        EA=1; /* interupt enable 中断允许*/
        ET2=1; /* enable timer2 interrupt 允许T2中断*/
        TR2=0; /* timer2 run 开始计时*/

        order1=1;

        t0_0=t0_1=t0_2=t0_3=t0_4=t0_5=t0_6=t0_7=2000;//舵机初始角度


        while(1) /* 电机实际控制演示 */
        {
       
        }
}
页: [1]
查看完整版本: 大家帮忙看一下这个程序,在调试助手上怎样驱动电机