热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于Protues的步进电机仿真与控制技术研究

本文基于Proteus平台,对步进电机的仿真与控制技术进行了深入研究。通过修改代码,实现了步进电机精确转动1圈的控制。实验结果验证了该方法的有效性和可靠性,为步进电机在精密控制领域的应用提供了有力支持。

步进电机圈数测试

在这里插入图片描述
下面代码已经修改过,圈数改为1圈

/*************** writer:shopping.w ******************/
#include
#define uint unsigned int
#define uchar unsigned char
uchar code FFW[]=
{0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09
};uchar code REV[]=
{0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01
};sbit K1 = P3^0;
sbit K2 = P3^1;
sbit K3 = P3^2;void DelayMS(uint ms)
{uchar i;while(ms--){for(i&#61;0;i<120;i&#43;&#43;);}
}void SETP_MOTOR_FFW(uchar n)
{uchar i,j;for(i&#61;0;i<1*n;i&#43;&#43;) //n控制圈数&#xff0c;运行1次&#xff0c;正转144°&#xff0c;转够5次&#xff0c;电机才能回到0°{for(j&#61;0;j<8;j&#43;&#43;){if(K3 &#61;&#61; 0) break;P1 &#61; FFW[j];DelayMS(100);}}
}void SETP_MOTOR_REV(uchar n)
{uchar i,j;for(i&#61;0;i<5*n;i&#43;&#43;){for(j&#61;0;j<8;j&#43;&#43;){if(K3 &#61;&#61; 0) break;P1 &#61; REV[j];DelayMS(25);}}
}void main()
{uchar N &#61; 1;while(1){if(K1 &#61;&#61; 0)//正转{P0 &#61; 0xfe;SETP_MOTOR_FFW(N);if(K3 &#61;&#61; 0) break;}else if(K2 &#61;&#61; 0)//反转{P0 &#61; 0xfd;SETP_MOTOR_REV(N);if(K3 &#61;&#61; 0) break;}else//停止{P0 &#61; 0xfb;P1 &#61; 0x03;}}
}

步进电机速度测试&#xff08;用延迟进行调速&#xff09;&#43;按键控制&#43;数码管显示延迟时间

在这里插入图片描述
上图有点杂乱&#xff0c;下面代码只用到&#xff1a;数码管&#xff0c;AT89c51芯片&#xff0c;步进电机&#xff0c;ULN2003A驱动&#xff0c;按键

#include "main.h"
#include
#include "Stepper motor.h"unsigned int Sec_5&#61;0,Sec_4&#61;0,Sec_3&#61;0 ,Sec_2 &#61; 0,Sec_1 &#61; 0,Sec_0&#61;0;//千百十个位数字
code unsigned char table[] &#61; { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
code unsigned char chage[] &#61; { 0xfe,0xfd,0xfb,0xf7,0xef,0xdf };//2-7位//显示位{}
//主函数 0 1 2 3 4 5 unsigned int c &#61; 0;//位数刷新
unsigned int cnt &#61; 0;//数码管刷新时间
unsigned long int time &#61; 1;//电机转动延迟时间
unsigned int num ;
unsigned int Sec &#61; 0;//时间单位&#xff0c;秒
unsigned int mode &#61; 1;//按键模式&#xff08;正转&#xff09;//**********************************************************
//主函数
//**********************************************************
void main()
{Init_Timer0();while(1){scan_key();//按键扫描if(mode&#61;&#61;0)Phase_B();if(mode&#61;&#61;1)Phase_A();if(mode&#61;&#61;2)move&#61;0x03;//复位delay_10um(time);}
}//****************************************************
//初始化定时器1
//****************************************************
void Init_Timer0()
{TMOD &#61; 0X01; //T0, 工作模式1TH0 &#61; (65536 - 10000)/256;TL0 &#61; (65536 - 10000)%256;TR0 &#61; 1; //开启定时器ET0 &#61; 1; //开启定时器中断EA &#61; 1; //开启总中断
}//*****************************************************
//中断函数
//****************************************************
void Timer0() interrupt 1
{TH0 &#61; (65536 - 1000)/256;//1ms 定时 模式1非自动重装需要手动重装再次定时TL0 &#61; (65536 - 1000)%256;//刷新显示 c个位Sec&#43;&#43;;cnt&#43;&#43;;num&#61;time;
//数据处理Sec_0 &#61; num%10;Sec_1 &#61; num/10%10;Sec_2 &#61; num/100%10;Sec_3 &#61; num/1000%10;Sec_4 &#61; num/10000%10;Sec_5 &#61; num/100000;
//每1000us*10&#61;10ms刷新一次if(cnt&#61;&#61;10){cnt&#61;0;SEG_DATA&#61;0x00;delay_10um(10);COM0&#61;chage[c]; switch(c){case 5:SEG_DATA&#61;table[Sec_0];break;//显示万位case 4:SEG_DATA&#61;table[Sec_1];break;//显示千位case 3:SEG_DATA&#61;table[Sec_2];break;//显示百位case 2:SEG_DATA&#61;table[Sec_3];break;//显示十位case 1:SEG_DATA&#61;table[Sec_4];break;//显示个位case 0:SEG_DATA&#61;table[Sec_5];break;//显示单位default:break;}c&#43;&#43;;if(c&#61;&#61;6)c&#61;0;}//1000*1ms&#61;1s刷新一次
if(Sec&#61;&#61;1000)//这个判断必须有&#xff0c;也不能在其他地方&#xff0c;不然不能刷新显示&#xff01;&#xff01;&#xff01;我也不清楚&#xff0c;调试了好久{Sec&#61;0; //num&#43;&#43;; 测试数码管显示&#xff0c;每1s数字加1}
}
//*******************************************************************************
//按键扫描
//*******************************************************************************
void scan_key()
{//-------------------------------------------------//电机正转if(key1&#61;&#61;0)//正转{mode&#61;1;}
// while(key1&#61;&#61;0);//-------------------------------------------------//电机反转if(key2&#61;&#61;0)//反转{mode&#61;0;}
// while(key2&#61;&#61;0);//-------------------------------------------------//电机停止if(key3&#61;&#61;0){mode&#61;2;}while(key3&#61;&#61;0);//-------------------------------------------------//转速调控if(key4&#61;&#61;0){time-&#61;1;delay_10um(10);if(time&#61;&#61;-1)time&#61;100;
// num&#43;&#43;;
// if(num&#61;&#61;3)
// num&#61;0;
// switch(num)
// {
// case 0:time&#61;100;break;
// case 1:time&#61;300;break;
// case 2:time&#61;50;break;
// }}
// while(key4&#61;&#61;0);//-------------------------------------------------}//延时n毫秒
void Delay_ms(unsigned int n)
{unsigned int i&#61;0,j&#61;0;for(i&#61;0;i<n;i&#43;&#43;)for(j&#61;0;j<123;j&#43;&#43;);
}//延时10*n微秒
void delay_10um(unsigned int n)
{while(n--);
}

main.c头文件

#ifndef __MAIN__H__
#define __MAIN__H__#include
#define COM0 P0
#define SEG_DATA P2sbit key1&#61;P3^0;
sbit key2&#61;P3^1;
sbit key3&#61;P3^2;
sbit key4&#61;P3^3;//函数声明
extern void Delay_ms( unsigned int m);
extern void delay_10um( unsigned int n);
extern void Init_Timer0();
extern void scan_key();
extern void forward();//extern void Phase_B();
//extern void Phase_C();
//extern void Phase_D();
extern unsigned long int time;#endif

下面是步进电机控制程序&#xff0c;每执行一次&#xff0c;转一个指定的角度

#include "Stepper motor.h"unsigned int a&#61; 0;
unsigned char code right[8]&#61;{0x03,0x02,0x06,0x04,0x0c,0x08,0x09,0x01,}; //顺时针A-AB-B-BC-C-CD-D-DA 方法四使用void Phase_A()//正转
{
//方法一
// switch(cnt)
// {
// case 0: move&#61;0x01;break;
// case 1: move&#61;0x03;break;
// case 2: move&#61;0x02;break;
// case 3: move&#61;0x06;break;
// case 4: move&#61;0x04;break;
// case 5: move&#61;0x0c;break;
// case 6: move&#61;0x08;break;
// case 7: move&#61;0x09;break;
// default:break;
// }
// cnt&#43;&#43;;
// if(cnt&#61;&#61;8)
// cnt&#61;0;
//方法二
// for(;a<8;a&#43;&#43;)//方法三
// move&#61;0x01<
// if(a&#61;&#61;4)a&#61;0;
//
//方法四move&#61;right[a&#43;&#43;];if(a&#61;&#61;8)a&#61;0;
}void Phase_B()//反转
{move&#61;right[a--];if(a&#61;&#61;-1)a&#61;7;
}

Stepper motor.h头文件

#ifndef __STEPPER MOTOR__H__
#define __STEPPER MOTOR__H__#include #define move P1
extern void Phase_A();
extern void Phase_B();//extern void delay_ms( unsigned int m);#endif

推荐阅读
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • Splay Tree 区间操作优化
    本文详细介绍了使用Splay Tree进行区间操作的实现方法,包括插入、删除、修改、翻转和求和等操作。通过这些操作,可以高效地处理动态序列问题,并且代码实现具有一定的挑战性,有助于编程能力的提升。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 文件描述符、文件句柄与打开文件之间的关联解析
    本文详细探讨了文件描述符、文件句柄和打开文件之间的关系,通过具体示例解释了它们在操作系统中的作用及其相互影响。 ... [详细]
  • 基因组浏览器中的Wig格式解析
    本文详细介绍了Wiggle(Wig)格式及其在基因组浏览器中的应用,涵盖variableStep和fixedStep两种主要格式的特点、适用场景及具体使用方法。同时,还提供了关于数据值和自定义参数的补充信息。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • Java 中 Writer flush()方法,示例 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
author-avatar
到几百元_309
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有