51单片机步进电机问题

请问如何通过键盘实现自由输入角度控制电机转动,如135.36度这种,我现在只会固定角度转动


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>

#define MAX_ANGLE_LEN 20

// 定义电机控制函数,输入角度值,输出电机转动信号
void control_motor(double angle) {
    // 将角度值转换为电机控制信号,这里只是一个示例
    double motor_signal = angle / 360.0;

    // 发送电机控制信号,控制电机转动
    // ...
}

int main() {
    char angle_str[MAX_ANGLE_LEN];
    double angle;

    printf("请输入角度值:");

    while (1) {
        if (_kbhit()) {
            char ch = _getch();

            if (isdigit(ch) || ch == '.' || ch == '-') {
                printf("%c", ch);
                strncat(angle_str, &ch, 1);
            } else if (ch == '\r') {
                angle = atof(angle_str);
                control_motor(angle);
                break;
            } else {
                printf("输入错误,请重新输入!\n");
                memset(angle_str, 0, sizeof(angle_str));
            }
        }
    }

    return 0;
}

说明:

程序使用conio.h头文件中的_kbhit()和_getch()函数来监听键盘事件。
定义了一个control_motor()函数,接受一个角度值作为输入,将其转换为电机控制信号,并发送给电机控制器。
在main()函数中,使用_getch()函数获取键盘输入,根据输入的字符构造角度字符串,然后使用atof()函数将字符串转换为浮点数。
当用户按下回车键时,将调用control_motor()函数控制电机转动。
程序使用memset()函数将角度字符串清空,以准备下一次输入。
请注意,程序仅仅是个示例,您需要将其适配到您实际的环境和设备上,包括电机控制器和电机转动信号的具体定义。

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7655935
  • 这篇博客也不错, 你可以看下用51单片机实现数码管显示输入的自然数
  • 除此之外, 这篇博客: 51单片机利用定时器中断制作秒表中的 单片机利用定时器中断制作秒表 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • #include
    #define LED P0
    
    sbit LA=P2^4; //对应着138译码器C,B,A端口
    sbit LB=P2^3;
    sbit LC=P2^2;
    
    sbit start=P3^1;//三个键控制开关和暂停
    sbit pulse=P3^0;
    sbit end=P3^2;
    
    char count; //中断次数定义
    unsigned  int sec; //秒数
    char i0,i1,i2,i3; //led数码管的0~4位
    unsigned char Display[10]= {0x3f,0x06,0x5b,0x4f,0x66,
                                0x6d,0x7d,0x07,0x7f,0x6f}; //led数码管段码
    void show(char j0,char j1,char j2,char j3); //显示秒数的函数
    void TransfromData(unsigned int sec); //数据处理,将秒数转换为个十百千万
    void Delay10ms(); //延时函数
    void main() 
    {
    	EA=1; //打开总中断
    	ET0=1;//打开定时器中断0
    	TMOD=0x01;//选择工作模式1
    	TH0=(65536-50000)/256;//定时50ms需要的高位初始化
    	TL0=(65536-50000)%6;//定时50ms需要的低位初始化    
      	while(1)
      	{
    		show(0,0,0,0);//未开始时显示0000
    
        	if(start==0 )
        	{
    			Delay10ms();//延时消抖
       			if(start==0)
      			{
    				TR0=1; //开始计数
    				while(pulse!=0 && end!=0) //未按下pulse或者时显示计时
    				{
    					TransfromData(sec);
    					show(i0,i1,i2,i3);
        			}
       
        			if(end==0)//按下end后的操作
    				{
    					TR0=0;
    					TH0=(65536-50000)/256;
          				TL0=(65536-50000)%6;
    					sec=0;
    					count=0;
    					//未下start的操作,一旦按下start可以跳出循环,由于按下按键有几十毫秒的时间
    					//在程序开始处仍然可以将start认为是按下的,又开始继续工作
    					while(start != 0)
    					{ 
        					show(0,0,0,0);
    					}
    				}
        			if(pulse==0)//按下pulse后的操作
        			{
        				TR0=0;
    					while(start != 0)
    					{
    						TransfromData(sec);
        					show(i0,i1,i2,i3);
    					}
    				TR0=1;
    				}
    			} 
    		}
    	}
    }
    void TransfromData(unsigned int s) {
    	i3=(s/1000);
    	i2=(s-i3*1000)/100;
    	i1=(s-i3*1000-100*i2)/10;
    	i0=s;
    }
    
    void int_T0() interrupt 1 {
    
    	TH0=(65536-50000)/256;
    	TL0=(65536-50000)%6;
    	count++;
    	if(count==20) 
    	{
    		sec++;
    		count=0;
    	}
    }
    void show(char j0,char j1,char j2,char j3)
    {
    	char i;
    	char j;
    	for(i=0; i<4; i++) 
    	{
    		switch(i) //通过switch语句进行段选和位选
    		{
    			case(0):LA=0;LB=0;LC=0;LED=Display[j0];break;
    			case(1):LA=0;LB=0;LC=1;LED=Display[j1];break;
       			case(2):LA=0;LB=1;LC=0;LED=Display[j2];break;
    			case(3):LA=0;LB=1;LC=1;LED=Display[j3];break;
    		}
    		j=10;while(j--) ;
    		LED=0x00;
    	}	
    }
    void Delay10ms()
    {
    	unsigned char i, j;
    	i = 108;
    	j = 145;
    	do
    	{
    		while (--j);
    	} 	while (--i);
    }
    
  • 您还可以看一下 朱有鹏老师的巫妖王51单片机开发板配套视频课程课程中的 选择巫妖王51单片机开发板的优势小节, 巩固相关知识点