c - 使用8051串行直流电机控制

标签 c embedded 8051

我们正在使用 AT89S51 微 Controller 开发直流电机 Controller 的代码。我们使用嵌入式 C 语言进行代码开发,使用 Keil microvision 作为 IDE,使用 Progisp 将 .hex 文件上传到微 Controller ,使用 PUTTY 进行串行接口(interface)。

这是代码:

#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;
      }
    }
  }
}

我们预计,当按下“1”按钮时,电机将以 90% 的功率工作;当按下“0”按钮时,电机将切换到 10% 的功率。然而,我们看到的是一些键盘按钮(1、4、5、8)打开电机,一些按钮(2、3、6、7)关闭电机。我无法理解不当工作的本质。请您帮我们解决这个问题。提前致谢

最佳答案

我将冒险猜测这个问题,并冒着被否决的风险。主循环仅在提交串行端口读取之前写入电机位很短的时间,并且无论什么任务,电机写入都会在控制端口位中留下 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;
        }
    }
}

关于c - 使用8051串行直流电机控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27094104/

相关文章:

c - NCURSES - 在 tty 模式下打印时错印新行

c - 为什么 GCC -mcmodel=large 在没有 -fPIC 的情况下即使使用 -no-pie 标志也会向函数调用添加偏移量?

c - 在面向对象范例中使用 C 语言对微处理器进行编程,是否可取?

CMake:使用两个不同的编译器进行交叉编译,但源代码相同

c - 如何仅从 8051 串行发送一次字符串?

c - c中的左移运算符

c - 如何在c中重写char数组?

c - 读取双值 PIC18F67K22

c - 8051 Controller 端口位读/写

c - 如何在8051中将单个特定引脚设置为输入或输出?