51单片机控制的步进电机C语言程序文件
大学毕业设计 C51程序控制步进电机

题目:简易步进电机控制步进电机控制摘要:本设计采用ATMEL公司DIP-40封装的AT89S52单片机实现对四相步进电机的手动和按键控制。
由单片机产生的脉冲信号经过分配后分解出对应的四相脉冲,分解出的四相脉冲经驱动电路功率放大后驱动步进电机的转动。
转速的调节和状态的改变由按键进行选择,此过程由程序直接进行控制。
通过键盘扫描把选择的信息反馈给单片机,单片机根据反馈信息做出相应的判断并改变输出脉冲的频率或转动状态信号。
电机转动的不同状态由液晶LCD1602显示出来。
而设计的扩展部分可以通过红外信号的发射由另一块单片机和红外线LED完成,用红外万能接收头接收红外信号,可以实现对电机的控制进行红外遥控。
关键字:四相步进电机单片机功率放大 LCD1602步进电机控制 (1)摘要 (1)关键字 (1)前言 (3)1系统总体方案设计及硬件设计 (4)1.1步进电机 (4)1.1.1 步进电机的种类 (4)1.1.2 步进电机的特点 (4)1.1.3 步进电机的原理 (5)1.2 控制系统电路设计 (7)1.3 液晶显示LCD1602 (7)1.4 AT89S52核心部件及系统SCH原理图 (9)1.5 LN2003A驱动 (10)2软件设计及调试 (13)2.1程序流程 (13)2.2软件设计及调试 (14)3 扩展功能说明 (15)4设计总结 (16)5 设计源程序 (16)6 附录 (21)参考文献 (22)附2:系统原理图及实物图 (23)步进电机广泛应用于对精度要求比较高的运动控制系统中,如机器人、打印机、软盘驱动器、绘图仪、机械阀门控制器等。
目前,对步进电机的控制主要有由分散器件组成的环形脉冲分配器、软件环形脉冲分配器、专用集成芯片环形脉冲分配器等。
分散器件组成的环形脉冲分配器体积比较大,同时由于分散器件的延时,其可靠性大大降低;软件环形分配器要占用主机的运行时间,降低了速度;专用集成芯片环形脉冲分配器集成度高、可靠性好,但其适应性受到限制,同时开发周期长、需求费用较高。
单片机控制步进电机系统(C语言源代码)

题目:单片机控制步进电机系统摘要很多工业控制设备对位移和角度的控制精度要求较高, 一般电机很难实现, 而步进电机可精确实现所设定的角度和转数。
本设计主要是运用51 单片机控制六线4相步进电机系统, 由单片机产生驱动脉冲信号, 控制步进电机以一定的转速向某一方向产生一定的转动角度。
同时能够利用单片机实现电机的正、反转及速度控制,并能在数码管上显示出相应的速度。
本文中给出了该系统设计的硬件电路,软件设计,人机交互等。
并对各个功能模块进行了详细的说明。
主要内容包括以下几个方面:单片机控制步进电机的一般原理。
电机驱动及控制的实现。
控制系统整体设计以及模块划分说明。
原理图。
代码。
关键词:单片机;步进电机;系统;驱动AbstractMany Industrial control equipment have a highly requirement in displacement and angle with control accuracy, the most motor can't carry out .but the step motor can carry out the displacement and angle that you enactmented in accuracy. This design mainly used SCM to control step motor system.The step motor is formed six lines and four phasic.Through SCM generate the drive pulse signal.Control stepper motor through a certain speed in a direction to get a certain degree of rotation angle.At the same time, It can use SCM to realization of the motor is , reverse and speed control. and showed the speed in the digital tube.In this paper, given the design of the system hardware circuit,software design, human-computer interaction and so on.and it given the details description of each functional module.the main contents include the following:(1) The general principles of signal_chip controlling step motor.(2) The realization of motor driving and controlling(3) Control system overall design and description module division(4) Schematic Diagram(5) CodeKey Words:SCM; stepper motor; system; drive目录引言41 单片机控制步进电机的一般原理41.1 步进电机41.1.1 步进电机介绍41.1.2 步进电机分类51.1.3 技术指标51.1.4 步进电机工作原理51.2 单片机72 步进电机驱动实现82.1简介82.2驱动选择83 系统硬件设计93. 1 单片机控制电机93.2 键盘93.3 显示部分10程序流程图11总结12致谢13参考文献13附录13C代码13引言目前,在工业控制生产以及仪器上应用十分广泛。
c语言实现单片机控制步进电机加减速源程序

C 语言实现单片机控制步进电机加减速源程序1. 引言在现代工业控制系统中,步进电机作为一种常见的执行元件,广泛应用于各种自动化设备中。
而作为一种常见的嵌入式软件开发语言,C 语言在单片机控制步进电机的加减速过程中具有重要的作用。
本文将从单片机控制步进电机的加减速原理入手,结合 C 语言的编程技巧,介绍如何实现单片机控制步进电机的加减速源程序。
2. 单片机控制步进电机的加减速原理步进电机是一种能够精确控制角度的电机,它通过控制每个步骤的脉冲数来实现旋转。
在单片机控制步进电机的加减速过程中,需要考虑步进电机的加速阶段、匀速阶段和减速阶段。
在加速阶段,需要逐渐增加脉冲的频率,使步进电机的转速逐渐增加;在匀速阶段,需要保持恒定的脉冲频率,使步进电机以匀速旋转;在减速阶段,需要逐渐减小脉冲的频率,使步进电机的转速逐渐减小。
这一过程需要通过单片机的定时器和输出控制来实现。
3. C 语言实现步进电机加减速的源程序在 C 语言中,可以通过操作单片机的 GPIO 来控制步进电机的旋转。
在编写源程序时,需要使用单片机的定时器模块来生成脉冲信号,以控制步进电机的旋转角度和速度。
以下是一个简单的 C 语言源程序,用于实现步进电机的加减速控制:```c#include <reg52.h>void main() {// 初始化定时器// 设置脉冲频率,控制步进电机的加减速过程// 控制步进电机的方向// 控制步进电机的启停}```4. 总结与回顾通过本文的介绍,我们了解了单片机控制步进电机的加减速原理和 C 语言实现步进电机加减速源程序的基本思路。
掌握这些知识之后,我们可以更灵活地应用在实际的嵌入式系统开发中。
在实际项目中,我们还可以根据具体的步进电机型号和控制要求,进一步优化 C 语言源程序,实现更加精准和稳定的步进电机控制。
希望本文能为读者在单片机控制步进电机方面的学习和应用提供一定的帮助。
5. 个人观点与理解在我看来,掌握 C 语言实现单片机控制步进电机加减速源程序的技术是非常重要的。
51单片机上画圆弧任意2点坐标就控制步进电机

#ifndef _MAIN_C_#define _MAIN_C_#include "config.h"#include "lcd1602.h"typedef unsigned char uint8;typedef signed char int8;typedef signed int int16;typedef unsigned int uint16;unsigned char T0RH;T0RL;unsigned int time_count=0;unsigned char n=0;unsigned char pdata str[12];int16 x_start_value=0;int16 y_start_value=0;int16 x_finish_value=0;int16 y_finish_value=0;int16 a;int16 b;int16 x;int16 y;int16 ox;int16 oy;int16 px[2],py[2];int16 r;int16 x_g2;int16 y_g2;int16 x_g3;int16 y_g3;int16 flag_3=0;//F 误差系数uint16 flag_finish=0;uint8 flag_xiangxian=0;unsigned char flag_g=0; //flag_g=0;flag_g=1,flag_g=2,flag_g=3; unsigned char div=0;unsigned char curr_index=0;unsigned char index=0;#define NUM_AS 2typedef struct node{signed int xe;signed int ye;unsigned char flag_g;signed int R;}lnode;//typedef struct node lnode;struct list{signed int x0;signed int y0;signed int xv;signed int yv;unsigned char num;unsigned char state;lnode vlist[8];};typedef struct list sqlist;typedef struct list *sqlist_ptr;/////////////////////////////////////////void configtime0(unsigned int ms);void xiangxian();void init();void addx();void backx();void addy();void backy();void panduan();void getarc(int16 xs,int16 ys,int16 xe,int16 ye);void f(int16 x1,int16 y1,int16 x2,int16 y2);void Draw_polygon2D(sqlist_ptr poly);void main(){ //sqlist idata L[1];//lnode xdata p[22]=0;lnode xdata s[]={{0,0,0,0},{0,400,1,800},{200,600,2,200},{600,600,1,0},{800,400,2,200},{800,0,1,0},{400, 400,2,400},{0,0,2,400}};//lnode xdata s[]={200,600,2,200};//init_mempool(p,sizeof(p));//sqlist_ptr L_ptr;for(curr_index=0;curr_index<2;curr_index++){L[curr_index].state=1;L[curr_index].x0=0;L[curr_index].y0=0;L[curr_index].xv=0;L[curr_index].yv=0;L[curr_index].num=8;//sizeof(s)/sizeof(lnode); //8// L[curr_index].vlist=(lnode *)malloc(8*sizeof(lnode));//L[curr_index].vlist=s;//for(index=0;index<L[curr_index].num;index++){L[curr_index].vlist[index].xe=s[index].xe;L[curr_index].vlist[index].ye=s[index].ye;L[curr_index].vlist[index].flag_g=s[index].flag_g;L[curr_index].vlist[index].R=s[index].R;}}EA=1;configtime0(1);lcdinit();flag_g=0;while(1){for(curr_index=0;curr_index<2;curr_index++){lcdclearfull();IntToString(str,curr_index);lcdshowstr(0,0,str);IntToString(str,L[1].num);lcdshowstr(5,0,str);Draw_polygon2D(&L[curr_index]);}}}//////////////////////////////////////////////////////////////////////////void Draw_polygon2D(sqlist_ptr poly){static unsigned char i=0;// if(poly->state==1)// {do{for(;i<poly->num;){if(poly->vlist[i].flag_g==0&&flag_finish==0){TR0=0;flag_3=0;x_finish_value=poly->vlist[i].xe;y_finish_value=poly->vlist[i].ye;x_start_value=poly->x0;y_start_value=poly->y0;flag_g=poly->vlist[i].flag_g;init();i=i+1;TR0=1;break;}else if(poly->vlist[i].flag_g==1&&flag_finish==0) //斜线的判断{TR0=0;flag_3=0;x_finish_value=poly->vlist[i].xe;y_finish_value=poly->vlist[i].ye;x_start_value=poly->vlist[i-1].xe;y_start_value=poly->vlist[i-1].ye;flag_g=poly->vlist[i].flag_g;init();i++;TR0=1;break;}else if((poly->vlist[i].flag_g==2)&&(flag_finish==0))//顺园的判断{TR0=0;flag_3=0;x_finish_value=poly->vlist[i].xe;y_finish_value=poly->vlist[i].ye;x_start_value=poly->vlist[i-1].xe;y_start_value=poly->vlist[i-1].ye;flag_g=poly->vlist[i].flag_g;r=poly->vlist[i].R;EA=0;f(x_start_value, y_start_value,x_finish_value,y_finish_value);EA=1;/*IntToString(str,px[0]);lcdshowstr(0,0,str);IntToString(str,py[0]);lcdshowstr(6,0,str);IntToString(str,px[1]);lcdshowstr(0,1,str);IntToString(str,py[1]);lcdshowstr(6,1,str);*/getarc( x_start_value, y_start_value,x_finish_value,y_finish_value);init();i++;TR0=1;break;}} //forIntToString(str,i);lcdshowstr(0,1,str);IntToString(str,poly->num);lcdshowstr(3,1,str);IntToString(str,poly->vlist[i].xe);lcdshowstr(5,1,str);IntToString(str,poly->vlist[i].ye);lcdshowstr(9,1,str);}while(i<poly->num);i=0;// }}/////////////////////////////////void init(){if(flag_g==0){a=x_finish_value-x_start_value;if(a<0)a=-a;b=y_finish_value-y_start_value;if(b<0)b=-b;x_finish_value=x_finish_value-x_start_value;y_finish_value=y_finish_value-y_start_value;x_start_value=x_start_value-x_start_value;y_start_value=y_start_value-y_start_value;flag_finish=a+b;xiangxian();x=x_start_value;y=y_start_value;n=10;}if(flag_g==1){x_finish_value=x_finish_value-x_start_value;y_finish_value=y_finish_value-y_start_value;x_start_value=x_start_value-x_start_value;//开始X点位移到原点y_start_value=y_start_value-y_start_value; //开始Y点位移到原点xiangxian(); //flag_finish=x_finish_value+y_finish_value;x=x_start_value;y=y_start_value;n=6;}if(flag_g==2) //顺圆{x_finish_value=x_finish_value-ox;y_finish_value=y_finish_value-oy; //计算y轴上要走步数x_start_value=x_start_value-ox;y_start_value=y_start_value-oy;a=x_finish_value-x_start_value;if (a<0) //当上式结果为负时{a=-a; //调整为正数}b=y_finish_value-y_start_value;if (b<0) //当上式结果为负时{b=-b; //调整为正数}ox=ox-ox;//oy=oy-oy;//flag_finish=a+b;xiangxian();x=x_start_value;y=y_start_value;x_g2=x_start_value;if(x_g2<0){x_g2=-x_g2;}y_g2=y_start_value; //起始位置坐标设定if(y_g2<0){y_g2=-y_g2;}n=6;}if(flag_g==3)//逆圆{}time_count=0;}void xiangxian(){if(flag_g==0){if(x_finish_value>=0){if(y_finish_value>=0){flag_xiangxian=1; // 1}if(y_finish_value<0){y_finish_value=0-y_finish_value;flag_xiangxian=4; // 4}}if(x_finish_value<0){if(y_finish_value>=0){flag_xiangxian=2;}if(y_finish_value<0){y_finish_value=0-y_finish_value;flag_xiangxian=3;}}}if(flag_g==1){if(x_finish_value>=0){if(y_finish_value>=0){flag_xiangxian=1;if(y_finish_value<0){y_finish_value=0-y_finish_value;flag_xiangxian=4;}}if(x_finish_value<0){x_finish_value=0-x_finish_value;if(y_finish_value>=0){flag_xiangxian=2;}if(y_finish_value<0){y_finish_value=0-y_finish_value;flag_xiangxian=3;}}}if(flag_g==2) //当顺圆插补时{if(x_finish_value==0) //当终点坐标在X轴上时{if(y_finish_value>0) //如果终点Y坐标为正{flag_xiangxian=2; //确定插补过程在第二象限}if(y_finish_value<0) //如果终点Y坐标为负{flag_xiangxian=4; //确定插补过程在第四象限y_finish_value=-y_finish_value; //终点Y座标求绝对值}}if(x_finish_value>0) //如果终点X坐标为正{if(y_finish_value>0) //如果终点Y坐标为正{flag_xiangxian=1; //确定插补过程在第一象限}if(y_finish_value==0) //当终点坐标在Y轴上时flag_xiangxian=1; //确定插补过程在第一象限}if(y_finish_value<0) //如果终点Y坐标为负{flag_xiangxian=4; //确定插补过程在第四象限y_finish_value=-y_finish_value; //终点Y座标求绝对值}}if(x_finish_value<0) //如果终点X坐标为负{x_finish_value=-x_finish_value; //终点X座标求绝对值if(y_finish_value>0) //如果终点Y坐标为正{flag_xiangxian=2; //确定插补过程在第二象限}if(y_finish_value==0) //当终点坐标在Y轴上时{flag_xiangxian=3; //确定插补过程在第三象限}if(y_finish_value<0) //如果终点Y坐标为负{flag_xiangxian=3; //确定插补过程在第三象限y_finish_value=-y_finish_value; //终点Y座标求绝对值}}}if(flag_g==3){}}void panduan(){if(flag_g==0){if(flag_finish>0){if(x!=x_finish_value){if(flag_xiangxian==1){addx();}if(flag_xiangxian==2){backx();}if(flag_xiangxian==3){backx();}if(flag_xiangxian==4){addx();}}if(x==x_finish_value){if(flag_xiangxian==1){addy();}if(flag_xiangxian==2){addy();}if(flag_xiangxian==3){backy();}if(flag_xiangxian==4){backy();}}}}if(flag_g==1){if(flag_finish>0){if(flag_3>=0){if(flag_xiangxian==1){addx();}if(flag_xiangxian==2){backx();}if(flag_xiangxian==3){backx();}if(flag_xiangxian==4){addx();}}if(flag_3<0){if(flag_xiangxian==1){addy();}if(flag_xiangxian==2){addy();}if(flag_xiangxian==3){backy();}if(flag_xiangxian==4){backy();}}}}if(flag_g==2) //当顺圆插补时{if(flag_finish>0){if(flag_3>=0) //当偏差式大于等于零时{if(flag_xiangxian==1) //当为第一象限顺圆插补时{backy(); //调用y轴反向走步程序}if(flag_xiangxian==2) //当为第二象限顺圆插补时{addx(); //调用x轴正向走步程序}if(flag_xiangxian==3) //当为第三象限顺圆插补时{addy(); //调用y轴正向走步程序}if(flag_xiangxian==4) //当为第四象限顺圆插补时{backx(); //调用x轴反向走步程序}}if(flag_3<0) //当偏差式小于零时{if(flag_xiangxian==1) //当为第四象限顺圆插补时{addx(); //调用x轴正向走步程序}if(flag_xiangxian==2) //当为第四象限顺圆插补时{addy(); //调用y轴正向走步程序}if(flag_xiangxian==3) //当为第四象限顺圆插补时{backx(); //调用x轴反向走步程序}if(flag_xiangxian==4) //当为第四象限顺圆插补时{backy(); //调用y轴反向走步程序}}}}if(flag_g==3){if(flag_finish>0){}}void addx(){while(time_count>=n){Xdir=0;Xpul=~Xpul;div++;if(div==2){if(flag_g==1){flag_3=flag_3-y_finish_value;}if(flag_g==2) //当顺圆查补时{if(flag_xiangxian==2) //当为第二象限顺圆查补时{flag_3=flag_3-2*x_g2+1; //查补偏差判别式x_g2--; //顺圆x坐标绝对值减一}if(flag_xiangxian==1) //当为第一象限顺圆查补时{flag_3=flag_3+2*x_g2+1; //查补偏差判别式x_g2++; //顺圆x坐标绝对值加一}}if(flag_g==3){}div=0;x=x+1;flag_finish=flag_finish-1;if(flag_finish<=0){TR0=0;}time_count=0;panduan();}}void backx(){while(time_count>=n){Xdir=1;Xpul=~Xpul;div++;if(div==2){div=0;if(flag_g==1){flag_3=flag_3-y_finish_value;}if(flag_g==2) //当顺圆查补时{if(flag_xiangxian==4) //当为第四象限顺圆查补时{flag_3=flag_3-2*x_g2+1; //查补偏差判别式x_g2--; //顺圆x坐标绝对值减一}if(flag_xiangxian==3) //当为第三象限顺圆查补时{flag_3=flag_3+2*x_g2+1; //查补偏差判别式x_g2++; //顺圆x坐标绝对值加一}}if(flag_g==3){}x--;flag_finish--;if(flag_finish<=0){TR0=0;}time_count=0;panduan();}}}void addy(){while(time_count>=n){Ydir=0;Ypul=~Ypul;div++;if(div==2){div=0;if(flag_g==1){flag_3=flag_3+x_finish_value;}if(flag_g==2) //当顺圆查补时{if(flag_xiangxian==3) //当为第三象限顺圆查补时{flag_3=flag_3-2*y_g2+1; //查补偏差判别式y_g2--; //顺圆y坐标绝对值减一}if(flag_xiangxian==2) //当为第二象限顺圆查补时{flag_3=flag_3+2*y_g2+1; //查补偏差判别式y_g2++; //顺圆y坐标绝对值加一}}if(flag_g==3){}y++;flag_finish--;if(flag_finish<=0){TR0=0;}time_count=0;panduan();}}}void backy(){while(time_count>=n){Ydir=1;Ypul=~Ypul;div++;if(div==2){div=0;if(flag_g==1){flag_3=flag_3+x_finish_value;}if(flag_g==2) //当顺圆查补时{if(flag_xiangxian==1) //当为第一象限顺圆查补时{flag_3=flag_3-2*y_g2+1; //查补偏差判别式y_g2--; //顺圆y坐标绝对值减一}if(flag_xiangxian==4) //当为第四象限顺圆查补时{flag_3=flag_3+2*y_g2+1; //查补偏差判别式y_g2++; //顺圆y坐标绝对值加一}}if(flag_g==3){}y--;flag_finish--;if(flag_finish<=0){TR0=0;}time_count=0;panduan();}}}/////////////////////圆上任意4点画圆弧void f(int16 x1,int16 y1,int16 x2,int16 y2) {float pdata d;float pdata dx,dy;float pdata D;float pdata my[2],nx[2];float pdata L;float pdata sink,cosk;float pdata n,m;n=x2-x1;if(n<0)n=-n;m=y2-y1;if(m<0)m=-m;dx=(float)n*n;//a^2+b^2;dy=(float)m*m;d=dx+dy;D=sqrt(d);// ok sqrtsink=n/D; // okcosk=m/D; // okL=(float)r*r-(float)(d/4); //okL=sqrt(L); //oknx[0]=(float)(x2+x1)/2-(float)L*sink ;my[0]=(float)(y2+y1)/2-(float)L*cosk;nx[1]=(float)(x2+x1)/2+(float)L*sink ;my[1]=(float)(y2+y1)/2+(float)L*cosk;px[0]=nx[0];py[0]=my[0];px[1]=nx[1];py[1]=my[1];}void getarc(int16 xs,int16 ys,int16 xe,int16 ye) {if((xs>xe)&&(ys<=ye)) //3{//取Y最大值if(py[1]>py[0]){oy=py[1];ox=px[1];}}else if((xs<xe)&&(ys<=ye)) //2{//取Y最小值if(py[0]<py[1]){oy=py[0];ox=px[1];}}else if((xs<xe)&&(ys>=ye)) //1{//取Y最小值if(py[0]<py[1]){oy=py[0];ox=px[0];}}else if((xs>xe)&&(ys>=ye)) //4{//取Y最大值if(py[1]>py[0]){oy=py[1];ox=px[0];}}}/////////////////////////////////////void configtime0(unsigned int ms){unsigned long tmp;tmp=11059200/12;tmp=(921600*ms)/(5000);tmp=65536-tmp;T0RH=(unsigned char )(tmp>>8);T0RL=(unsigned char)tmp;TMOD=TMOD&0xf0;TMOD=TMOD|0x01;ET0=1;TR0=0;TH0=T0RH;TL0=T0RL;}///////////////void time0() interrupt 1 // 1ms 进一次中断{TH0=T0RH;TL0=T0RL;time_count++;panduan();}。
51单片机按键控制步进电机加减速及正反转

51单片机按键控制步进电机加减速及正反转之前尝试用单片机控制42步进电机正反转,电机连接导轨实现滑台前进后退,在这里分享一下测试程序及接线图,程序部分参考网上找到的,已经实际测试过,可以实现控制功能。
所用硬件:步进电机及驱动器、STC89C52单片机、直流电源1、硬件连接图•注意:上图为共阳极接法,实际连接参考总体线路连接。
•驱动器信号端定义:PUL+:脉冲信号输入正。
( CP+ )PUL-:脉冲信号输入负。
( CP- )DIR+:电机正、反转控制正。
DIR-:电机正、反转控制负。
EN+:电机脱机控制正。
EN-:电机脱机控制负。
•电机绕组连接A+:连接电机绕组A+相。
A-:连接电机绕组A-相。
B+:连接电机绕组B+相。
B-:连接电机绕组B-相。
•电源连接VCC:电源正端“+”GND:电源负端“-”注意:DC直流范围:9-32V。
不可以超过此范围,否则会无法正常工作甚至损坏驱动器.•总体线路连接输入信号共有三路,它们是:①步进脉冲信号PUL+,PUL-;②方向电平信号DIR+,DIR-③脱机信号EN+,EN-。
输入信号接口有两种接法,可根据需要采用共阳极接法或共阴极接法。
在这里我采用的是共阴极接法:分别将PUL-,DIR-,EN-连接到控制系统的地端(接入单片机地端);脉冲输入信号通过PUL+接入单片机(代码中给的P2^6脚),方向信号通过DIR+接入单片机(代码中给的P2^4脚),使能信号通过EN+接入(不接也可,代码中未接,置空)。
按键连接见代码,分别用5个按键控制电机启动、反转、加速、减速、正反转。
注意:接线时请断开电源,电机接线需注意不要错相,相内相间短路,以免损坏驱动器。
2、代码1.#include<reg51.h>2.#define MotorTabNum 53.unsigned char T0_NUM;4.sbit K1 = P3^5; // 启动5.sbit K2 = P3^4; // 反转6.sbit K3 = P3^3; // 加速7.sbit K4 = P3^2; // 减速8.sbit K5 = P3^1; //正反转9.10.sbit FX = P2^4; // 方向11.//sbit MotorEn = P2^5; // 使能12.sbit CLK = P2^6; // 脉冲13.14.inttable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};15.16.unsigned char g_MotorSt = 0; //17.unsigned char g_MotorDir = 0; //18.unsigned char MotorTab[7] = {12, 10, 8, 6, 4, 2,1};19.20.signed char g_MotorNum = 0;21.22.void delayms(xms);23.void mDelay(unsigned int DelayTime);24.void T0_Init();25.26.void KeyScan(void);27.28.29.30.void main(void)31.{32.T0_Init();33.// MotorEn = 0; //34.FX = 0;35.while(1)36.{37.KeyScan(); //38.}39.40.41.}42.43.void T0_Init()44.{45.TMOD = 0x01;46.TH0 = (65535-100)/256; // 1ms47.TL0 = (65535-100)%256;48.EA = 1;49.ET0 = 1;50.// TR0 = 1;51.52.}53.54.void T0_time() interrupt 155.{56.// TR0 = 0;57.TH0 = (65535-100)/256;58.TL0 = (65535-100)%256;59.T0_NUM++;60.if(T0_NUM >= MotorTab[g_MotorNum]) //61.{62.T0_NUM = 0;63.CLK=CLK^0x01; //64.}65.// TR0 = 1;66.}67.68.69.//--------------------------70.void KeyScan(void)71.{72.if(K1 == 0)73.{74.delayms(10);75.if(K1 == 0)76.{77.g_MotorSt = g_MotorSt ^ 0x01;78.// MotorEn ^= 1;79.TR0 = 1;80.FX ^= 0; //反转81.}82.}83.84.if(K2 == 0)85.{86.delayms(10); //正转87.if(K2 == 0)88.{89.g_MotorDir = g_MotorDir ^ 0x01;90.FX ^= 1; //加速91.}92.}93.94.if(K3 == 0) //95.{96.delayms(5); //加速97.if(K3 == 0)98.{99.g_MotorNum++;100.if(g_MotorNum > MotorTabNum) 101.g_MotorNum = MotorTabNum; 102.}103.}105.if(K4 == 0) //106.{107.delayms(5); // 减速108.if(K4 == 0)109.{110.g_MotorNum--;111.if(g_MotorNum < 0)112.g_MotorNum = 0;113.}114.}115.116.if(K5 == 0) //117.{118.delayms(10); // 正反转119.if(K5 == 0)120.{121.g_MotorSt = g_MotorSt ^ 0x01; 122.g_MotorDir = g_MotorDir ^ 0x01; 123.MotorEn ^= 1;124.TR0 = 1;125.while(1)126.{127.FX ^= 1; //128.delayms(90000);129.FX ^= 0; //130.delayms(90000);131.}132.}133.}135.136.void delayms(xms)//延时137.{138.unsigned int x,y;139.for(x=xms;x>0;x--)140.for(y=110;y>0;y--);141.}3、常见问题解答•控制信号高于5v一定要串联电阻,否则可能会烧坏驱动器控制接口电路。
控制电机的c语言程序

//水位5
if(shuiman==1&&sw5==0&&sw4==1&&sw3==1&&sw2==1&&sw1==1)//当唯一的闭合一个传感器单元:水位5时发生
{
P0=table[5];//显示水位深度:5
}
//水位4
if(shuiman==1&&sw5==1&&sw4==0&&sw3==1&&sw2==1&&sw1==1)//当唯一的闭合一个传感器单元:水位4时发生
#include<reg51.h>
//定义一个数组,使数码管显示的数字和数组元素的下标相等
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
sbit shuiman=P1^0;//水满
sbit sw5=P1^1;//水位5
{
P0=table[2];//显示水位深度:2
}
//水位低
if(shuiman==1&&sw5==1&&sw4==1&&sw3==1&&sw2==1&&sw1==0)//当唯一的闭合一个传感器单元:水位1时发生
{
dianji=0;//开电机
state=0;//电机工作指示灯打开
P0=table[1];//显示水位深度:1
}
//手工上水
if(shougong==0)//当按手工上水按钮时发生
{
dianji=0;//开电机
遥控步进电机程序

#include <reg52.h> //51芯片管脚定义头文件#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define DATA_PORT P0sbit IRIN = P3 ^ 2; //红外接收器数据线sbit BEEP = P3 ^ 7; //蜂鸣器驱动线sbit RELAY = P3 ^ 6; //继电器驱动线sbit LCD_RS = P2 ^ 0;sbit LCD_RW = P2 ^ 1;sbit LCD_EN = P2 ^ 2;uchar n[32];uint p=215;//速度初值uchar IRCOM[] ={0x00, 0x00, 0x00, 0x00 //前4个分别是用户码,用户码,数据码,数据反码};unsigned char code FFW[8] ={0xf1, 0xf3, 0xf2, 0xf6, 0xf4, 0xfc, 0xf8, 0xf9};unsigned char code REV[8] ={0xf8, 0xfc, 0xf4, 0xf6, 0xf2, 0xf3, 0xf1,0xf9 //注意,这两个数组初相不能相同!};/**********************************************************us延时子程序(4.34us)**********************************************************/void delayNOP(){_nop_();_nop_();_nop_();_nop_();}/********************************************************** ms延时子函数**********************************************************/ void delayms(unsigned int ms){unsigned char k;while (ms--){for (k = 0; k < 114; k++);}}/********************************************************** us延时子函数该延时函数与解码有关!!!**********************************************************/ void delay(unsigned char x) //x*0.14MS{unsigned char i;while (x--){for (i = 0; i < 14; i++);}}/********************************************************** 蜂鸣器驱动子函数**********************************************************/ void beep(){unsigned char i;for (i = 0; i < 100; i++){BEEP = !BEEP; //BEEP取反delay(6);}BEEP = 1; //关闭蜂鸣器}/********************************************************** 写指令数据到LCDRS=L,RW=L,EN 下降沿执行写操作。
完整的单片机控制步进电机程序

#include "reg52.h"#include "INTRINS.H"#include <absacc.h>#include <math.h>#define uint unsigned int#define uchar unsigned charvoid check_addr(void); /* 地址核对*/uchar code slave_addr[4]={00, 01, 02, 255}; /* 从机地址*/uchar idata T0low, T0high,common_count,input_order,cmd_in_permit,interval; ucharsent_ok,speed_change,start_up,start_end,address_true,i;uint y1;uint codeadd[100]={60006,62771,63693,64154,64430,64614,64746,64845,64922,64983,65033,65075,651 11,65141,65167,65190,65211,65229,65245,65260,65273,65285,65296,65306,65315,65323,65331 , 65339,65345,65352,65358,65363,65368,65373,65378,65382,65387,65390,65394,65398,65401,6 5404,65407,65410,65413,65416,65418,65421,65423,65425,65428,65430,65432,65434,65435,654 37,65439,65441,65442,65444,65445,65447,65448,65450,65451,65452,65453,65455,65456,65457 , 65458,65459,65460,65461,65462,65463,65464,65465,65466,65467,65468,65469,65469,65470,6 5471,65472,65472,65473,65474,65475,65475,65476,65477,65477,65478,65478,65479,65480,654 80,65481};sbit P2_0=P2A0; sbit P2_2=P2A2; sbit P1_0=P1A0; sbit WD=P1A7; /* 作输入步进电机的脉冲信号发送口*//* 作输入步进电机的旋转方向信号发送口*//*作串口输出信号的使能口,P1_0=0时接通串口,输出信号*/ /* 看门狗*/main(){P2_0=0;P2_2=0; /* 步进电机的旋转方向待试验后确定*/P1_0=1; /* 开机时需要关断,串口发送功能,需要时再接通*/ WD=1; /* 看门狗先为1,电平翻转为喂狗*/ i=0;common_count=0; cmd_in_permit=0;input_order=0;interval=0; address_true=1;speed_change=0;start_up=0;start_end=0;sent_ok=0; // 允许发送EA=1; /* 开放总中断*/ TMOD=0x21;TH1 = 0xFD; TL1 = 0xFD; SCON = 0xd0; PCON &= 0x00; SM2=1;TR1 = 1;ES=1; // 波特率9600// 设定串行口工作方式// 波特率不倍增// 启动定时器1T2MOD=00;T2CON=0x00;RCAP2H =0xEE; //赋T2 的预置值0xA600,25MS ,0xB800 ,20MS,0xCA00 ,15MS,0xDC00 ,10MS,0xEE00 ,5MSRCAP2L =0x00;TR2=1; //启动定时器ET2=1; //打开定时器2 中断do{if(address_true==1){ address_true=0; check_addr();} if(start_up==1&&start_end==0) //第一次启动{y1=add[common_count];T0high = (uchar)(y1>>8) ; /* 取y1 的高8 位*/T0low = (uchar)(y1&0x00ff); /*取y1的低8位*/TR0 = 1;ET0=1; /* 允许T/C0 中断*/start_end=1;}if(speed_change==1){ if(interval>=0&&interval<=0x63) {if(interval>common_count){common_count=common_count+1; }if(interval<common_count){common_count=common_count-1; }speed_change=0;} if(sent_ok==1){ sent_ok=0; P1_0=0; for(i=0;i<=20;i++) {_nop_();}TI=0; SBUF=T0high; while(TI==0);TI=0; TI=0; SBUF=T0low; while(TI==0);TI=0;P1_0=1; for(i=0;i<=20;i++) {_nop_();}SM2=1;}} while(1);}void timer0(void) interrupt 1 using 3{ P2_0=~P2_0; y1=add[common_count];T0high = (uchar)(y1>>8) ; /* 取y1 的高8 位*/ T0low = (uchar)(y1&0x00ff); /* 取y1 的低8 位*/ THO=TOhigh; /*高8 位TOhigh 送定时器0 的TH0*/ TL0=T0low; /*低8 位T0low 送定时器0 的TL0*/}void timer2(void) interrupt 5 using 2{TF2=0; /*T2 溢出中断需软件清0*/ speed_change=1; //速度可以改变标示,以便主程序处理WD=!WD; /*MAX813 喂狗*/}void inte_SERIAL() interrupt 4 using 1 /*串口0 中断服务子程序*/{uchar key_in ; key_in=0;if(RI){key_in=SBUF;RI=0;if (SM2==1){ if(key_in==slave_addr[2]){SM2=0; address_true=1;}}if ((SM2==0)&& (RB8==0)){ if(key_in==0xff){SM2=1;}if(key_in==0xfe){ /* 接收主机命令引导字节,准备接收主机命令*/ cmd_in_permit=1;} if(cmd_in_permit==1){ input_order=input_order+1;}if (input_order==2){ /* 接收主机命令,使从机开始调节电机*/ cmd_in_permit=0; input_order=0;/*interval 代表控制器发给电机的转速期望值*/ interval= key_in;sent_ok=1; if(start_up==0){start_up=1;}}}}}void check_addr(void){ /* 地址核对成功,发送从机地址给主机*/TB8=1;RB8=0;P1_0=0;for(i=0;i<=25;i++) {_nop_();}SBUF=slave_addr[2]; /* 发送地址核对成功,发送从机地址给主机*/ do{} while(TI==0); TI=0;P1_0=1;for(i=0;i<=25;i++) {_nop_();}TB8=0;。
步进电机控制程序(c语言51单片机)

// pri_dj = Pme );
if( i == set_pwm_width ) { P1 = 0xff; i = 0; one _round_flg = 0; while ( !one_round_flg & key_puse );}
if(!key_puse) { delay(4ms); if(!key_puse) break; }
while ( key_puse & key_clear ); delay ( 8ms );
if ( !key_clear ) { round_num = 0; display(); }
if ( !key_puse ) break; }
while( !key_puse ); delay(8ms);
while( !key_puse ); }
set_display_num(); for(i = 0; i < LEDLen ; i ++){
P0 = 0xf0; P0 = P0 | LEDBuf[i] ; if(i==0) led_1000 = 0; //P0^4 if(i==1) led_100 = 0; //P0^5 if(i==2) led_10 = 0; //P0^6 if(i==3) led_1 = 0; //P0^7
delay ( 1ms ); tmp = (~(P2 | 0xF0)); P2 = 0x7F; // 0111 1111
delay ( 1ms ); tmp = (~(P2 | 0xF0)) * 10 + tmp; set_round_num = set_round_num + tmp * 100; set_round_num = set_round_num * Chilun_Num;
51单片机驱动步进电机__终极完整版

51单片机驱动步进电机__终极(完整版)在这里介绍一下用51单片机驱动步进电机的方法。
这款步进电机的驱动电压12V,步进角为 7.5度 . 一圈360 度 , 需要 48 个脉冲完成!!!该步进电机有6根引线,排列次序如下:1:红色、2:红色、3:橙色、4:棕色、5:黄色、6:黑色。
采用51驱动ULN2003的方法进行驱动。
ULN2003的驱动直接用单片机系统的5V电压,可能力矩不是很大,大家可自行加大驱动电压到12V。
;************************************************ ******************************;************************* 步进电机的驱动*************************************** ; DESIGN BY BENLADN911 FOSC = 12MHz 2005.05.19;---------------------------------------------------------------------------------; 步进电机的驱动信号必须为脉冲信号!!! 转动的速度和脉冲的频率成正比!!!; 本步进电机步进角为 7.5度 . 一圈 360 度 , 需要48 个脉冲完成!!!;---------------------------------------------------------------------------------; A组线圈对应 P2.4; B组线圈对应 P2.5; C组线圈对应 P2.6; D组线圈对应 P2.7; 正转次序: AB组--BC组--CD组--DA组 (即一个脉冲,正转 7.5 度);----------------------------------------------------------------------------------;----------------------------正转-------------------------- ORG 0000H LJMP MAIN ORG 0100HMAIN:MOV R3,#144 正转 3 圈共 144 脉冲 START: MOVR0,#00H START1: MOV P2,#00H MOV A,R0MOV DPTR,#TABLE MOVC A,@A+DPTRJZ START 对 A 的判断,当 A = 0 时则转到 START MOV P2,ALCALL DELAY INC R0DJNZ R3,START1MOV P2,#00H LCALL DELAY1;-----------------------------反转------------------------MOV R3,#144 反转一圈共 144 个脉冲 START2:MOV P2,#00H MOV R0,#05 START3: MOV A,R0MOV DPTR,#TABLE MOVC A,@A+DPTR JZ START2 MOV P2,A CALL DELAY INC R0DJNZ R3,START3 MOV P2,#00HLCALL DELAY1 LJMP MAINDELAY: MOV R7,#40 步进电机的转速 M3: MOV R6,#248 DJNZ R6,$ DJNZ R7,M3RETDELAY1: MOV R4,#20 2S 延时子程序 DEL2: MOV R3,#200 DEL3: MOV R2,#250 DJNZ R2,$ DJNZ R3,DEL3 DJNZ R4,DEL2 RET TABLE:DB 30H,60H,0C0H,90H 正转表 DB 00 正转结束DB 30H,90H,0C0H,60H 反转表 DB 00 反转结束 END 51单片机控制四相步进电机拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为 360/(4×5)=18度。
单片机驱动步进电机程序代码

/********************************************************实现功能:正转程序使用芯片:AT89S52晶振:11.0592MHZ编译环境:Keil作者:【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!********************************************************/#include<reg52.h> //库文件#define uchar unsigned char //字符型宏定义#define uint unsigned int //整型宏定义uchar tcnt; //定时器计数初值定义uint sec; //速度值定义uchar buf[11];uchar bai,shi,ge;/********************控制位定义*************************/sbit shi_neng=P1^0; // 使能控制位sbit fang_shi=P1^1; // 工作方式控制位sbit fang_xiang=P1^2;// 旋转方向控制位sbit mai_chong=P1^3; // 脉冲控制位/********************延时函数***************************/void delay1ms(uchar z){uchar x,y;for(x=0;x<z;x++)for(y=0;y<110;y++);}/***************************定时中断服务函数*************/void t0(void) interrupt 1 using 0 //定时中断服务函数{tcnt++; //每过250ust tcnt 加一if(tcnt==1) //当tcnt满足条件时{tcnt=0; //计满重新再计sec++;if(sec==6) //括号内数值越小,电机转动速度越快{sec=0; //计满重新再计mai_chong=~mai_chong; //脉冲输出}}}/***********************定时器0/1初始化****************************/void T0_Init(){ET0 = 1;TMOD = 0x22;TH0=0x06; //对TH0 TL0 赋值TL0=0x06;TR0=1; //开始定时sec=0;mai_chong=1; // 脉冲控制位}/***********************串口初始化****************************/void Uart_Init(){TMOD = 0x22;TH1 = 0xFD;TL1 = 0xFD;SCON = 0x50;PCON &= 0xef;TR1 = 1;}/***********************数据接收函数****************************/void ReceiveBuf(){int i;for(i=0;i<11;i++){buf[i] = SBUF;while(RI == 0);RI=0;}}/***********************角度控制函数****************************/ void Control(){if((bai==buf[5])&(shi==buf[6])&(ge==buf[7])){shi_neng=0;};if(bai<buf[5]){shi_neng=1;fang_xiang=0;}else if(bai>buf[5]){shi_neng=1;fang_xiang=1;};if((bai==buf[5])&shi<buf[6]){fang_xiang=0;}else if((bai==buf[5]&shi>buf[6])){shi_neng=1;fang_xiang=1;};if((bai==buf[5])&(shi==buf[6]&(ge<buf[7]))) {shi_neng=1;fang_xiang=0;}else if((bai==buf[5])&(shi==buf[6])&(ge>buf[7])) {shi_neng=1;fang_xiang=1;};if((bai==buf[5])&(shi==buf[6])&(ge==buf[7])) {};delay1ms(3);bai=buf[5];shi=buf[6];ge=buf[7];}/************************主函数****************************/main(){EA=1;T0_Init();Uart_Init();while(1){// shi_neng=1; // 使能控制位fang_shi=1; // 工作方式控制ReceiveBuf();delay1ms(1);Control();delay1ms(10);}}/*************************结束******************************/Welcome To Download !!!欢迎您的下载,资料仅供参考!。
51单片机控制的步进电机C语言程序

51单片机控制的步进电机C语言程序用的是L298驱动的和ULN2003一样,你把它换成2003就行拉#include <AT89X51.H>unsigned char codetable[]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9,0x00,0xf1,0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0x f3,0x00};unsigned char temp,temp_old;unsigned char key;unsigned char i,j,k,m,s;void delay(int i){for(m=i;m>0;m--)for(j=250;j>0;j--)for(k=10;k>0;k--);}void saomiao(){P3=0xff;P3_4=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0e:key=1;break;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=4;break;}temp=P3;temp=temp&0x0f;while(temp!=0x0f){temp=P3;temp=temp&0x0f;}}}P3=0xff;P3_5=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;}temp=P3;temp=temp&0x0f;while(temp!=0x0f){temp=P3;temp=temp&0x0f;}}}}void main(void){while(1){saomiao();if(key==1){ P1=0;P2=0;saomiao();}if(key==2){temp_old=key;for(s=0;s<8;s++){ P2=table[s];P1_4=0;delay(13);saomiao();if(key!=temp_old){P1_4=1;break;}}}if(key==3){temp_old=key;for(s=0;s<8;s++){ P2=table[s];P1_5=0;delay(5);saomiao();if(key!=temp_old){P1_5=1;break;}}}if(key==4){temp_old=key; for(s=0;s<8;s++){ P2=table[s];P1_6=0;delay(20);saomiao();if(key!=temp_old){P1_6=1;break;}}}if(key==5){temp_old=key;for(s=9;s<17;s++){ P2=table[s];P1_7=0;delay(13);saomiao();if(key!=temp_old){P1_7=1;break;}}}if(key==6){temp_old=key;for(s=9;s<17;s++){ P2=table[s];P1_5=0;delay(5);saomiao();if(key!=temp_old){P1_5=1;break;}}}if(key==7){temp_old=key;for(s=9;s<17;s++){ P2=table[s];P1_6=0;delay(20);saomiao();if(key!=temp_old){P1_6=1;break;}}}}}C语言程序源代码#include <REGX51.H> // 51寄存器定义#include "intrins.h"#define control P1 //P1_0:A相,P1_1:B相,P1_2:C相,P1_3:D相#define discode P0 //显示代码控制端口#define uchar unsigned char //定义无符号型变量#define uint unsigned intsbit en_dm=P3^0; //显示代码锁存控制sbit en_wk=P3^1; //位控锁存控制uchar code corotation[4]= {0x03,0x06,0x0c,0x09};//电机正转uchar code rollback[4]={0x0c,0x06,0x03,0x09}; //电机反转uchar code tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示字段uint code Levspeed[5]={500,400,300,200,100};//电机速度等级uchar Hscan,speedcount;//Hscan行扫描,speedcount 速度等级计数uint uu; //频率计数uint step,setstep; //step:电机步伐计数,setstep:手动设置电机步伐uint speed=500; //电机初始速度uchar count;uchar flag[5];uchar butcount; //按键次数//****************************************//flag[0] 正转标志//flag[1] 反转标志//flag[2] 加速标志//flag[3] 减速标志//flag[4] 设置标志//****************************************Delay1mS(unsigned int tt) //延时1ms “Delay1mS”延时子程序,用循环语句延时。
步进电机C语言代码

#include <AT89X51.h>static unsigned int count; //计数static int step_index; //步进索引数,值为0-7static bit turn; //步进电机转动方向static bit stop_flag; //步进电机停止标志static int speedlevel; //步进电机转速参数,数值越大速度越慢,最小值为1,速度最快static int spcount; //步进电机转速参数计数void delay(unsigned int endcount); //延时函数,延时为endcount*0.5毫秒void gorun(); //步进电机控制步进函数void main(void){count = 0;step_index = 0;spcount = 0;stop_flag = 0;P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFE;TL0 = 0x0C; //设定时每隔0.5ms中断一次TR0 = 1; //开始计数turn = 0;speedlevel = 2;delay(10000);speedlevel = 1;do{speedlevel = 2;delay(10000);speedlevel = 1;delay(10000);stop_flag=1;delay(10000);stop_flag=0;}while(1);}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFE;TL0=0x0C; //设定时每隔0.5ms中断一次count++;spcount--;if(spcount<=0){spcount = speedlevel;gorun();}}void delay(unsigned int endcount){count=0;do{}while(count<endcount);}void gorun(){if (stop_flag==1){P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;return;}switch(step_index) {case 0: //0P1_0 = 1;P1_1 = 0;P1_2 = 0;P1_3 = 0;break;case 1: //0、1P1_0 = 1;P1_1 = 1;P1_2 = 0;P1_3 = 0;break;case 2: //1P1_0 = 0;P1_1 = 1;P1_2 = 0;P1_3 = 0;break;case 3: //1、2P1_0 = 0;P1_1 = 1;P1_2 = 1;P1_3 = 0;break; case 4: //2P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 0;break; case 5: //2、3P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 1;break; case 6: //3P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 1;break; case 7: //3、0P1_0 = 1;P1_1 = 0;P1_2 = 0;P1_3 = 1; }if (turn==0){step_index++;if (step_index>7)step_index=0; }else{step_index--;if (step_index<0)step_index=7; }}。
51单片机控制步进电机硬件图及C语言编程

51单片机控制步进电机硬件图#include <reg51.h> //51芯片管脚定义头文件#include <intrins.h> //内部包含延时函数_nop_();#include<absacc.h>#define uchar unsigned char#define uint unsigned intuchar code FFW[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //四相八拍正转编码uchar code REV[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; ////四相八拍反转编码sbit P14=P1^4; //将P14位定义为P1.4引脚sbit P15=P1^5; //将P15位定义为P1.5引脚sbit P16=P1^6; //将P16位定义为P1.6引脚sbit P17=P1^7; //将P17位定义为P1.7引脚sbit P20=P2^0; //将P20位定义为P2.0引脚sbit P21=P2^1; //将P21位定义为P2.1引脚sbit P22=P2^2; //将P22位定义为P2.2引脚sbit P23=P2^3; //将P23位定义为P2.3引脚sbit P24=P2^4; //将P24位定义为P2.4引脚sbit P25=P2^5; //将P25位定义为P2.5引脚sbit P26=P2^6; //将P26位定义为P2.6引脚sbit P27=P2^7; //将P27位定义为P2.7引脚sbit P34=P3^4; //将P34位定义为P3.4引脚sbit P35=P3^5; //将P35位定义为P3.5引脚sbit P36=P3^6; //将P36位定义为P3.6引脚sbit P37=P3^7; //将P37位定义为P3.7引脚sbit P30=P3^0; //将P30位定义为P3.0引脚sbit P31=P3^1; //将P31位定义为P3.1引脚sbit BEEP=P3^2; // 蜂鸣器bit on=0;bit off=1; //运行与停止标志bit zdirection=0; //方向标志bit fdirection=0; //方向标志uchar h,l,k; //定义行键值//定义列键值uchar idata count[3]; //0-9数值储存unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0~9的段码uchar keyval=0; //定义变量储存按键值uchar dat=0; //按键值uint run_i=0;uchar count_i=0;uint run=0; //需要运行的步数uint drun=0; //当前运行的步数bit flag;uint x=60;uint y=60;uint z=0;/* uint k=0; //调速按键次*//**************************************************************/ void led_delay1(void){unsigned char j;for(j=0;j<52;j++);}void beep(){uchar j;for (j=0;j<200;j++){led_delay1();BEEP=!BEEP; //BEEP取反}BEEP=1; //关闭蜂鸣器}/**************************************************************函数功能:数码管动态扫描延时**************************************************************/void led_delay(void){unsigned char j;for(j=0;j<200;j++);}/**************************************************************/**************************************************************函数功能:软件延时去抖动子程序**************************************************************/void delay20ms(void){unsigned char i,j;for(i=0;i<70;i++)for(j=0;j<60;j++);}void display(uint run){ //显示设点步数P31=1; //点亮数码管DS6P30=0;P34=0;P35=0;P36=0;P37=0;P14=0;P15=0;if((run/100)!=0){ P0=Tab[run/100]; //显示百位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P30=1;P31=0;P34=0;P36=0;P37=0;P14=0;P15=0;if(((run%100/10)==0)&&(run/10==0)) { P0=0xff;led_delay(); //动态扫描延时led_delay();} //点亮数码管DS5else{ P0=Tab[run%100/10]; //显示十位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P37=1; //点亮数码管DS4P30=0;P34=0;P35=0;P36=0;P31=0;P14=0;P15=0;if((run/10==0)&&(run%100/10==0)&&(run%10==0)){ P0=0xff;led_delay(); //动态扫描延时led_delay(); //动态扫描延时}else{ P0=Tab[run%10]; //显示个位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;}/*********************************************************************/void ddisplay(uint drun){ //显示运行步数P36=1; //点亮数码管DS3P30=0;P34=0;P35=0;P31=0;P37=0;P15=0;if((drun/100)!=0){P0=Tab[drun/100]; //显示百位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P35=1; //点亮数码管DS2P30=0;P34=0;P31=0;P36=0;P37=0;P14=0;P15=0;if(((drun%100/10)==0)&&(drun/10==0)) { P0=0xff;led_delay(); //动态扫描延时led_delay();}//点亮数码管DS5else{ P0=Tab[drun%100/10]; //显示十位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P34=1; //点亮数码管DS1P30=0;P31=0;P35=0;P36=0;P37=0;P14=0;P15=0;if((drun/10==0)&&(drun%100/10==0)&&(drun%10==0)){ P0=0xff;led_delay(); //动态扫描延时led_delay(); //动态扫描延时}else{ P0=Tab[drun%10]; //显示个位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;}void dddisplay(){ P15=1;P36=0;P30=0;P34=0;P35=0;P31=0;P37=0;P14=0;if((fdirection==1)&&(on==1)){P0=0xbf; led_delay(); led_delay(); }P0=0xff;P14=1;P36=0;P30=0;P34=0;P35=0;P31=0;P37=0;P15=0;if(y==60){P0=0x08;led_delay(); led_delay();}if(y==50){P0=0x03; led_delay(); led_delay(); }if(y==40){P0=0x46; led_delay(); led_delay();}if(y==30){P0=0x21 ;led_delay(); led_delay();}if(y==20){P0=0x86; led_delay(); led_delay(); }if(y==10){P0=0x8e; led_delay(); led_delay();}P0=0xff;}/************************************************************** 函数功能:主函数**************************************************************/ void main(void){ x=60;P14=0;P15=0;P16=0;P17=0;EA=1;EX1=1; //允许使用外中断IT1=1; //选择负跳变来触发外中断PT0=1;ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=0xec; //定时器T0的高8位赋初值TL0=0x78; //定时器T0的低8位赋初值TR0=1;P30=1; //启动定时器T0P34=1;P35=1;P36=1;P37=1;P31=1;P2=0xf0;while(1){if(flag){P2=0x0f; h=P2&0x0f; //所有行线置为高电平"1",所有列线置为低电平"0",并把值给hif((P2&0x0f)!=0x0f) //行线中有一位为低电平"0",说明有键按下delay20ms(); //延时一段时间、软件消抖else {keyval=16;}if(h!=0x0f) //确实有键按下{h=P2&0x0f; //读取行值P2=0xf0; //反转电位l=P2&0xf0; //读取列值k=h+l; //行列相加,为键位值if(k==0x7e) keyval=12;if(k==0x7d) keyval=0;if(k==0x7b) keyval=13;if(k==0x77) keyval=15;if(k==0xbe) keyval=1;if(k==0xbd) keyval=2;if(k==0xbb) keyval=3;if(k==0xb7) keyval=14; //键位与设定对应if(k==0xde) keyval=4;if(k==0xdd) keyval=5;if(k==0xdb) keyval=6;if(k==0xd7) keyval=11;if(k==0xee) keyval=7;if(k==0xed) keyval=8;if(k==0xeb) keyval=9;if(k==0xe7) keyval=10;}else keyval=16;dat=keyval;if((dat==10)&&(run!=0)) //正转键按下{zdirection=1; //方向标志fdirection=0;on=1; //运行与停止标志off=0;}if((dat==11)&&(run!=0)) //反转键按下{fdirection=1; //方向标志zdirection=0;on=1; //运行与停止标志off=0;}if(dat==12) //加速键{if(y==10) y=10;else y=y-10;}if(dat==13) //减速键{if(y==60) y=y;else y=y+10;}if((dat==14)&&(run!=0)) //开始键按下{ if(z==1) {on=1;}elseon=1;off=0;z=0;if((zdirection==0)&&(fdirection==0)){zdirection=1;}}if(dat==15) { z++;on=0; } //停止键按下一次if((on==0)&&(z==2)) //停止键按下二次{count[0]=0; //显示清零count[1]=0;count[2]=0;drun=0; run=0;z=0;on=0;off=1; //运行与停止标志}if((dat>=0)&&(dat<=9)&&(on==0)&&(off==1)){count[count_i]=dat;if(count[0]!=0){count_i++;}if((count_i==3)&&(on==0)&(off==1)){count_i=0;}if((count_i==0)&&(on==0)&(off==1)){ if(count[0]==0)run=0;else run=count[0]*100+count[1]*10+count[2];}if((count_i==1)&&(on==0)&(off==1)){run=count[0];}if((count_i==2)&&(on==0)&(off==1)){run=count[0]*10+count[1];}}if((dat==0)&&(on==1)){off=1;}if(dat==16);flag=0;}/*if(run!=0){*/ddisplay(drun);dddisplay();display(run);/*} */ //调用按键值的数码管显示子程序if((run==drun)&&run!=0){on=0;off=1;beep();drun=0; run=0;count[0]=0; //显示清零count[1]=0;count[2]=0;count_i=0;}}}/**************************************************************外部中断键盘扫描键值保存在dat中******************************************************************************* ************/void Interrupt1() interrupt 2 using 3{flag=1;}/*************************************************************************/ void Interrupt2() interrupt 1 using 1{ TR0=0;EX1=1;TH0=0xec;TL0=0x78;x--;if(x==0){if((zdirection==1)&&(fdirection==0)&&(on==1)&&(off==0)){P1=FFW[run_i];fdirection=0;led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时drun++;run_i++;if(run_i==8)run_i=0;if(run==drun){on=0;off=1;}}if((zdirection==0)&&(fdirection==1)&&(on==1)&&(off==0)){P1=REV[run_i];led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时zdirection=0;drun++;run_i++;if(run_i==8)run_i=0;if(run==drun){on=0;off=1;}}if((on==0)&&(off=1))P1=0x00; x=y;}TR0=1;}。
片机控制的步进电机C语言程序

51单片机控制的步进电机C语言程序用的是L298驱动的和ULN2003一样,你把它换成2003就行拉#include <AT89X51.H>unsigned char codetable[]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9,0x00,0xf1,0xf9,0xf8,0xfc,0xf4, 0xf6,0xf2,0xf3,0x00};unsigned char temp,temp_old;unsigned char key;unsigned char i,j,k,m,s;void delay(int i){for(m=i;m>0;m--)for(j=250;j>0;j--)for(k=10;k>0;k--);}void saomiao(){P3=0xff;P3_4=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0e:key=1;break;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=4;break;}temp=P3;temp=temp&0x0f; while(temp!=0x0f) {temp=P3;temp=temp&0x0f; }}}P3=0xff;P3_5=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;}temp=P3;temp=temp&0x0f;while(temp!=0x0f) {temp=P3;temp=temp&0x0f; }}}}void main(void){while(1){saomiao();if(key==1){ P1=0;P2=0;saomiao();}if(key==2){temp_old=key;for(s=0;s<8;s++){ P2=table[s]; P1_4=0;delay(13);saomiao();if(key!=temp_old) {P1_4=1;break;}}}if(key==3){temp_old=key;for(s=0;s<8;s++){ P2=table[s]; P1_5=0;delay(5);saomiao();if(key!=temp_old) {P1_5=1;break;}}}if(key==4){temp_old=key;for(s=0;s<8;s++){ P2=table[s]; P1_6=0;delay(20);saomiao();if(key!=temp_old) {P1_6=1;break;}}}if(key==5){temp_old=key;for(s=9;s<17;s++){ P2=table[s]; P1_7=0;delay(13);saomiao();if(key!=temp_old) {P1_7=1;break;}}}if(key==6){temp_old=key;for(s=9;s<17;s++){ P2=table[s]; P1_5=0;delay(5);saomiao();if(key!=temp_old){P1_5=1;break;}}}if(key==7){temp_old=key; for(s=9;s<17;s++){ P2=table[s]; P1_6=0;delay(20);saomiao();if(key!=temp_old){P1_6=1;break;}}}}}C语言程序源代码#include <REGX51.H> // 51寄存器定义#include "intrins.h"#define control P1 //P1_0:A相,P1_1:B相,P1_2:C相,P1_3:D相#define discode P0 //显示代码控制端口#define uchar unsigned char //定义无符号型变量#define uint unsigned intsbit en_dm=P3^0; //显示代码锁存控制sbit en_wk=P3^1; //位控锁存控制uchar code corotation[4]= {0x03,0x06,0x0c,0x09};//电机正转uchar code rollback[4]={0x0c,0x06,0x03,0x09}; //电机反转uchar code tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示字段uint code Levspeed[5]={500,400,300,200,100};//电机速度等级uchar Hscan,speedcount;//Hscan行扫描,speedcount 速度等级计数uint uu; //频率计数uint step,setstep; //step:电机步伐计数,setstep:手动设置电机步伐uint speed=500; //电机初始速度uchar count;uchar flag[5];uchar butcount; //按键次数//****************************************//flag[0] 正转标志//flag[1] 反转标志//flag[2] 加速标志//flag[3] 减速标志//flag[4] 设置标志//****************************************Delay1mS(unsigned int tt) //延时1ms “Delay1mS”延时子程序,用循环语句延时。
单片机驱动步进电机程序代码

/********************************************************实现功能:正转程序使用芯片:AT89S52晶振:11.0592MHZ编译环境:Keil作者:【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!********************************************************/#include<reg52.h> //库文件#define uchar unsigned char //字符型宏定义#define uint unsigned int //整型宏定义uchar tcnt; //定时器计数初值定义uint sec; //速度值定义uchar buf[11];uchar bai,shi,ge;/********************控制位定义*************************/sbit shi_neng=P1^0; // 使能控制位sbit fang_shi=P1^1; // 工作方式控制位sbit fang_xiang=P1^2;// 旋转方向控制位sbit mai_chong=P1^3; // 脉冲控制位/********************延时函数***************************/void delay1ms(uchar z){uchar x,y;for(x=0;x<z;x++)for(y=0;y<110;y++);}/***************************定时中断服务函数*************/void t0(void) interrupt 1 using 0 //定时中断服务函数{tcnt++; //每过250ust tcnt 加一if(tcnt==1) //当tcnt满足条件时{tcnt=0; //计满重新再计sec++;if(sec==6) //括号内数值越小,电机转动速度越快{sec=0; //计满重新再计mai_chong=~mai_chong; //脉冲输出}}}/***********************定时器0/1初始化****************************/void T0_Init(){ET0 = 1;TMOD = 0x22;TH0=0x06; //对TH0 TL0 赋值TL0=0x06;TR0=1; //开始定时sec=0;mai_chong=1; // 脉冲控制位}/***********************串口初始化****************************/void Uart_Init(){TMOD = 0x22;TH1 = 0xFD;TL1 = 0xFD;SCON = 0x50;PCON &= 0xef;TR1 = 1;}/***********************数据接收函数****************************/void ReceiveBuf(){int i;for(i=0;i<11;i++){buf[i] = SBUF;while(RI == 0);RI=0;}}/***********************角度控制函数****************************/ void Control(){if((bai==buf[5])&(shi==buf[6])&(ge==buf[7])){shi_neng=0;};if(bai<buf[5]){shi_neng=1;fang_xiang=0;}else if(bai>buf[5]){shi_neng=1;fang_xiang=1;};if((bai==buf[5])&shi<buf[6]){fang_xiang=0;}else if((bai==buf[5]&shi>buf[6])){shi_neng=1;fang_xiang=1;};if((bai==buf[5])&(shi==buf[6]&(ge<buf[7]))) {shi_neng=1;fang_xiang=0;}else if((bai==buf[5])&(shi==buf[6])&(ge>buf[7])) {shi_neng=1;fang_xiang=1;};if((bai==buf[5])&(shi==buf[6])&(ge==buf[7])) {};delay1ms(3);bai=buf[5];shi=buf[6];ge=buf[7];}/************************主函数****************************/main(){EA=1;T0_Init();Uart_Init();while(1){// shi_neng=1; // 使能控制位fang_shi=1; // 工作方式控制ReceiveBuf();delay1ms(1);Control();delay1ms(10);}}/*************************结束******************************/Welcome To Download !!!欢迎您的下载,资料仅供参考!。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
我上周刚做的这个实验成功拉,给你参考一下吧这可是我当时辛辛苦苦编出来的啊,不过我用的是L298驱动的和ULN2003一样,你把它换成2003就行拉
#include <AT89X51.H>
unsigned char code table[]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf 9,0x00,0xf1,0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0x00};
unsigned char temp,temp_old;
unsigned char key;
unsigned char i,j,k,m,s;
void delay(int i)
{
for(m=i;m>0;m--)
for(j=250;j>0;j--)
for(k=10;k>0;k--);
}
void saomiao()
{
P3=0xff;
P3_4=0;
temp=P3;
temp=temp&0x0f;
if(temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--); temp=P3;
temp=temp&0x0f;
if(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
switch(temp)
{
case 0x0e:
key=1;
break;
case 0x0d:
key=2;
break;
case 0x0b:
key=3;
break;
case 0x07:
key=4;
break;
}
temp=P3;
temp=temp&0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
}
}
P3=0xff;
P3_5=0;
temp=P3;
temp=temp&0x0f;
if(temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp&0x0f;
if(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
switch(temp)
{
case 0x0d:
key=5;
break;
case 0x0b:
key=6;
break;
case 0x07:
key=7;
break;
}
temp=P3;
temp=temp&0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
}
}
}
void main(void)
{
while(1)
{
saomiao();
if(key==1)
{ P1=0;
P2=0;
saomiao();
}
if(key==2)
{
temp_old=key;
for(s=0;s<8;s++)
{ P2=table[s];
P1_4=0;
delay(13);
saomiao();
if(key!=temp_old)
{
P1_4=1;
break;
}
}
}
if(key==3)
{
temp_old=key;
for(s=0;s<8;s++)
{ P2=table[s];
P1_5=0;
delay(5);
saomiao();
if(key!=temp_old)
{
P1_5=1;
break;
}
}
}
if(key==4)
{
temp_old=key;
for(s=0;s<8;s++)
{ P2=table[s];
P1_6=0;
delay(20);
saomiao();
if(key!=temp_old)
{
P1_6=1;
break;
}
}
}
if(key==5)
{
temp_old=key;
for(s=9;s<17;s++)
{ P2=table[s];
P1_7=0;
delay(13);
saomiao();
if(key!=temp_old)
{
P1_7=1;
break;
}
}
}
if(key==6)
{
temp_old=key;
for(s=9;s<17;s++)
{ P2=table[s];
P1_5=0;
delay(5);
saomiao();
if(key!=temp_old)
{
P1_5=1;
break;
}
}
}
if(key==7)
{
temp_old=key;
for(s=9;s<17;s++)
{ P2=table[s];
P1_6=0;
delay(20);
saomiao();
if(key!=temp_old)
{
P1_6=1;
break;
}
}
}
}
}。