我们正在使用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)关闭电机。我无法理解不正当工作的本质。拜托,你能帮我们解决这个问题。提前致谢
答案 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
返回时会再次写入。