采用8051串联直流电机控制

时间:2014-11-23 20:46:02

标签: c embedded 8051

我们正在使用AT89S51微控制器开发直流电机控制器的代码。我们使用嵌入式C代码开发,Keil microvision作为IDE,Progisp用于将.hex文件上传到微控制器,PUTTY用于串行接口。

以下是代码:

#include <reg51.h>
#include <stdio.h>
unsigned int k;
sbit motor = P1^0;

void delay ( int q ) {
  int w;
  for ( w = 0; w < q; w++ );
}

void next_line()
{
  SBUF = 10; // go to next line
  while(TI == 0);
  TI = 0; 
  SBUF = 13; // go to the beginning of the line
  while(TI == 0);
  TI = 0;
}

unsigned char receive() //Function to receive serial data 
{ 
  unsigned char value;
  while ( RI == 0 );
  value=SBUF; 
  P1=value; 
  RI=0;
  return value;
} 

void start()
{
  SCON=0x50;
  TMOD=0x20;
  TH1=0xFD;
  TR1=1;
  TI=1;
}

int i;

main()
{
  while (1)
  {
    unsigned char speed = 0;
    start();
    speed=receive();
    switch (speed)
    {
    case '1':
      k=90; // 90 msec out of 100 msec
      next_line();
      break;
    case '0':
      k=10; // 10 msec out of 100 msec
      next_line();
      break;
    };
    for(i=0; i<100; i++)
    {
      if (i<k) {
        motor = 0;
      }
      else {
        motor = 1;
      }
    }
  }
}

当&#39> 1&#39;我们希望电机能够以90%的功率工作。按下按钮,当&#39; 0&#39; 0切换到10%功率。按下按钮。但是,我们看到的是一些键盘按钮(1,4,5,8)打开电机,一些按钮(2,3,6,7)关闭电机。我无法理解不正当工作的本质。拜托,你能帮我们解决这个问题。提前致谢

2 个答案:

答案 0 :(得分:2)

我将冒险猜测问题并冒险投降。主循环仅在写入串行端口之前在非常短的时间内写入电机位,并且无论选择何种占空比,电机写入都会在控制端口位留下1 ,因此电动机应保持运转或停止。但OP表示按下一个键可以停止或运行电机。 receive()函数等待输入,然后在返回之前将其写入电机端口(不是位定义的)。很容易认为这就是控制电机的动力,但OP按键的LSB与电机控制不一致。那是什么?启动电机的按键都清零1位,停止电机的按键都设置为1位。所以我的第一个猜测是OP为电机控制定义了错误的位,并且正确的声明是

sbit motor = P1^1;

然后从receive()函数

中删除此行
P1 = value;

我从按键位1的第二个猜测是电机逻辑被反转,因此0运行电机,1停止。最重要的是,主循环应检查串行字符输入,这是我的(未经测试!)重写main()

main()
{
    unsigned char speed;
    int k = 10;                     // default is 'slow'
    int i;
    start();                        // moved outside of loop
    while (1)                       // repeat until power off
    {
        while (RI == 0)             // repeat until serial data in
        {
            for(i=0; i<100; i++)    // duty cycle
                if (i<k)
                    motor = 1;      // off: or 0x02 if required for b1
                else
                    motor = 0;      // on: I have inverted the logic
        }

        speed=receive();            // get key press
        switch (speed)
        {
            case '1':
                k=90;               // 90 msec out of 100 msec
                next_line();
                break;
            case '0':
                k=10;               // 10 msec out of 100 msec
                next_line();
                break;
        }
    }
}

答案 1 :(得分:1)

while中的main循环似乎是将占空比设置为10%或90%的1位电机控制,它是通过写入motor来实现的。等同于P1。但是在100次写入之后它会调用receive(),这应该让电机保持运行,因为函数不会返回,直到按下一个键。所以我不明白为什么马达有时会停止。当函数确实返回时,您的case语句不会考虑其他键可能已被按下,因此您只需使用上一次按键设置的k。此外,receive()等待RXD,然后将接收到的字符写入电机控制的P1。所以从表面上看,RXD的LSB用于控制电机。但这是一个错误,因为从receive() P1返回时会再次写入。