大家帮忙看一下这个程序,在调试助手上怎样驱动电机
大家帮忙看一下以下程序,如果我想要这两个电机同时正转或反转,在串口调试助手上应该怎么样输入十六进制的编码,编码是什么?谢谢!//调其中的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]