步进电机实验C语言程序

合集下载

步进电机控制-C程序及仿真

步进电机控制-C程序及仿真

步进电机控制-C程序及仿真步进电机步进电机和普通电动机不同之处是步进电机接受脉冲信号的控制。

步进电机可以直接接受数字信号,不需要进行数字与模拟量的转换,具有高精度快速启停能力。

在非超载的情况下,步进电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。

这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点。

使得在速度、位置等控制领域用步进电机来控制变的非常的简单。

一、步进电机的结构和工作原理步进电机是一种专门用于位置和速度精确控制的特种电机。

步进电机的最大特点是其“数字性”,对于微电脑发过来的每一个脉冲信号,步进电机在其驱动器的推动下运转一个固定角度(简称一步),如下图所示。

如接收到一串脉冲步进电机将连续运转一段相应距离。

同时可通过控制脉冲频率,直接对电机转速进行控制。

步进电机在构造上有三种主要类型:反应式(Variable Reluctance,VR)、永磁式(Permanent Magnet,PM)和混合式(Hybrid Stepping,HS)。

反应式定子上有绕组、转子由软磁材料组成。

结构简单、成本低、步距角小,可达1.2°、但动态性能差、效率低、发热大,可靠性难保证。

永磁式永磁式步进电机的转子用永磁材料制成,转子的极数与定子的极数相同。

其特点是动态性能好、输出力矩大,但这种电机精度差,步矩角大(一般为7.5°或15°)。

混合式混合式步进电机综合了反应式和永磁式的优点,其定子上有多相绕组、转子上采用永磁材料,转子和定子上均有多个小齿以提高步矩精度。

其特点是输出力矩大、动态性能好,步矩角小,但结构复杂、成本相对较高。

混合型,因具有高精度、高转矩、微小步进角和数个优异的特征,所以刚开始在OA 关系,其它的分类上也大幅的被使用,特别是在生产量上大半是使用在盘片记忆关系的磁头转送上。

按定子上绕组来分,共有二相、三相和五相等系列。

步进电机控制设计(C程序设计语言)

步进电机控制设计(C程序设计语言)

接口课程设计任务书学生姓名专业班级指导老师工作单位计算机学院题目:步进电机控制设计(C程序设计语言)一、内容:在MIFID微机实验台上以双八拍的方式控制步进电机运行,用按钮控制启动和停止。

接口硬件电路图见说明书。

二、要求:1、控制步进电机运行的相序表存储在文件中。

2、按下SW1按钮,从文件中取出一个相序数据,从并行接口8255A的PA口输出,使步进电机运行。

相序数据在CRT上显示。

按下SW2按钮,步进电机运行停止。

3、SW1按钮的数字量由PC1输入,SW2按钮的数字量由PC0输入,4、设计程序运行时的界面友好。

三、进度安排:指导教师签名:年月日系主任(责任教师)签名:年月日一.设计目的和内容目的:通过步进电机控制实验,学习并行接口电路及其控制程序的设计原理与方法。

内容:在MIFID微机实验台上以双八拍的方式控制步进电机运行,用按钮控制启动和停止。

接口硬件电路图见说明书。

要求:1、控制步进电机运行的相序表存储在文件中。

2、按下SW1按钮,从文件中取出一个相序数据,从并行接口8255A的PA口输出,使步进电机运行。

相序数据在CRT上显示。

按下SW2按钮,步进电机运行停止。

3、SW1按钮的数字量由PC1输入,SW2按钮的数字量由PC0输入,4、设计程序运行时的界面友好。

二、实验预备知识可编程并行接口8255是一个具有两个8位(A端口和B端口)和两个4位(C端口)并行I/O端口的芯片。

在与外设进行数据传输时,把A、B、C3个端口分为两组。

A组由A端口和C端口的高4位组成。

B组由B端口和C端口的低4位组成。

为了满足多种数据传输的要求,可以通过对8255的编程用方式控制字设置3种工作方式来实现。

这3种工作方式为:方式0(基本I/O工作方式);方式1(选通I/O工作方式);方式2(双向传送方式)。

8255的控制字有工作方式控制字和C端口的位置位/复位控制字。

工作方式控制字是必须要预先设定的,C端口的位置位/复位控制字可视需要而定。

89C51单片机对步进电动机的C语言控制程序

89C51单片机对步进电动机的C语言控制程序

89C51单片机对步进电动机的控制程序啊?兄弟做的如何了?我也是不懂啊,真是有点同病相怜了这个程序是课程设计的,现在老师要复杂点的,不让用延时程序了,因为浪费CPU时间,改为定时器扫描防抖,还有显示是用四个数码管,用四个键控制,其中一个起停,一个正反转,两个加减速。

我只能写到这些了,你有何进展,交流一下吧#define uchar unsigned char //定义一下方便使用#define uint unsigned int#define ulong unsigned long#include <reg52.h> //包括一个52标准内核的头文件sbit P10 = P1^0; //头文件中没有定义的IO就要自己来定义了sbit P11 = P1^1;sbit P12 = P1^2;sbit P13 = P1^3;sbit K1 = P3^2;sbit K2 = P3^5;sbit K3 = P3^6;sbit K4 = P3^7;sbit P20=P2^0;sbit P21=P2^1;bit ldelay=0; //长定时溢出标记,预置是0uchar a,m=50;uchar result;uint b,n;uint i,j;char code dx516[3] _at_ 0x003b;//这是为了仿真设置的/*********************************************************************** ***********///电机正转void zheng_z(){ uchar code ledp1[8]={0xfe,0xfc,0xfd,0xf9,0xfb,0xf3,0xf7,0xf6};//预定的写入P1的值正转uchar ledi1; //用来指示正转显示顺序P1=ledp1[ledi1];//读出一个值送到P1口ledi1++;//指向下一个if(ledi1==8)ledi1=0; //到了最后一个灯就换到第一个}//电机反转void fan_z(){ uchar code ledp2[8]={0xf6,0xf7,0xf3,0xfb,0xf9,0xfd,0xfc,0xfe};//预定的写入P1的值反转uchar ledi2; //用来指示反转显示顺序P1=ledp2[ledi2];//读出一个值送到P1口ledi2++; //指向下一个if(ledi2==8)ledi2=0; //到了最后一个灯就换到第一个}//减速void jian_s(){m+=5;if(m>=50)m=50;}//加速void jia_su(){ m-=5;if(m<=10)m=10;}/*******************************************************************/ void delay(uint j){j=100;for(i=0;i<j;i++){;}}void display(uint x){switch(x){case 0: P0=0xC0;break;case 1: P0=0xF9;break;case 2: P0=0xA4;break;case 3: P0=0xB0;break;case 4: P0=0x99;break;case 5: P0=0x92;break;case 6: P0=0x82;break;case 7: P0=0xF8;break;case 8: P0=0x80;break;case 9: P0=0x90;break;}}void sudu(uint c){switch(c){case 50: result=15;break;case 45: result=17;break;case 40: result=19;break;case 35: result=21;break;case 30: result=25;break;case 25: result=30;break;case 20: result=38;break;case 15: result=50;break;case 10: result=75;break;}}/*******************************************************************/ //主程序void main(void){TMOD = 0x01; //设定时器0为16位模式TH0 =0xdb; //赋T0的预置值0xdbTL0 =0xff;TR0=1; //启动定时器ET0=1; //打开定时器0中断EA=1; //打开总中断while(1) //主程扫描各键值{if(ldelay) //发现有时间溢出标记,进入处理{ldelay=0; //清除标记zheng_z();if(!K3)a=1; //如果读到K3为0if(!K4)a=0; //如果读到K4为0if(a==1)zheng_z();elsefan_z();if(!K1) //如果读到K1为0jian_s(); //减速if(!K2) //如果读到K2为0jia_su(); //加速/*********************************************************************** ************/sudu(m);b=result/10;n=result%10;P20=1;P21=0;display(b);delay (2);P20=~P20;P21=~P21;display(n);delay (2);}}}//定时器0中断timer0() interrupt 1{static uchar t;TH0 =0xdb; //赋T0的预置值0xdbTL0 =0xff;//TF0=0;t++;if(t==m){ t=0;ldelay=1;}}//定时器1中断/*timer1() interrupt 3{static uchar t;TF0=0;t++;if(t==20) { t=0; ldelay=1; } }*/。

c语言电动机正转反转程序,步进电机正反转和加速减速c源程序

c语言电动机正转反转程序,步进电机正反转和加速减速c源程序

c语⾔电动机正转反转程序,步进电机正反转和加速减速c源程序这是⼀个群⾥朋友发给我的步进电机实现正转反转和加速减速的单⽚机c语⾔源程序,这⾥给⼤家共享下,有需要的朋友直接复制到keil⾥编译就可以了,程序已测试成功。

/*****************************************单4拍正转 zheng[]={0x01,0x08,0x04,0x02}单4拍反转 fang[]={0x01,0x02,0x04,0x08}双4拍正转 zheng[]={0x09,0x0c,0x06,0x03}双4拍反转 fang[]={0x03,0x06,0x0c,0x09}单双8拍正转 zheng[]={0x01,0x09,0x08,0x0c,0x04,0x06,0x02,0x03}单双8拍反转 fang[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}*****************************************/#include"reg51.h"#include"intrins.h"#define uchar unsigned char#define uint unsigned intbit front_move,back_move;uchar jzaj(void); //单4拍正转 zheng[]={0x01,0x08,0x04,0x02}; 单4拍反转 fang[]={0x01,0x02,0x04,0x08};void ajcl(uchar jz);void delay(uchar del);uchar code zheng[]={0x01,0x09,0x08,0x0c,0x04,0x06,0x02,0x03};uchar code fang[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};void timer0() interrupt 1{static uchar jz;TH0=0xfc;TL0=0x18;jz=jzaj();if(jz)ajcl(jz);}//步进电机正反转和加速减速程序void main(){uchar count=0;TMOD=0x01;TH0=0xFC;TL0=0x18;TR0=1;ET0=1;EA=1;while(1){if(front_move){P2=zheng[count];delay(100);count++;if(count==8) count=0;}if(back_move){P2=fang[count];delay(100);count++;if(count==8) count=0;}}}uchar jzaj(void){uchar hz,lz;P1=0xf0; //置所有⾏为低电平,⾏扫描,列线输⼊(此时)if((P1&0xf0)!=0xf0) //判断是否有有键按下(读取列的真实状态,若第4列有键按下则P1的值会变成0111 0000),有往下执⾏{delay(10); //延时去抖动(10ms)if((P1&0xf0)!=0xf0) //再次判断列中是否是⼲扰信号,不是则向下执⾏{hz=0xfe; //逐⾏扫描初值(即先扫描第1⾏)while((hz&0x10)!=0) //⾏扫描完成时(即4⾏已经全部扫描完成)sccode为1110 1111 停⽌while程序{P1=hz; //输出⾏扫描码if ((P1&hz)!=hz) //***(P2&0xf0)!=0xf0***也可这样 本⾏有键按下(即P1(真实的状态)的⾼四位不全为1){lz=(P1&0xf0)|0x0f; //列while((P1&0xf0)!=0xf0);return((~hz)|(~lz)); //返回⾏和列break; //有按键返回 提前退出循环}else //所扫描的⾏没有键按下,则扫描下⼀⾏,直到4⾏都扫描,此时sccode值为1110 1111 退出while程序hz=_crol_(hz,1);//⾏扫描码左移⼀位}}}elsereturn 0; //⽆键按下,返回0}void ajcl(uchar jz){if(jz==0x11){back_move=0;front_move=1;}if(jz==0x21){front_move=0;back_move=1;}if(jz==0x41){P2=0x00;front_move=0;back_move=0;}}void delay(uchar del) {uchar i;for(;del>0;del--)for(i=0;i<125;i++) {;}}。

步进电机c程序

步进电机c程序

步进电机控制程序(2008-06-05 19:07:55)转载分类:程序设计标签:it步进电机(键盘控制可调速)#include <reg51.h>#define uchar unsigned charstatic unsigned int count; //计数static int step_index; //步进索引数,值为0-7static bit turn; //步进电机转动方向static bit stop_flag; //步进电机停止标志static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢static int spcount; //步进电机转速参数计数void ddelay(void); //键盘扫描延时函数void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒void gorun(); //步进电机控制步进函数sbit P10=P2^0 ; //电机端口定义sbit P11=P2^1 ;sbit P12=P2^2;sbit P13=P2^3 ;void ddelay(void){uchar i;for (i=300;i>0;i--);}uchar keyscan(void){uchar scancode;uchar tmpcode;P1 = 0xf8; // 发全0行扫描码if ((P1&0xf8)!=0xf8) // 若有键按下{ddelay(); // 延时去抖动if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响{scancode = 0xfe;while((scancode&0x08)!=0) // 逐行扫描{P1 = scancode; // 输出行扫描码if ((P1&0xf8)!=0xf8) // 本行有键按下tmpcode = (P1&0xf8)|0x07;return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列 }else scancode = (scancode<<1)|0x01; // 行扫描码左移一位}}}return(0); // 无键按下,返回值为0}void main(void){uchar key;count = 0;step_index = 0;spcount = 0;P10 = 0;P11 = 0;P12 = 0;P13 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFc;TL0 = 0x18; //设定时每隔1ms中断一次TR0 = 1; //开始计数stop_flag = 0;turn=0;speedlevel = 20;while(1){key = keyscan();switch(key){case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5Sstop_flag=0;turn = 0;speedlevel =10;gorun();delay(1000);break;case 0x0c: //按键*,停止2000*0.5MS=0.5Sstop_flag=1;break;case 0x0a: //按键0,反转以speedlevel = 1的速度转1000*0.5MS=0.5Sstop_flag=0;turn=1;speedlevel =10;gorun();delay(1000);break;case 0x11: // 按键9,以--speedlevel的加速转1000*0.5MS=0.5Sstop_flag=0;if (speedlevel==1){ speedlevel=1;}else { --speedlevel;}gorun();delay(1000);break;case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5Sstop_flag=0;++speedlevel;gorun();delay(1000);break;}}}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFc;TL0=0x18; //设定时每隔1ms中断一次count++;spcount--;if(spcount<=0) //速度调整,SPEEDLEVEL越大,延时越长(延时约为1MS*SPEEDLEVEL),{ // 频率越小,速度越慢spcount = speedlevel;gorun();}}void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒{count=0;do{}while(count<endcount);void gorun(){if (stop_flag==1) {P10 = 0;P11 = 0;P12 = 0;P13 = 0;return;}switch(step_index) {case 0: //0P10 = 1;P11 = 0;P12 = 0;P13 = 0;break;case 1: //0、1P10 = 1;P11 = 1;P12 = 0;P13 = 0;break;case 2: //1P10 = 0;P11 = 1;P12 = 0;P13 = 0;break;case 3: //1、2P10 = 0;P11 = 1;P12 = 1;P13 = 0;break;case 4: //2P10 = 0;P11 = 0;P12 = 1;P13 = 0;break;case 5: //2、3P10 = 0;P11 = 0;P12 = 1;P13 = 1;break;case 6: //3P10 = 0;P11 = 0;P12 = 0;P13 = 1;break;case 7: //3、0P10 = 1;P11 = 0;P12 = 0;P13 = 1;}if (turn==0) //正转{step_index++;if (step_index>7)step_index=0;}else{ //反转step_index--;if (step_index<0)step_index=7;}}步进电机(键盘控制可调速加显示)#include <reg51.h>#define uchar unsigned charstatic unsigned int count; //计数static int step_index; //步进索引数,值为0-7static bit turn; //步进电机转动方向static bit stop_flag; //步进电机停止标志static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢static int spcount; //步进电机转速参数计数void ddelay(void); //键盘扫描延时函数void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒void gorun(); //步进电机控制步进函数void Delay400Ms(void);void LCMInit(void); //LCM初始化void WriteCommandLCM(unsigned char WCLCM,BuysC); //BuysC为0时忽略忙检测void DisplayOneChar(uchar X, uchar Y, uchar DData);void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar *DData,uchar n);sbit P10=P3^0 ; //电机端口定义sbit P11=P3^1 ;sbit P12=P3^2;sbit P13=P3^3 ;uchar code speed[]={ 0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30};uchar code stop[] = {"stop"};uchar code go[] = {"go:"};uchar code back[] = {"back:"};uchar code max[] = {"max:8"};void ddelay(void){uchar i;for (i=300;i>0;i--);}uchar keyscan(void){uchar scancode;uchar tmpcode;P1 = 0xf8; // 发全0行扫描码if ((P1&0xf8)!=0xf8) // 若有键按下{ddelay(); // 延时去抖动if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响{scancode = 0xfe;while((scancode&0x08)!=0) // 逐行扫描{P1 = scancode; // 输出行扫描码if ((P1&0xf8)!=0xf8) // 本行有键按下{tmpcode = (P1&0xf8)|0x07;return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列 }else scancode = (scancode<<1)|0x01; // 行扫描码左移一位}}}return(0); // 无键按下,返回值为0}void main(void){uchar key;count = 0;step_index = 0;spcount = 0;P10 = 0;P11 = 0;P12 = 0;P13 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFc;TL0 = 0x18; //设定时每隔1ms中断一次TR0 = 1; //开始计数P0=0XFF;P3 &=0XEF; //573片选LCMInit(); //LCM初始化Delay400Ms();stop_flag = 0;turn=0;speedlevel = 5;DisplayListChar(0,0,3,go,1); //每次扫描键盘显示更新一次uchar code go[] DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次while(1){key = keyscan();switch(key){case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S stop_flag=0;turn = 0;speedlevel =5;gorun();WriteCommandLCM(0x01,1);//显示清屏,DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[] DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次delay(1000);break;case 0x0c: //按键*,停止2000*0.5MS=0.5Sstop_flag=1;WriteCommandLCM(0x01,1);//显示清屏,DisplayListChar(0,0,4,stop,0); //每次扫描键盘显示更新一次break;case 0x0a: //按键0,反转以speedlevel = 1的速度转1000*0.5MS=0.5S stop_flag=0;turn=1;speedlevel =5;gorun();WriteCommandLCM(0x01,1);//显示清屏,DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次delay(1000);break;case 0x11: // 按键9,以--speedlevel的加速转1000*0.5MS=0.5Sstop_flag=0;if (speedlevel==2){ speedlevel=2;}else { speedlevel--;}gorun();if(speedlevel==2){ DisplayListChar(0,1,5,max,0);}else {DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次 delay(1000);break;case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5Sstop_flag=0;speedlevel++;gorun();WriteCommandLCM(0x01,1);//显示清屏,if(turn==0){DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[] DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次else {DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次DisplayOneChar(0,1,speed[speedlevel]);} //每次扫描键盘显示更新一次delay(1000);break;}}}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFc;TL0=0x18; //设定时每隔1ms中断一次count++;spcount--;if(spcount<=0) //速度调整,SPEEDLEVEL越大,延时越长(延时约为1MS*SPEEDLEVEL),{ // 频率越小,速度越慢spcount = speedlevel;gorun();}}void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒{count=0;do{}while(count<endcount);}void gorun(){if (stop_flag==1){P10 = 0;P11 = 0;P12 = 0;P13 = 0;return;}switch(step_index){case 0: //0P10 = 1;P11 = 0;P12 = 0;P13 = 0;break;case 1: //0、1P10 = 1;P11 = 1;P12 = 0;P13 = 0;break;case 2: //1P10 = 0;P11 = 1;P12 = 0;P13 = 0;break;case 3: //1、2P10 = 0;P11 = 1;P12 = 1;P13 = 0;break;case 4: //2P10 = 0;P11 = 0;P12 = 1;P13 = 0;break;case 5: //2、3P10 = 0;P11 = 0;P12 = 1;P13 = 1;break;case 6: //3P10 = 0;P11 = 0;P12 = 0;P13 = 1;break;case 7: //3、0P10 = 1;P11 = 0;P12 = 0;P13 = 1;}if (turn==0) //正转 {step_index++;if (step_index>7)step_index=0; }else{ //反转step_index--;if (step_index<0)step_index=7;}}步进电机(自动循环调速)#include <reg51.h>sbit P00=P2^0 ;sbit P01=P2^1 ;sbit P02=P2^2;sbit P03=P2^3 ;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;P00 = 0;P01 = 0;P02 = 0;P03 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFE;TL0 = 0x0C; //设定时每隔0.5ms中断一次TR0 = 1; //开始计数turn = 0;do{speedlevel =4;delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1Sspeedlevel =4;delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1Sstop_flag=1;delay(6000);//停止,2000*0.5MS=3Sstop_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){P00 = 0;P01 = 0;P02 = 0;P03 = 0;return;}switch(step_index){case 0: //0P00 = 1;P01 = 0;P02 = 0;P03 = 0;break;case 1: //0、1P00 = 1;P01 = 1;P02 = 0;P03 = 0; break;case 2: //1P00 = 0;P01 = 1;P02 = 0;P03 = 0; break;case 3: //1、2P00 = 0;P01 = 1;P02 = 1;P03 = 0; break;case 4: //2P00 = 0;P01 = 0;P02 = 1;P03 = 0; break;case 5: //2、3P00 = 0;P01 = 0;P02 = 1;P03 = 1; break;case 6: //3P00 = 0;P01 = 0;P02 = 0;P03 = 1; break;case 7: //3、0P00 = 1;P01 = 0;P02 = 0;P03 = 1;}if (turn==0){step_index++;if (step_index>7) step_index=0; }else{step_index--;if (step_index<0)step_index=7;}}步进电机控制Link - Thu, 17 Jan 2008 12:41:32 +0800Description:本设计采用的步进电机为35BYJ46型四相八拍电机,电压为DC12V。

步进电机实验C语言程序

步进电机实验C语言程序
步进电机实验c语言程序 #include #define uint unsigned int #define uchar unsigned char uchar fed[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //zheng uchar rvs[]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; //fan sbit key1=p0^0;启动sbit key2=p0^7;停止sbit key3=p0^2; sbitkey4=p0^3; sbitkey5=p0^4;升速sbit key6=p0^5; voiddelay100us(uint do{x=46; do{ }while(--x!=0); }while(--z!=0); voidmain() ucharqt=0,ss=0,js=0,bs=10; while(1) p1=0x00;if(key1==0) qt=1;//启动 qt=0;//停止 ss=1;//加速 js=0;//减速 p1=fed[i];delay100us(bs); if(ss==1) ss=0;bs=bs-3; p1=rvs[i];delay100us(bs); if(js==1) js=0;bs=bs+3; p1=0x00;if(key3==0) p1=fed[i];delay100us(10); p1=rvs[i];delay100us(10); chenxiao9996 分享于 2015-02-03 00:56:8.0 步进电机实验c语言程序 文档格式: .docx 文档页数: 3页 文档大小: 9.7k 文档热度: 文档分类: 中学教育 -- 高中教育 文档标签: 步进电机 sbit uchar 语言 实验 程序 步进电机实验c语言程序

c语言实现单片机控制步进电机加减速源程序

c语言实现单片机控制步进电机加减速源程序

C 语言实现单片机控制步进电机加减速源程序1. 引言在现代工业控制系统中,步进电机作为一种常见的执行元件,广泛应用于各种自动化设备中。

而作为一种常见的嵌入式软件开发语言,C 语言在单片机控制步进电机的加减速过程中具有重要的作用。

本文将从单片机控制步进电机的加减速原理入手,结合 C 语言的编程技巧,介绍如何实现单片机控制步进电机的加减速源程序。

2. 单片机控制步进电机的加减速原理步进电机是一种能够精确控制角度的电机,它通过控制每个步骤的脉冲数来实现旋转。

在单片机控制步进电机的加减速过程中,需要考虑步进电机的加速阶段、匀速阶段和减速阶段。

在加速阶段,需要逐渐增加脉冲的频率,使步进电机的转速逐渐增加;在匀速阶段,需要保持恒定的脉冲频率,使步进电机以匀速旋转;在减速阶段,需要逐渐减小脉冲的频率,使步进电机的转速逐渐减小。

这一过程需要通过单片机的定时器和输出控制来实现。

3. C 语言实现步进电机加减速的源程序在 C 语言中,可以通过操作单片机的 GPIO 来控制步进电机的旋转。

在编写源程序时,需要使用单片机的定时器模块来生成脉冲信号,以控制步进电机的旋转角度和速度。

以下是一个简单的 C 语言源程序,用于实现步进电机的加减速控制:```c#include <reg52.h>void main() {// 初始化定时器// 设置脉冲频率,控制步进电机的加减速过程// 控制步进电机的方向// 控制步进电机的启停}```4. 总结与回顾通过本文的介绍,我们了解了单片机控制步进电机的加减速原理和 C 语言实现步进电机加减速源程序的基本思路。

掌握这些知识之后,我们可以更灵活地应用在实际的嵌入式系统开发中。

在实际项目中,我们还可以根据具体的步进电机型号和控制要求,进一步优化 C 语言源程序,实现更加精准和稳定的步进电机控制。

希望本文能为读者在单片机控制步进电机方面的学习和应用提供一定的帮助。

5. 个人观点与理解在我看来,掌握 C 语言实现单片机控制步进电机加减速源程序的技术是非常重要的。

控制步进电机实验报告(3篇)

控制步进电机实验报告(3篇)

第1篇一、实验目的1. 理解步进电机的工作原理及控制方法。

2. 掌握单片机与步进电机驱动模块的接口连接方法。

3. 学习使用C语言编写程序,实现对步进电机的正反转、转速和定位控制。

4. 通过实验,加深对单片机控制系统的理解。

二、实验原理步进电机是一种将电脉冲信号转换为角位移或线位移的电机,其特点是控制精度高、响应速度快、定位准确。

步进电机控制实验主要涉及以下几个方面:1. 步进电机驱动模块:常用的驱动模块有ULN2003、A4988等,它们可以将单片机的数字信号转换为步进电机的控制信号。

2. 单片机:单片机是整个控制系统的核心,负责接收按键输入、处理数据、控制步进电机驱动模块等。

3. 步进电机:步进电机分为单相、双相和三相等类型,本实验使用的是双相四线步进电机。

三、实验设备1. 单片机开发板:例如STC89C52、STM32等。

2. 步进电机驱动模块:例如ULN2003、A4988等。

3. 双相四线步进电机。

4. 按键。

5. 数码管。

6. 电阻、电容等元件。

7. 电源。

四、实验步骤1. 硬件连接(1)将步进电机驱动模块的输入端(IN1、IN2、IN3、IN4)分别连接到单片机的P1.0、P1.1、P1.2、P1.3口。

(2)将按键的输入端连接到单片机的P3.0口。

(3)将数码管的段选端连接到单片机的P2口。

(4)将步进电机驱动模块的电源端连接到电源。

(5)将步进电机连接到驱动模块的输出端。

2. 编写程序(1)初始化单片机I/O端口,设置P1口为输出端口,P3.0口为输入端口,P2口为输出端口。

(2)编写按键扫描函数,用于读取按键状态。

(3)编写步进电机控制函数,实现正反转、转速和定位控制。

(4)编写主函数,实现以下功能:a. 初始化数码管显示;b. 读取按键状态;c. 根据按键状态调用步进电机控制函数;d. 更新数码管显示。

3. 调试程序(1)将程序烧写到单片机中;(2)打开电源,观察数码管显示和步进电机运行状态;(3)根据需要调整程序,实现不同的控制效果。

步进电机C语言程序

步进电机C语言程序

C语言程序清单#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <bios.h>#include <ctype.h>#include <process.h>void dis(void);void key(void);void clear(void);void ccscan(void);void action(void);void putbuf(void);void getkey(void);void delay0(int time);void keyscan(void);void delay1(int time);#define IOY0 0x0C400#define MY8255_A IOY0+0x00*4#define MY8255_B IOY0+0x01*4#define MY8255_C IOY0+0x02*4#define MY8255_MODE IOY0+0x03*4char a[]={0x6d,0x79,0x73,0x77,0x39,0x06,0x5b,0x4f,0x66,0x80};char b[]={0x00,0x09,0x04,0x05};char c[] = {0x10,0x30,0x20,0x60,0x40,0xc0,0x80,0x90};int dir=1;int mode=0;int grd=1;int cc;int n;void main(){int i=0;int j;outp(MY8255_MODE, 0x81);while(1){while((i<=7)&&(i>=0)){while(1){keyscan();if(mode==1) break; key();}if(dir==1) i++;if(dir==0) i--;outp(MY8255_C, c[i]); if(grd==4)for(j=500;j>0;j--) {delay1(0x10); keyscan();}if(grd==3)for(j=1000;j>0;j--) {delay1(0x10); keyscan();}if(grd==2)for(j=3000;j>0;j--) {delay1(0x10); keyscan();}if(grd==1)for(j=5000;j>0;j--){delay1(0x10); keyscan();}key();}if(i>7) i=0;if(i<0) i=7;}}void delay1(int time){int i;int j;for(i=0;i<=time;i++){for(j=0;j<=0x700;j++){ }}return;}void keyscan(){dis();clear();ccscan();if (cc){dis();delay0(0x100);delay0(0x100);clear();ccscan();if (cc){getkey();putbuf();}}key();}void getkey(void){int i;int j = 0xfe;for(i=0;i<=3;i++){outp(MY8255_A, j);if ( !( (inp(MY8255_C)) & 0x01) ) {n = i + 0;action();return;}if ( !( (inp(MY8255_C)) & 0x02) ) {n = i + 4;action();return;}if ( !( (inp(MY8255_C)) & 0x04) ) {n = i + 8;action();return;}if ( !( (inp(MY8255_C)) & 0x08) ) {n = i + 12;action();return;}j <<= 1;}}void ccscan(void){outp(MY8255_A, 0x00);cc = inp(MY8255_C);cc = (~cc) & 0x0F;}void dis(void){int i;int j = 0xf7;for(i=3;i>=0;i--){outp(MY8255_A, j);outp(MY8255_B, a[b[i]]); delay0(0x100);j >>= 1;j |= 0x80;}}void clear(void){outp(MY8255_B, 0x00);}void action(void){if(n==0){if(dir==1) dir=0; else dir=1;}if(n==1){if(mode==1) mode=2; else mode=1;}if(n==2){dir=1;mode=0;grd=1;}if(n==4) grd=1;if(n==5) grd=2;if(n==6) grd=3;if(n==7) grd=4;}void putbuf(void){b[0]=mode;b[2]=dir+3;b[3]=grd+4;dis();clear();ccscan();while (cc){dis();clear();ccscan();}}void key(void){if (bioskey(1) != 0){exit(0);}}void delay0(int time){int i;int j;for(i=0;i<=time;i++){for(j=0;j<=0x100;j++) { }}return;}。

电子设备控制的步进电机正反转和加速减速C程序

电子设备控制的步进电机正反转和加速减速C程序

电子设备控制的步进电机正反转和加速减速C程序简介本文档介绍了如何使用C程序实现电子设备控制中步进电机的正反转和加速减速功能。

步骤以下是实现步进电机正反转和加速减速功能的步骤:1. 引入必要的库文件:在C程序中,首先需要引入适当的库文件来支持步进电机的控制功能。

2. 定义引脚:根据实际连接的硬件,定义步进电机相关的引脚。

3. 初始化引脚:在程序的开头部分,将步进电机相关的引脚初始化为适当的输入或输出。

4. 正转功能:编写代码来实现步进电机的正转功能,包括控制引脚的状态、延时等。

5. 反转功能:编写代码来实现步进电机的反转功能,包括控制引脚的状态、延时等。

6. 加速减速功能:编写代码来实现步进电机的加速减速功能,可以使用循环来实现逐渐增加或减少延时的效果。

7. 主程序:在主程序中调用以上功能函数,根据需要实现步进电机的正反转和加速减速。

8. 编译和调试:将代码编译为可执行文件,并在目标设备上进行调试和测试。

注意事项在编写和运行C程序时,需要注意以下事项:- 确保引脚定义正确:根据实际情况,确认步进电机相关的引脚定义是正确的。

- 调试和测试:在运行程序之前,可以先进行调试和测试。

可以逐步调试代码,确保每个功能都正常工作。

- 安全性考虑:在使用C程序控制电子设备时,需要考虑安全问题。

确保代码的执行不会对设备或人员造成危险。

结论本文档介绍了如何使用C程序实现电子设备控制中步进电机的正反转和加速减速功能。

按照以上步骤进行编码和调试,即可实现所需功能。

在编写和运行程序时,请注意相关安全事项。

步进电机控制程序(c语言51单片机)

步进电机控制程序(c语言51单片机)
delay ( Delay_time );
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; }
}
P1 = 0xff;
if ( pri_dj ) break;
if ( !key_puse ) {
fx_run();
}
}
}
void run () {
#define Delay_time 180
/* 转一圈 50 次循环,每循环 4 步 ,50 * 4 = 200 , 200 * 1。8 = 360 */
one_round_flg = 1;
tmp = round_num / Chilun_Num ;
set_display_num();
P0 = 0xf0;
void display ();
void delay(uint delay_time) { uint i; for (i=0; i < delay_time ; i++) ; }
void run ();
void fx_run();
uint round_num = 0; /* 记录已转的 齿轮数 , 中断1次 加 1*/
for ( i="0" ; bujin_zx_stop & !pri_dj;i++ ){
P1 = 0xf9;
delay ( Delay_time ); // bujin_zx_stop = P3^3;

步进电机调速控制系统设计C语言程序及说明

步进电机调速控制系统设计C语言程序及说明

步进电机调速控制系统设计C语言程序及说明使用元器件:单片机8051、步进电机17H185H-04A、128细分/3.0A步进电机驱动器、LED显示器。

实现控制功能:以8051单片机为控制器,系统设四个按键:“工作/停止按键"、“加速按键”、“减速按键”、“正反向控制按键”。

系统上电后,按下“正反向控制按键",控制电机正反转;每按一次“加速按键”后,步进电机由低向高加速一级,每按一次“减速按键”后,由高向低减速一级;按“工作/停止按键"后,电机停止转动,系统回到等待状态。

同时需要显示运行状态和转速(以实际转速或等级表示).程序清单及说明#include<reg52。

h>sbit EN=P2^0; //使能输出sbit DIR=P2^1; //方向控制sbit PWM=P2^2;//PWM输出sbit zled=P2^6;//正转信号灯sbit fled=P2^7;//反转信号灯sbit sw1=P0^0;//启停按钮sbit sw2=P0^1;//正反转按钮sbit sw3=P0^2;//加速按钮sbit sw4=P0^3;//减速按钮unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};unsigned char i,j,k,temp=0,zkb=5,zkb1=0,speed=0;void delay()//延时10ms{for(i=20;i>0;i--)for(j=248;j〉0;j--);}void InitTimer0(void) //T0定时器初始化{TMOD = 0x00; //设置定时器方式0TH0 = 0xef;//高8位送初值TL0 = 0xdd; //低8位送初值EA = 1; //开中断总允许ET0 = 1;//开T0中断允许TR0 = 1; //启动T0开始定时}void main() //主程序{InitTimer0();EN=1; //初始使能端输出0DIR=1;//方向端输出1zled=0;//正传信号灯端口输出0,灯亮fled=1;//反转信号灯输出1,灯不亮while(1){P1=table[speed];//启停if(sw1==0)//判断启停键按下{delay(); //调用延时程序if(sw1==0)//再判断,启停键按下{while(sw1==0);//启停键按下,使能端取反EN=~EN;}}//正反转子程序if(sw2==0) //判断换向键是否按下{delay();if(sw2==0){while(sw2==0);DIR=~DIR; //换向键按下,方向端口取反fled=~fled; //正传指示灯控制端取反zled=~zled;//反转传指示灯控制端取反}}//加速子程序if(sw3==0) //判断加速键是否按下{delay();if(sw3==0){while(sw3==0); //加速键按下if(speed>=5)//判断转速是否大于5 speed=5; //大于5,保持5级转速elsespeed++;//小于5,加速一级}}//减速子程序if(sw4==0) //判断减速键是否按下{delay();if(sw4==0){while(sw4==0);//减速键按下if(speed==1) //转速为1,保持1级转速speed=1;elsespeed—-; //转速不为1,减速1级}}}}void Timer0Interrupt(void) interrupt 1switch(speed)//加减速按键按下,对应选择T0初值,进入终端产生不同频率脉冲{case 1:TH0=0XDD;break;case 2:TH0=0XE1;break;case 3:TH0=0XE5;break;case 4:TH0=0XEa;break;case 5:TH0=0xf0;break;}TL0 = 0xdd;if(zkb1〉=10)zkb1=0;zkb1++;if(zkb1〈=5)PWM=1;elsePWM=0;}。

步进电机C语言代码

步进电机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; }}。

msp430单片机控制步进电机实验的电路图及C程序

msp430单片机控制步进电机实验的电路图及C程序

各模块的电路图如下:试验程序如下:#include <msp430x14x.h>#define DCO_FREQ 1000000 // DCO frequency#define ONE_SEC_CNT 512 // Number of WDT interrupts in 1 second#define DEBOUNCE_CNT 0x05 // (1/512)*5 = ~10 msec debounce#define DIR_MASK 0x01 // 0x01 is clockwise, 0x00 is counter-clockwise #define STEP_MASK 0x02 // 0x00 is full-stepping, 0x02 is half-stepping #define MOTION_MASK 0x04 // 0x00 is continuous, 0x04 is single-step#define DEFAULT_RA TE 0x8000 // Default stepping rate#define MIN_RATE 0x8000 // Minimum stepping rate#define MAX_RATE 0x0800 // Maximum stepping rate// Default state is full-stepping, clockwise, continuousunsigned char state = 1; // State variableunsigned char stepIndex = 0; // State table indexunsigned int rate = DEFAULT_RA TE; // Stepping rateunsigned char change_rate_flag = 0; // Flag indicating rate changeunsigned int max_rate = MAX_RA TE; // Maximum stepping rateunsigned int min_rate = MIN_RA TE; // Minimum stepping rate unsigned int SW[4];void sys_init(void);void Set_DCO(unsigned long freq);void timerA_Init(void);void uart0_Init(void);void wdt_Init(void);void toggle_stepping_mode(void);void increase_stepping_rate(void);void decrease_stepping_rate(void);void toggle_motion(void);void toggle_direction(void);//定义串口操作变量char nRev_UART0; // 串口0 的接收标志char UART0_TX_BUF[10]; // 串口0 的发送缓冲区char UART1_RX_Temp[10];char UART0_RX_BUF[10]; // 串口0 的接收缓冲区int nTX0_Len;int nRX0_Len;int nRX0_Len_temp;char nTX0_Flag;int nSend_TX0;// 整步状态表Astatic const unsigned char fullStepA[] ={0x00,0x00,0x01,0x01};// 半步状态表Bstatic const unsigned char fullStepB[] ={0x01,0x00,0x00,0x01};// 半步状态表Astatic const unsigned char HalfStepA[] = {0x01, // 001 10x06, // 110 20x00, // 000 30x00, // 000 40x00, // 000 50x07, // 111 60x01, // 001 70x01 // 001 8};// 逆时钟、半步状态表Bstatic const unsigned char CcwHalfStepB[] = {0x01, // 001 10x01, // 001 20x01, // 001 30x06, // 110 40x00, // 000 50x00, // 000 60x00, // 000 70x07 // 111 8};// 顺时钟、半步状态表Bstatic const unsigned char CwHalfStepB[] = {0x00, // 000 10x00, // 000 20x00, // 000 30x07, // 111 40x01, // 001 50x01, // 001 60x01, // 001 70x06 // 110 8};void main(void){int i;// 停止WDTWDTCTL = WDTPW + WDTHOLD;sys_init();_EINT();for(;;){if(nRev_UART0 == 1){nRev_UART0 = 0;for(i = 0;i < nRX0_Len;i++) UART1_RX_Temp[i] = UART0_RX_BUF[i];if((UART1_RX_Temp[0] == 'A') && (UART1_RX_Temp[1] == 'T')){UART0_TX_BUF[0] = 'O';UART0_TX_BUF[1] = 'K';UART0_TX_BUF[2] = 13;nTX0_Len = 3;switch(UART1_RX_Temp[2]){case 'D': // 方向toggle_direction();break;case 'C': // 运动模式toggle_motion();break;case 'M': // 步进模式toggle_stepping_mode();break;case 'F': // 增加速率increase_stepping_rate();break;case 'S': // 降低速率decrease_stepping_rate();break;default: break;}}else{UART0_TX_BUF[0] = 'E';UART0_TX_BUF[1] = 'R';UART0_TX_BUF[2] = 'O';UART0_TX_BUF[3] = 'R';UART0_TX_BUF[4] = 'R';UART0_TX_BUF[5] = 13;nTX0_Len = 6;}// 设置中断标志,进入发送中断程序IFG1 |= UTXIFG0;nRX0_Len = 0;}}}void sys_init(void){// 设置下降沿触发中断P1IES = 0x0f;P1IFG = 0x00;P1IE = 0x0f;// 设置P2.3,2,1,0 为输出// 设置P3.3,2,1,0 为输出P2OUT = 0x00;P3OUT = 0x00;P2DIR |= 0x0f;P3DIR |= 0x0f;// 设置DCOSet_DCO(DCO_FREQ);// 初始化Timer AtimerA_Init();// 初始化UART0uart0_Init();// 初始化WDTwdt_Init();}void Set_DCO(unsigned long freq){unsigned int clkCnt;unsigned int numDcoClks;unsigned int prevCnt = 0;// ACLK = LFXT1CLK/8 = 4096 HzBCSCTL1 |= DIV A_3;numDcoClks = freq/4096;TACCTL2 = CM_1 + CCIS_1 + CAP; TACTL = TASSEL_2 + MC_2 + TACLR; while(1){while( !(TACCTL2 & CCIFG) ){}TACCTL2 &= ~CCIFG;clkCnt = TACCR2 - prevCnt;prevCnt = TACCR2;if( numDcoClks == clkCnt ){break;}else if( clkCnt > numDcoClks ){DCOCTL--;if( DCOCTL == 0xFF ){if( BCSCTL1 & 0x07 ){BCSCTL1--;}else{break;}}}else{DCOCTL++;if( DCOCTL == 0x00 ){if( (BCSCTL1 & 0x07) != 0x07 ){BCSCTL1++;}else{break;}}}}// ACLK = LFXT1CLK/1 = 32768 HzBCSCTL1 &= ~DIV A_3;TACCTL2 = 0;TACTL = 0;}void wdt_Init(void){// 设置时钟源为ACLK,1秒内产生512此WDTCTL = WDTPW + WDTTMSEL + WDTCNTCL + WDTSSEL + WDTIS0 + WDTIS1; }void uart0_Init(void){//将寄存器的内容清零U0CTL = 0X00;//数据位为8bitU0CTL += CHAR;U0TCTL = 0X00;//波特率发生器选择ACLKU0TCTL += SSEL0;//波特率为9600UBR0_0 = 0X03;UBR1_0 = 0X00;UMCTL_0 = 0x4A;//使能UART0的TXD和RXDME1 |= UTXE0 + URXE0;//使能UART0的RX中断IE1 |= URXIE0;//使能UART0的TX中断IE1 |= UTXIE0;//设置P3.4为UART0的TXDP3SEL |= BIT4;//设置P3.5为UART0的RXDP3SEL |= BIT5;//P3.4为输出管脚P3DIR |= BIT4;}void timerA_Init(void){TACCR0 = rate;TACCTL0 = CCIE;TACTL = TASSEL_2 + MC_1 + TACLR;}interrupt [TIMERA0_VECTOR] void TimerA_ISR(void) {unsigned char index;unsigned char p2 = 0;unsigned char p3 = 0;// 判断步进速率是否需要改变if( change_rate_flag ){TACCR0 = rate;change_rate_flag = 0;}// 判断状态switch( (state & 0x3) ){case 0x00: // 整步、逆时钟方向index = stepIndex & 0x03;p2 |= fullStepA[index];p3 |= fullStepB[index];P2OUT = p2;P3OUT = p3;++stepIndex;break;case 0x01: // 整步、顺时钟方向index = stepIndex & 0x03;p3 |= fullStepA[index];p2 |= fullStepB[index];P3OUT = p3;P2OUT = p2;++stepIndex;break;case 0x02: // 半步、逆时钟方向index = stepIndex & 0x07;p2 |= HalfStepA[index];p3 |= CcwHalfStepB[index];P2OUT = p2;P3OUT = p3;++stepIndex;break;case 0x03: // 半步、顺时钟方向index = stepIndex & 0x07;p3 |= CwHalfStepB[index];p2 |= HalfStepA[index];P3OUT = p3;P2OUT = p2;++stepIndex;break;default: break;}// 如果单步状态下,禁止定时器中断if( state & MOTION_MASK ){TACCTL0 &= ~CCIE;}}////////////////////////////////////////// 处理来自串口0 的接收中断interrupt [UART0RX_VECTOR] void UART0_RX_ISR(void) {//接收来自的数据UART0_RX_BUF[nRX0_Len_temp] = RXBUF0;nRX0_Len_temp += 1;if(nRX0_Len_temp >= 2)if(UART0_RX_BUF[nRX0_Len_temp - 2] == '\r' && UART0_RX_BUF[nRX0_Len_temp - 1] == '\n') {// 过滤掉回车换行(\r\n)if(nRX0_Len_temp == 2){nRX0_Len_temp = 0;}else if(nRX0_Len_temp > 2){nRX0_Len = nRX0_Len_temp;nRev_UART0 = 1;nRX0_Len_temp = 0;}}}////////////////////////////////////////// 处理来自串口0 的发送中断interrupt [UART0TX_VECTOR] void UART0_TX_ISR(void) {if(nTX0_Len != 0){// 表示缓冲区里的数据没有发送完nTX0_Flag = 0;TXBUF0 = UART0_TX_BUF[nSend_TX0];nSend_TX0 += 1;if(nSend_TX0 >= nTX0_Len){nSend_TX0 = 0;nTX0_Len = 0;nTX0_Flag = 1;}}}interrupt [WDT_VECTOR] void WDT_ISR(void){unsigned char sw_state;static unsigned char one_sec_flag = 0;// 获得P1口的输入sw_state = ~P1IN & 0x0f;// 判断是否有键按下if( sw_state == 0x00 ){// 禁止看门狗中断IE1 &= ~WDTIE;// 判断是否S2的激活状态小于1秒if( !one_sec_flag && (SW[1] >= DEBOUNCE_CNT) ){toggle_motion();}// 复位状态计数器SW[0] = 0;SW[1] = 0;SW[2] = 0;SW[3] = 0;// 复位标志one_sec_flag = 0;// 使能P1口的中断功能P1IFG = 0x00;P1IE = 0x0f;}else{// 检查是否是S1状态if( sw_state & 0x01 ){if( SW[0] < ONE_SEC_CNT ){// 增加状态计数器++SW[0];}if( SW[0] == DEBOUNCE_CNT ){toggle_direction();}}else{SW[0] = 0;}// 检查是否是S2状态if( sw_state & 0x02 ){if( SW[1] < ONE_SEC_CNT ){// 增加状态计数器++SW[1];}if( SW[1] == ONE_SEC_CNT )toggle_stepping_mode();one_sec_flag = 1;SW[1] = 0;}}else{// 判断是否S2的激活状态小于1秒if( !one_sec_flag && (SW[1] >= DEBOUNCE_CNT) ) {toggle_motion();}one_sec_flag = 0;SW[1] = 0;}// 检查是否是S3状态if( sw_state & 0x04 ){// 检查是否是连续模式if( (state & MOTION_MASK) == 0 ){if( SW[2] < ONE_SEC_CNT ){// 增加状态计数器++SW[2];}if( SW[2] == DEBOUNCE_CNT ){increase_stepping_rate();}}else // 单步模式{// 增加状态计数器++SW[2];if( (SW[2] % DEBOUNCE_CNT) == 0 ){increase_stepping_rate();}}else{SW[2] = 0;}// 检查是否是S4状态if( sw_state & 0x08 ){if( SW[3] < ONE_SEC_CNT ){// 增加状态计数器++SW[3];}if( SW[3] == DEBOUNCE_CNT ){decrease_stepping_rate();}}else{SW[3] = 0;}}}interrupt [PORT1_VECTOR] void PORT1_ISR(void) {// 禁止端口1的中断P1IE = 0x00;// 清除端口1的中断标志P1IFG = 0x00;// 使能看门狗中断IE1 |= WDTIE;}void increase_stepping_rate(void){unsigned int new_rate;// 检查是否是连续模式if( (state & MOTION_MASK) == 0 )new_rate = rate >> 1;if( new_rate >= max_rate ){rate = new_rate;change_rate_flag = 1;}}//使能定时器A的中断TACCTL0 |= CCIE;}void decrease_stepping_rate(void){// 检查是否是连续模式if( (state & MOTION_MASK) == 0 ){if( rate <= (min_rate >> 1) ){rate <<= 1;change_rate_flag = 1;}}// 使能定时器A的中断TACCTL0 |= CCIE;}void toggle_stepping_mode(void){// 切换步进模式state ^= STEP_MASK;// 检查是否是半步模式if( state & STEP_MASK ){// 从整步模式切换到半步模式// 定时器的频率加倍rate = (rate >> 1);change_rate_flag = 1;max_rate = (MAX_RA TE >> 1);min_rate = (MIN_RATE >> 1);}else // 整步模式// 从半步模式切换到整步模式// 定时器的频率减半rate = (rate << 1);change_rate_flag = 1;max_rate = MAX_RATE;min_rate = MIN_RA TE;}}void toggle_motion(void){state ^= MOTION_MASK;// 检查是否是连续步进模式if( (state & MOTION_MASK) == 0 ){// 使能定时器中断TACCTL0 |= CCIE;}}void toggle_direction(void){state ^= DIR_MASK;}。

C语言测控系统程序设计-步进电机实验报告

C语言测控系统程序设计-步进电机实验报告

C语言测控系统程序设计步进电机控制实验报告实验的目的:1.掌握计算机并行接口的工作原理与使用方法。

2.了解步近电机的工作原理与步进电机驱动器的使用。

3.学习控制步进电机位置、速度的实时软件设计。

实验要求:1.步进电机向某一方向转4周,然后再向另一方向转2周。

注意观察是否回到原来的起始位置(旋转结束后旋钮的指向是否停在原来位置)。

2.提高步进电机转速,旋转5周。

注意观察是否出现失步现象估计步进电机的带载启动频率。

*3.编写“升速-恒速-减速”控制程序。

起始频率应低于步进电机的带载启动频,恒速运行时的频率应高于步进电机的带载启动频。

整个运行过程应是整圈数,注意观察是否有振荡和丢步现象。

程序清单和注释:实验要求一的程序:#include <dos.h>#include <stdio.h>void delay(unsigned int m){unsigned int i,j,z;for(i=0;i<10000;i++)for(j=0;j<10;j++)for(z=0;z<m;z++);}void plus(int m){outportb(0x378,0x01); delay(m);outportb(0x378,0x00); delay(m);}void minus(int m){outportb(0x378,0x02); delay(m);outportb(0x378,0x03); delay(m);}void main(){long n;for(n=0;n<6400;n++) {plus(20);}for(n=0;n<3200;n++) {minus(20);}}实验要求二的程序:void main(){long n;for(n=0;n<8000;n++){plus(10);}}实验要求三的程序:void main(){long n;int m=25;for(n=0;n<4800;n++){plus(m);if(n%480==0)m=m-2;}for(n=0;n<3200;n++){plus(m);}for(n=0;n<4800;n++){m=m+2;if(n%480==0)m=m+2; }}。

我的51单片机之 步进电机 的 C语言与汇编的编程

我的51单片机之 步进电机 的 C语言与汇编的编程
A1=1; B1=C1=D1=0; delay(); A1=B1=1; C1=D1=0; delay(); B1=1; A1=C1=D1=0; delay(); B1=C1=1; A1=D1=0; delay(); C1=1; A1=B1=D1=0; delay(); C1=D1=1; A1=B1=0; delay(); D1=1; A1=B1=C1=0; delay(); D1=A1=1; B1=C1=0; delay();
ORG 0000H AJMP MAIN ORG 0030H
ForKey EQU P3.2; BackKey EQU P3.3;
A1 EQU P2.0; B1 EQU P2.1; C1 EQU P2.2; D1 EQU P2.3;
Speed EQU 40H;
;八拍方式驱动,顺序为 A AB B BC C CD D DA MAIN: START:
步进电机实验
一、功能: 按下 KINT0 和 KINT1 键分别控制步进电机正反转。
二、电路图:
三、C 程序: //*********************************************************************** //按下 KINT0 和 KINT1 键分别控制步进电机的正转和反转,made by luqichao //***********************************************************************
}
void BackRun() {
D1=1; B1=C1=A1=0; delay(); D1=C1=1; A1=B1=0; delay(); C1=1; A1=B1=D1=0; delay(); C1=B1=1; A1=D1=0; delay(); B1=1; A1=C1=D1=0; delay(); B1=A1=1; C1=D1=0; delay(); A1=1; D1=B1=C1=0; delay(); A1=D1=1; B1=C1=0; delay(); }
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档