求助:利用LV控制直流电机的问题
各位好,小弟利用LV控制三台直流电机的运转,在网上搜了点资料,编了程序,调了半个月依然没有好效果,又不会用仿真器,听师兄说,我用的KEIL似乎仿真功能不足.所以想请研究过的,会用仿真器的朋友帮我看看程序,过一遍程序.
我自己也测试过,烧进程序后,利用LV控制,电机没反应;但是如果在main函数那里给dc_motor和dc_motor_speed设置初值,烧进程序后电机就会转,这时控制LV电机也不会改变速度..由此我判断定时器0产生的PWM波应该有执行,而串口中断那里出了问题...
请哪位研究过的朋友帮我看看程序,谢谢.程序如下:
#include <AT89X55.H> //单片机头文件包含文件
#include <absacc.h>
#include <intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit en1=P0^0; //L298的Enable A
sbit en2=P0^1; //L298的Enable B
sbit en3=P2^0; //L298的Enable c
sbit s1=P0^2; // L298的Input 1
sbit s2=P0^5; // L298的Input 2
sbit s3=P0^6; // L298的Input 3
sbit s4=P0^7; // L298的Input 4
sbit s5=P2^1; // L298的Input 5
sbit s6=P2^2; // L298的Input 6
uchar t=0; // 中断计数器
uchar m1=0; // 电机1速度值
uchar m2=0; // 电机2速度值
uchar m3=0; // 电机3速度值
uchar tmp1,tmp2,tmp3; //电机1 2 3当前速度值
uchar dc_motor; //电机代号
uchar dc_motor_temp; //存放dc_motor的值,防止数据泄露
char dc_motor_speed; //电机速度,由于电机有正反转,故设置为有符号数
uchar serial_count; //串口计数
void timer0() interrupt 1 //定时器0产生PWM信号,此部分是引用网上的
{
if(t==0) //1个PWM周期完成后才会接受新数值
{
tmp1=m1;
tmp2=m2;
tmp3=m3;
}
if(t<tmp1) en1=0; else en1=1; //产生电机1的PWM信号
if(t<tmp2) en2=0; else en2=1; //产生电机2的PWM信号
if(t<tmp3) en3=0; else en3=1; //产生电机3的PWM信号
t++;
if(t>=20) t=0; //1个PWM信号由20次中断产生
}
void dc_motor_control () interrupt 4 //单片机串口中断处理程序
{
ES=0; //关闭串口允许中断位,为了不受第二次中断干扰
RI=0; //清接收中断标志位
if(serial_count==0) //用来把PC机发送下来的指令放入需要的地方,第一个是电机代号的信息
{
dc_motor=SBUF; //把串口接收缓冲区中的信息放入dc_motor里面
dc_motor_temp=dc_motor; //将dc_motor暂存在dc_motor_temp里面
serial_count++; //然后串口计数加1
}
else
{
dc_motor_speed=SBUF; //第二个接收到的字节用于表示speed,存入dc_motor_speed中
serial_count=0; //只接收2个字节,为了下次能把第一字节放入dc_motor中,进行计数清零
}
ES=1; //接收处理完毕之后要把中断允许位重新打开,不然下次没法完成处理
}
void motor(uchar index, char speed) //直流电机的方向控制函数,index代表电机代号,speed是速度值,此部分引用网上
{
if(speed>=-20 && speed<=20) //限制速度值在-20至20之间
{
if(index==1) //电机1的处理
{
m1=abs(speed); //取速度的绝对值赋给m1
if(speed<0) //速度值为负则反转
{
s1=1;
s2=0;
}
else //速度值不为负数则正转
{
s1=0;
s2=1;
}
}
if(index==2) // 电机2的处理
{
m2=abs(speed);
if(speed<0)
{
s3=1;
s4=0;
}
else
{
s3=0;
s4=1;
}
}
if(index==3) // 电机3的处理
{
m3=abs(speed);
if(speed<0)
{
s5=1;
s6=0;
}
else
{
s5=0;
s6=1;
}
}
}
}
main() //主程序
{
dc_motor=0;
serial_count=0;
dc_motor_temp=0;
dc_motor_speed=0;
TMOD=0x22; //模式2,T0用来产生PWM波,T1作为串行口波特率发生器
TH1=0xfd; //baud rate is 9600,11.0592HZ
TL1=0xfd;
TH0=0xec; //TO初值为236,也就是256-20
TL0=0xec;
SCON=0x50; //允许串行口接受数据
PCON=0x00;
ES=1; //串行通信中断使能
EA=1; //所有中断使能
TR1=1; //启动定时器1
ET0=1; //定时器0允许中断
TR0=1; //启动定时器0
while(1)
{
motor(dc_motor,dc_motor_speed); //调用电机函数
}
} 你从计算机发数据下来是怎么发的,发一个字节,产生一次中断,按你的程序是SBUF的值先给电机号,然后又给电机速度,那电机速度不就等于电机号了吗?
如果一次发两个字节,你又把进行中断后,你把中断给关了,这样后面那个字节又同时给了电机号与电机速度,这样不行吧,呵呵。
不知道是不是这个问题。
[ 本帖最后由 luke 于 2007-12-19 15:59 编辑 ]
页:
[1]