cpubbs论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

LabVIEW+单片机学习套件全套教程资料下载[免费]LabVIEW论坛精华列表贴USB0816数据采集卡《LabVIEW宝典》
LabWindows/CVI论坛精华贴NET0816以太网数据采集卡RC0210远程设备授权系统 关闭关停锁定打开设备 户外分布式数据采集
NET1624低速高精度以太网数据采集卡WIFI0824SD无线WIFI网络数据采集卡脱机运行 SD存储 小尺寸微型 串口采集远程采集 安卓 手持移动采集 纪录仪
查看: 1578|回复: 1

求助:利用LV控制直流电机的问题

[复制链接]
发表于 2007-12-11 21:41:31 | 显示全部楼层 |阅读模式
各位好,小弟利用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);       //调用电机函数
        }
       
}
发表于 2007-12-15 11:15:01 | 显示全部楼层
你从计算机发数据下来是怎么发的,发一个字节,产生一次中断,按你的程序是SBUF的值先给电机号,然后又给电机速度,那电机速度不就等于电机号了吗?
如果一次发两个字节,你又把进行中断后,你把中断给关了,这样后面那个字节又同时给了电机号与电机速度,这样不行吧,呵呵。
不知道是不是这个问题。


[ 本帖最后由 luke 于 2007-12-19 15:59 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|cpubbs论坛. ( 粤ICP备09171248号 )

GMT+8, 2024-5-20 02:19 , Processed in 0.470609 second(s), 8 queries , Gzip On, File On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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