热门标签 | 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

推荐阅读
  • 首先说一下,这是我在CSDN上的第一个文章,其实这个账号早在几年前就申请了,不过当时只是为了下载一个资源,而且也不怎么懂信息技术相关的领域,后来就再也没怎么动过,直到今天我才开始使用这个账号 ... [详细]
  • 手把手教你构建简易JSON解析器
    本文将带你深入了解JSON解析器的构建过程,通过实践掌握JSON解析的基本原理。适合所有对数据解析感兴趣的开发者。 ... [详细]
  • mysql 分库分表策略_【数据库】分库分表策略
    关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多, ... [详细]
  • 本文将详细介绍如何使用ViewPager实现多页面滑动切换,并探讨如何去掉其默认的左右切换动画效果。ViewPager是Android开发中常用的组件之一,用于实现屏幕间的内容切换。 ... [详细]
  • 本文介绍了如何在 Linux 系统上构建网络路由器,特别关注于使用 Zebra 软件实现动态路由功能。通过具体的案例,展示了如何配置 RIP 和 OSPF 协议,以及如何利用多路由器查看工具(MRLG)监控网络状态。 ... [详细]
  • 重构:优化现有代码设计(第二版)笔记
    本文介绍了重构的基本概念,通过具体示例展示了如何提炼函数以处理过长的代码段,并探讨了多种重构技术,如分阶段重构、封装变量等。 ... [详细]
  • 学习目的:1.了解android线程的使用2.了解主线程与子线程区别3.解析异步处理机制主线程与子线程:所谓主线程,在Windows窗体应用程序中一般指UI线程,这个是程序启动的时 ... [详细]
  • Web安全入门:MySQL基础操作与SQL注入防范
    本文详细介绍了MySQL数据库的基础操作命令,包括数据库和表的基本管理,以及数据的增删查改等常用操作。同时,针对Web安全领域常见的SQL注入问题,提供了初步的理解和防范措施。 ... [详细]
  • 本文详细介绍了MySQL中关于员工数据库的基础知识、操作技巧以及常见问题的解决方案,适合初学者和有一定基础的用户阅读。 ... [详细]
  • 导读上一篇讲了zsh的常用字符串操作,这篇开始讲更为琐碎的转义字符和格式化输出相关内容。包括转义字符、引号、print、printf的使用等等。其中很多内容没有必要记忆,作为手册参 ... [详细]
  • 题目概述:给定一个数组,计算其中所有连续子序列中平均值不低于给定值k的数量。通过将每个元素减去k并计算前缀和,问题转化为二维数点问题。此问题可以通过离线处理,利用树状数组来高效解决。 ... [详细]
  • 解决PHP与MySQL之间的编码不匹配问题
    探讨如何有效解决PHP与MySQL之间常见的编码问题,确保数据的正确传输与显示。 ... [详细]
  • A题简单判断#includeusingnamespacestd;typedeflonglongll;intt;intmain(){cint;whil ... [详细]
  • 本文介绍如何利用C语言在Linux操作系统中实现递归创建多级目录的功能,包括必要的头文件引入和函数实现。 ... [详细]
  • 本文探讨如何使用C语言开发一个座位分配系统,包括飞机座位选择、考场座位随机分配等功能,并提供了详细的代码示例。 ... [详细]
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社区 版权所有