基于C51的步进电机控制器设计

  • 设计任务
  • 一、步进电机是什么
  • 二、程序设计
    • 1.流程图
    • 2.定时器中断调速程序
    • 3.怎么可能只有一种写法呢?
  • 总结
    • 写在最后

提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 设计任务
  • 一、步进电机是什么
  • 二、程序设计
    • 1.流程图
    • 2.定时器中断调速程序
    • 3.怎么可能只有一种写法呢?
  • 总结
    • 写在最后

设计任务

控制器有三种运转模式:连续模式、点动模式、行程模式。四位数码管,从左到右,第一位显示模式,第二位显示方向,三四位显示速度或行程。各模式间采用<模式>键切换。
(1)连续模式:可以用+、—键增减速,FWR、REV键调整正反方向,<启/停>键启动或停止电机连续运转。
(2)点动模式:FWR为正转、REV为反转,按键不松开,电机一直运转。
(3)行程模式:可以用+、—键设置一个行程,<启/停>键启动电机运转,步进电机自动先加速,再匀速,最后减速停止走完整个行程。


提示:以下是本篇文章正文内容,下面案例可供参考

一、步进电机是什么

本次使用的是五线四项步进电机28BYJ-48,八拍工作。L298N中VCC接5V,可正常工作。由于这款步进电机本身有1:64的减速比,所以程序装载后速度较慢,想加速在改变参数后电机本身会出现堵转、丢步等现象。

对步进电机工作原理不是很了解的同学可以百度一下哈,不过不用过于深究这个问题,接好线之后上手做就完事了,奥利给~

二、程序设计

1.流程图

大概是流程图吧,可能画的不太规范。

2.定时器中断调速程序

代码如下(示例):

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int#define MotorData P0                 //步进电机控制接口定义sbit plus=P2^0;                     //独立按键接口定义
sbit minus=P2^1;
sbit FWR=P2^2;
sbit REV=P2^3;
sbit start=P2^4;
sbit stop=P2^5;
sbit modelTranslat=P2^7;sbit DI1=P1^0;                        //数码管接口定义
sbit DI2=P1^1;
sbit DI3=P1^2;
sbit DI4=P1^3;
sbit DIO=P1^4;
sbit RCK=P1^5;
sbit SCLK=P1^6;uchar phasecw[8] = {0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//正转导通相序uchar DIG_CODE[11] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//数码管段选  以0起始uint modelFlag=0,directionFlag=0,speedNnumber=5,stepNnumber=0,stepTrue=0,startFlag=0xff,order=0;
//定时器中断  时间初始化 相序标记赋值
void Time0() interrupt 1 {uint speedTrue=2000*(10-speedNnumber); TH0=(65536-speedTrue)/256;TL0=(65536-speedTrue)%256;if(order==7){order=-1;}order+=1;
}
//小延时
void delay(uint i){while(i--);
}
//ms延时函数
void Delay_xms(uint x){uint i,j;for(i=0;i<x;i++){for(j=0;j<112;j++);}
}
//拆分并将待显示数据送达数码管   段选
void transitData(uchar display_data){uint i;SCLK=0;RCK=0;for(i=0;i<8;i++){SCLK=0;if((display_data<<i)&0x80){DIO=1;}else DIO=0;SCLK=1; }RCK=1;
}
//分模式对显示数据位选  调用段选  延时消隐
void Dislay(){if(modelFlag==0){DI1=1;DI2=0;DI3=0;DI4=0;transitData(DIG_CODE[modelFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=1;DI3=0;DI4=0;transitData(DIG_CODE[directionFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=1;DI4=0;transitData(DIG_CODE[0]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=0;DI4=1;transitData(DIG_CODE[speedNnumber]);delay(1);transitData(DIG_CODE[10]);}if(modelFlag==1){DI1=1;DI2=0;DI3=0;DI4=0;transitData(DIG_CODE[modelFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=1;DI3=0;DI4=0;transitData(DIG_CODE[directionFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=1;DI4=0;transitData(DIG_CODE[0]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=0;DI4=1;transitData(DIG_CODE[speedNnumber]);delay(1);transitData(DIG_CODE[10]);}if(modelFlag==2){uint disStep=stepNnumber-(stepTrue/512);DI1=1;DI2=0;DI3=0;DI4=0;transitData(DIG_CODE[modelFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=1;DI3=0;DI4=0;transitData(DIG_CODE[directionFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=1;DI4=0;transitData(DIG_CODE[disStep/10]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=0;DI4=1;transitData(DIG_CODE[disStep%10]);delay(1);transitData(DIG_CODE[10]);}
}
//按键检测 标记赋值
void Keyscan(){//模式按键检测if(modelTranslat==0){Delay_xms(1);if(modelTranslat==0){if(modelFlag==2){modelFlag=0;  }else modelFlag+=1;               }Delay_xms(200);//松手检测      }//+-分模式判断if(plus==0 || minus==0){Delay_xms(1);if(modelFlag==0){if(plus==0){if(speedNnumber==9){speedNnumber=-1;}speedNnumber+=1;                             }if(minus==0){if(speedNnumber==0){speedNnumber=10;}speedNnumber-=1;           }                       }if(modelFlag==1){if(plus==0){              if(speedNnumber==9){speedNnumber=-1;}speedNnumber+=1;              }if(minus==0){                if(speedNnumber==0){speedNnumber=10;}speedNnumber-=1;           }                       }//+不设上限 —不能为负if(modelFlag==2){if(plus==0){stepNnumber+=1;               }if(minus==0){if(stepNnumber==0){stepNnumber=5;}stepNnumber-=1;                           }}Delay_xms(200);//松手检测}//方向键切换   正转标记为0  反转为1if(FWR==0){Delay_xms(10);if(FWR==0){directionFlag=0;     }}if(REV==0){Delay_xms(10);if(REV==0){directionFlag=1;     }}//启停标记  启动标记为0 停止为1if(start==0){startFlag=0;}if(stop==0){startFlag=1;}
}
//顺时针转动
void MotorCW(){MotorData=phasecw[order];TR0=1;    stepTrue+=1;
}
//逆时针转动
void MotorCCW(){MotorData=phasecw[7-order];TR0=1;     stepTrue+=1;
}
//停止转动
void MotorStop(){MotorData=0x00;stepTrue=0;stepNnumber=0;startFlag=0xff;TR0=0;
}
//分模式调电机正反转
void modelFirst(){if(directionFlag){MotorCCW();     }else{MotorCW();                        }
}
void modelSecond(){if(FWR==0){MotorCW();  }if(REV==0){MotorCCW();}
}
void modelThird(){uint stepTarget=(stepNnumber*1024);//64*8=512   实测45°uint i,j;if(!directionFlag){for(i=0;i<stepTarget;i++){MotorCW(); }}else{for(i=0;i<stepTarget;i++){MotorCCW();              }}MotorStop();
}void main(){Delay_xms(50);//等待系统稳定TMOD=0X01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;while(1){Keyscan();Dislay();if(startFlag==0){                    switch(modelFlag){case(0):modelFirst();break;case(1):modelSecond();break;case(2):modelThird();break;default:break;               }}if(startFlag==1){MotorStop();  }     }
}

3.怎么可能只有一种写法呢?

第二种调速方式:延时
我个人感觉这种做法有点耍赖皮的感觉,而且实际上机测试的时候数码管的显示效果会差很多,就断断续续的感觉,也有可能是八拍工作方式的问题,时间会有点久,如果换成四拍工作方式的话效果可能会好一些,有兴趣的同志们可以用四拍导通相序来试一下。
代码如下(示例):

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int#define MotorData P0                 //步进电机控制接口定义sbit plus=P2^0;                     //独立按键接口定义
sbit minus=P2^1;
sbit FWR=P2^2;
sbit REV=P2^3;
sbit start=P2^4;
sbit stop=P2^5;
sbit modelTranslat=P2^7;sbit DI1=P1^0;                        //数码管接口定义
sbit DI2=P1^1;
sbit DI3=P1^2;
sbit DI4=P1^3;
sbit DIO=P1^4;
sbit RCK=P1^5;
sbit SCLK=P1^6;uchar phasecw[8] ={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//正转导通相序
uchar phaseccw[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};//反转导通相序 uchar DIG_CODE[11] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00};//数码管段选  以0起始uint modelFlag=0,directionFlag=0,speedNnumber=5,stepNnumber=0,stepTrue=0,startFlag=0xff;
//小延时
void delay(uint i){while(i--);
}
//ms延时函数
void Delay_xms(uint x){uint i,j;for(i=0;i<x;i++){for(j=0;j<112;j++);}
}void transitData(uchar display_data){uint i;SCLK=0;RCK=0;for(i=0;i<8;i++){SCLK=0;if((display_data<<i)&0x80){DIO=1;}else DIO=0;SCLK=1; }RCK=1;
}void Dislay(){if(modelFlag==0){DI1=1;DI2=0;DI3=0;DI4=0;transitData(DIG_CODE[modelFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=1;DI3=0;DI4=0;transitData(DIG_CODE[directionFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=1;DI4=0;transitData(DIG_CODE[0]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=0;DI4=1;transitData(DIG_CODE[speedNnumber]);delay(1);transitData(DIG_CODE[10]);}if(modelFlag==1){DI1=1;DI2=0;DI3=0;DI4=0;transitData(DIG_CODE[modelFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=1;DI3=0;DI4=0;transitData(DIG_CODE[directionFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=1;DI4=0;transitData(DIG_CODE[0]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=0;DI4=1;transitData(DIG_CODE[speedNnumber]);delay(1);transitData(DIG_CODE[10]);}if(modelFlag==2){uint disStep=stepNnumber-(stepTrue/64);DI1=1;DI2=0;DI3=0;DI4=0;transitData(DIG_CODE[modelFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=1;DI3=0;DI4=0;transitData(DIG_CODE[directionFlag]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=1;DI4=0;transitData(DIG_CODE[disStep/10]);delay(1);transitData(DIG_CODE[10]);DI1=0;DI2=0;DI3=0;DI4=1;transitData(DIG_CODE[disStep%10]);delay(1);transitData(DIG_CODE[10]);}
}void Keyscan(){//模式按键检测if(modelTranslat==0){Delay_xms(1);if(modelTranslat==0){if(modelFlag==2){modelFlag=0; }else modelFlag+=1;               }Delay_xms(200);//松手检测      }//+-分模式判断if(plus==0 || minus==0){Delay_xms(1);if(modelFlag==0){if(plus==0){if(speedNnumber==9){speedNnumber=-1;}speedNnumber+=1;                             }if(minus==0){if(speedNnumber==0){speedNnumber=10;}speedNnumber-=1;           }                       }if(modelFlag==1){if(plus==0){              if(speedNnumber==9){speedNnumber=-1;}speedNnumber+=1;              }if(minus==0){                if(speedNnumber==0){speedNnumber=10;}speedNnumber-=1;           }                       }//+不设上限 —不能为负if(modelFlag==2){if(plus==0){stepNnumber+=1;               }if(minus==0){if(stepNnumber==0){stepNnumber=5;}stepNnumber-=1;                           }}Delay_xms(200);//松手检测}//方向键切换   正转标记为0  反转为1if(FWR==0){Delay_xms(10);if(FWR==0){directionFlag=0;     }}if(REV==0){Delay_xms(10);if(REV==0){directionFlag=1;     }}//启停标记  启动标记为0 停止为1if(start==0){startFlag=0;}if(stop==0){startFlag=1;}
}//顺时针转动
void MotorCW(){uchar i;for(i=0;i<8;i++){//Dislay();MotorData=phasecw[i];Delay_xms(10-speedNnumber);//转速调节//Dislay();}stepTrue+=1;
}
//逆时针转动
void MotorCCW(){uchar i;for(i=0;i<8;i++){//Dislay();MotorData=phaseccw[i];Delay_xms(10-speedNnumber);//转速调节//Dislay();}stepTrue+=1;
}
//停止转动
void MotorStop(){MotorData=0x00;stepTrue=0;stepNnumber=0;startFlag=0xff;
}void modelFirst(){if(directionFlag){MotorCCW();        }else{MotorCW();                        }
}void modelSecond(){if(FWR==0){MotorCW(); }if(REV==0){MotorCCW();}
}void modelThird(){uint stepTarget=(stepNnumber*64);uint i;if(!directionFlag){for(i=0;i<stepTarget;i++){MotorCW();   }}else{for(i=0;i<stepTarget;i++){MotorCCW();  }}MotorStop();
}//主函数
void main(){Delay_xms(50);//等待系统稳定while(1){Keyscan();Dislay();if(startFlag==0){                   switch(modelFlag){case(0):modelFirst();break;case(1):modelSecond();break;case(2):modelThird();break;default:break;               }}if(startFlag==1){MotorStop();  }     }
}

总结

以上就是我对本次实习任务的程序总结,其实这次实习让我收获最大的就是排查问题的思维方式,将可能导致问题出现的原因都穷举出来,想清楚了以后一项一项的检查,可以按照个人直觉(按可能性从高到低的去查),也可将原因分层,逐级排查,,一定要有耐心不要着急,最后一定是能够完成的。

写在最后

针对程序如有疑问可以私信联系我,看到之后我会尽力解答。祝大家学业有成&别墅靠海&终成眷属!

基于C51的步进电机控制器设计相关推荐

  1. 基于8086的步进电机控制器设计(计算机接口技术设计报告)

    注:图片展示连线未跑通,因为我们不需要交工程文件,只用交word,时间比较紧,大体上理论是正确的.我的未跑通仿真文件 文章目录 题目设计要求 一.概述 二.硬件设计方案 三.硬件详细设计 1.总线模块 ...

  2. matlab设计风电机外部控制器,【matlab编程代做】步进电机控制器设计

    <[matlab编程代做]步进电机控制器设计>由会员分享,可在线阅读,更多相关<[matlab编程代做]步进电机控制器设计(8页珍藏版)>请在人人文库网上搜索. 1.步进电机控 ...

  3. 步进电机控制器设计 利用Quartus ii9.0设计一个具有四相单四拍

    步进电机控制器设计 利用Quartus ii9.0设计一个具有四相单四拍,四相双四拍和四相八拍的脉冲分配器.设计一个三选一数据选择器来控制pause信号选择工作方式,以及用两个74160与两个7447 ...

  4. 基于 FPGA 的 UART 控制器设计(VHDL)(下)

    今天给大侠带来基于FPGA的 UART 控制器设计(VHDL)(下),由于篇幅较长,分三篇.今天带来第三篇,下篇,使用 FPGA 实现 UART.话不多说,上货. 之前有关于 Veriliog HDL ...

  5. 彩灯控制器课程设计vhdl_基于VHDL的彩灯控制器设计与实现毕业设计(DOC毕业设计论文)...

    基于VHDL的彩灯控制器设计与实现毕业设计(DOC毕业设计论文) <计算机组成原理>课程设计报告目 录任务书 .2摘 要 .5Abstract .61 引 言 71.1VHDL 技术介绍7 ...

  6. 【Simulink教程案例1】基于Simulink的PID控制器设计与实现

    欢迎订阅<FPGA/MATLAB/SIMULINK系列教程> 目录 1.软件版本 2.PID控制器理论概述 3.基于Simulink的PID控制器设计

  7. 【Simulink教程案例2】基于Simulink的模糊控制器设计与实现

    欢迎订阅<FPGA/MATLAB/SIMULINK系列教程> 目录 1.软件版本 2.模糊控制器理论详细介绍 3.基于Simulink的模糊控制器设计

  8. 步进电机控制器设计 利用Quartus ii9.0设计一个具有四相单四拍,四相双四拍和四相八拍的脉冲分配器

    步进电机控制器设计 利用Quartus ii9.0设计一个具有四相单四拍,四相双四拍和四相八拍的脉冲分配器. 设计一个三选一数据选择器来控制pause信号选择工作方式,以及用两个74160与两个744 ...

  9. 基于FPGA的SDRAM控制器设计(二)

    基于FPGA的SDRAM控制器设计(二) 1. SDRAM理论基础 2. SDRAM初始化模块以及仿真 3.TOP模块的仲裁机制 4. SDRAM刷新模块代码以及仿真 5.代码 6.参考资料 1. S ...

  10. 七、基于FPGA的Flash控制器设计

    根据项目需求,设计一个Flash控制器.以便将完成低速数据的存储.Flash选用了S25FL032.使用单线SPI接口,接线如图: 1,Flash S25fl032介绍 1.1 IO描述 1.2 相关 ...

最新文章

  1. idea 提示vue插件_Vue + SpringBoot + MyBatis 音乐网站
  2. 力扣合并两个有序数组
  3. BZOJ2216 [Poi2011]Lightning Conductor 【决策单调性dp】
  4. 使用IDA Pro动态调试SO文件
  5. 新鲜出炉 | 临床基因组学数据分析实战开课啦!!!
  6. k-means算法实现python
  7. docker跑codalab_Codalab使用与采坑
  8. 快速列出所有字段_【小麦课堂】快速查询明细数据的操作
  9. yum安装时出现:Cannot retrieve metalink for repository: epel. Please verify its path and try again
  10. mac 黑窗口连接mysql_macOS -- Mac系统如何通过终端使用mysql
  11. java求立方体表面积和体积_设计一个立方体类BOX,它能计算并输出立方体的体积和表面积...
  12. 神经网络与深度学习(第一章)(五)
  13. 衡量现金分红收益率的指标——股息率
  14. 微信赌场——H5棋牌游戏渗透之旅
  15. Houdini图文笔记:用Houdini实现随机自然倒角
  16. R绘图 第八篇:绘制饼图(ggplot2)
  17. 前端从后端导出excel表格文件的两种方法
  18. python bins分箱,划分数值区间
  19. flowable中强制结束流程
  20. 2019,塞翁失马,败走麦城

热门文章

  1. (转)Oracle数据库资料收藏
  2. 在VirtualBox中安装WindowsXP
  3. 长安大学微型计算机原理与接口技术答案,长安大学微机原理与接口技术AB卷试题与答案.doc...
  4. 杰奇为什么只能用php5.2,若夏小说新版 杰奇最新2.2专业版内核 WAP端+电脑端+在线充值+关关采集器(送规则)...
  5. 杰奇reader.php源码,最新杰奇CMS Jieqi V2.4 静思文学源码全解密开源版完整源码分享,附带关关采集杰奇V3.5版程序...
  6. html表单与表格,HTML--表格与表单(示例代码)
  7. 西电微原课设——矩阵式键盘数字密码锁设计
  8. 耗时162天,从华为外包5k转岗正式员工15k,经历的心酸只有自己知道
  9. 计算机处理技术职业道德与论文,计算机职业道德j论文.doc
  10. 从软件开发到 AI 领域工程师:模型训练篇