步进电机控制程序
步进电机的控制程序
mega16的,16和32管脚兼容,只不过flash大小不一样,不过中断向量号也不一样,你看下自己改改。
时钟频率:内部RC 1M 芯片:ULN2003 键值:0 小角度快正转。
1 小角度快倒。
2 大角度快转。
3 大角度快倒。
4 小角度正慢转。
5 小角度倒慢转。
6 大角度正慢转。
7 大角度倒慢转。
********************************************************************/#include<iom16v.h>#include <macros.h>#define uchar unsigned char#define uint unsigned intuchar a=0,b=0;uchar KEY_num=0xe1;unsigned int m=9000;const uchar f1[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03}; //正转时序3.75度const uchar f2[]={0x04,0x06,0x02,0x03,0x01,0x09,0x08,0x0c}; //倒转时序3.75度const uchar f3[]={0x01,0x02,0x04,0x08}; //正转时序7.5度const uchar f4[]={0x01,0x08,0x04,0x02}; //倒转时序7.5度void delay(int k) //延时{ int i; for(i=0;i<k;i++); }void delay_10ms(uint data){ uint m=2; while(data) { data--; m=2; while(m)m--; } }void zhengzhuan1(void) //正转3.75度{ unsigned char j; for (j=0;j<8;j++) { PORTC=f1[j]; delay(m); } }void daozhuan1(void) //倒转3.75度{ unsigned char j; for (j=0;j<8;j++) { PORTC=f2[j]; delay(m); } }void zhengzhuan2(void) //正转7.5度{ unsigned char j; for (j=0;j<4;j++) { PORTC=f3[j]; delay(m); } }void daozhuan2(void) //倒转7.5度{ unsigned char j; for (j=0;j<4;j++) { PORTC=f4[j]; delay(m); } }void port_int() //初始化端口{ PORTB = 0xf0; DDRB = 0x0F; DDRC=0xff; PORTC=0x01; }void init_devices(void){ CLI(); //禁止所有中断MCUCR = 0x00; MCUCSR = 0x80;//禁止JTAG GICR = 0x00; port_int();SEI();//开全局中断}//按键键值读取程序//返回按键键值,如果没有按键则返回0.void KYY_read(){ //定义按键值存放内存PORTB=0xf0; //行全部送高电平PORTB=0xf0;if((PINB&0xf0)!=0xf0) //有按键{ delay_10ms(1);//延时消抖if((PINB&0xf0)!=0xf0) //确定有按键按下{ PORTB=0xfe; //扫描第一行PORTB=0xfe;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+1; a=9; }PORTB=0xfd; //扫描第二行PORTB=0xfd;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+2; } PORTB=0xfb; //扫描第三行PORTB=0xfb;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+4; } PORTB=0xf7; //扫描第四行PORTB=0xf7;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+8; } } } //没有按键返回0 }//按键执行程序//送如参数:按键键值KEY_do(uchar data){ uchar KEY_number=data;switch(KEY_number){ case 0xe1:a=0;b=0;daozhuan1();m=5000;break;case 0xd1:a=0;b=1;daozhuan1();m=6000;break;case 0xb1:a=0;b=2;daozhuan1();m=7000;break;case 0x71:a=0;b=3;daozhuan1();m=8000;break;case 0xe2:a=0;b=4;daozhuan2();m=5000;break;case 0xd2:a=0;b=5;daozhuan2();m=6000;break;case 0xb2:a=0;b=6;daozhuan2();m=7000;break;case 0x72:a=0;b=7;daozhuan2();m=8000;break;case 0xe4:a=0;b=8;zhengzhuan1();m=5000;break;case 0xd4:a=0;b=9;zhengzhuan1();m=6000;break;case 0xb4:a=1;b=0;zhengzhuan1();m=7000;break;case 0x74:a=1;b=1;zhengzhuan1();m=8000;break;case 0xe8:a=1;b=2;zhengzhuan2();m=5000;break;case 0xd8:a=1;b=3;zhengzhuan2();m=6000;break;case 0xb8:a=1;b=4;zhengzhuan2();m=7000;break;case 0x78:a=1;b=5;zhengzhuan2();m=8000;break; default:b=0;break;}}void main (void)//主程序{ init_devices();while(1){ KYY_read(); KEY_do(KEY_num); }}#include <reg51.h> //51芯片管脚定义头文件#include <intrins.h> //内部包含延时函数_nop_();#define uchar unsigned char#define uint unsigned intuchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};sbit K1 = P3^4; //正转sbit K2 = P3^5; //反转sbit K3 = P3^6; //停止sbit K4 = P3^7;sbit BEEP = P0^6; //蜂鸣器/********************************************************//*/* 延时t毫秒/* 11.0592MHz时钟,延时约1ms/*/********************************************************/void delay(uint t){uint k;while(t--){for(k=0; k<125; k++){ }}}/**********************************************************/void delayB(uchar x) //x*0.14MS{uchar i;while(x--)for (i=0; i<13; i++){ }}}/**********************************************************/ void beep(){uchar i;for (i=0;i<180;i++){delayB(5);BEEP=!BEEP; //BEEP取反}BEEP=1; //关闭蜂鸣器}/********************************************************/ /*/*步进电机正转/*/********************************************************/ void motor_ffw(){uchar i;uint j;for (j=0; j<12; j++) //转1*n圈{if(K4==0){break;} //退出此循环程序for (i=0; i<8; i++) //一个周期转30度{P0 = FFW[i]; //取数据delay(15); //调节转速}}}/********************************************************/ /*/*步进电机反转/********************************************************/ void motor_rev(){uchar i;uint j;for (j=0; j<12; j++) //转1×n圈{if(K4==0){break;} //退出此循环程序for (i=0; i<8; i++) //一个周期转30度{P0 = REV[i]; //取数据delay(15); //调节转速}}}/********************************************************** 主程序**********************************************************/main(){uchar r,N=5; //N 步进电机运转圈数P2=0xDF;while(1){if(K1==0){beep();for(r=0;r<N;r++){motor_ffw(); //电机正转if(K4==0){beep();break;} //退出此循环程序}}else if(K2==0){beep();for(r=0;r<N;r++){motor_rev(); //电机反转if(K4==0){beep();break;} //退出此循环程序}}elseP0 = 0xf0;}}/********************************************************/ULN2803是8路NPN达林顿连接晶体管系列,特别适用于低逻辑电平数字电路,如:TTL,COMS或PMOS/NMOS,和较高的电压/电流要求之间的接口,广泛应用与计算机、打印机、继电器、灯等类似负载中。
基于stm32控制的步进电机程序代码
基于stm32控制的步进电机程序代码一、前言步进电机是一种常见的电机类型,其控制方式也有很多种。
在本文中,我们将介绍如何使用STM32控制步进电机。
二、硬件准备在开始编写程序之前,我们需要准备以下硬件:1. STM32单片机开发板2. 步进电机驱动板3. 步进电机4. 电源三、步进电机驱动原理步进电机驱动原理是通过不同的脉冲信号来控制步进电机转动。
其中,每个脉冲信号代表着一个步进角度,而不同的脉冲序列则可以实现不同的转速和方向。
四、STM32控制步进电机程序代码以下是基于STM32控制步进电机的程序代码:```c#include "stm32f10x.h"#define CLK_PORT GPIOA#define CLK_PIN GPIO_Pin_0#define DIR_PORT GPIOA#define DIR_PIN GPIO_Pin_1void delay_us(uint16_t us){uint16_t i;while(us--){i = 10;while(i--);}void step(uint8_t dir){if(dir == 0)GPIO_ResetBits(DIR_PORT, DIR_PIN);elseGPIO_SetBits(DIR_PORT, DIR_PIN);for(int i=0; i<200; i++){GPIO_SetBits(CLK_PORT, CLK_PIN);delay_us(2);GPIO_ResetBits(CLK_PORT, CLK_PIN);delay_us(2);}}int main(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = CLK_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(CLK_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = DIR_PIN;GPIO_Init(DIR_PORT, &GPIO_InitStructure);while(1){step(0);delay_us(1000);step(1);delay_us(1000);}}```五、代码解析1. 定义了CLK_PORT和CLK_PIN,用于控制步进电机的脉冲信号。
步进电机控制程序
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//************驱动芯片输入接口*************sbit M2=P1^0;//细分接口sbit M1=P1^1;//细分接口sbit CW=P1^2;//正反转切换sbit PROTECT=P1^3;//保护端输出sbit M0=P1^4; //初始化输出端sbit RESET=P1^5;//复位sbit CLK=P1^6;//脉冲输出端sbit ENABLE=P1^7;//使能端//************驱动芯片输出接口*************sbit zs=P3^2;//正转指示灯sbit fs=P3^3;//反转指示灯sbit bj=P3^4;//报警指示灯//***************24C02定义*************sbit sda=P3^0;//24C02引脚sbit scl=P3^1;//24C02引脚//************显示数据定义*********uint t=0,t2=0;//圈数计数标志位uchar b=0;//圈数判断标志位uint sudu=0; //速度标志位uint quanshu=0;//圈数标志位uint quanshu2=0;//圈数存储标志位uchar m=1; //模式选择标志位uchar temp=1;//按键控制标志位uchar i=1,j=0;//按键控制标志位uchar sudu1[3];//速度显示字符串uchar quanshu1[3];//圈数显示字符串uchar code setSta_[4]={0xfe,0xfd,0xfb,0xf7};//24C02字符串uchar code getSta_[4]={0x70,0xb0,0xd0,0xe0};//24C02字符串//**********液晶控制引脚************sbit RS=P3^7; //液晶控制引脚sbit RW=P3^6; //液晶控制引脚sbit E=P3^5; //液晶控制引脚//***********显示字符串*******************uchar code table0[]="MODE";//开机显示字符串uchar code table1[]="SPEED:";//开机显示字符串uchar code table2[]="COILS:";//开机显示字符串uchar code table3[]="V ery Dinger!";//报警//***********24C02程序*************void delay(){ ;; }void start() //开始信号{sda=1;//sda为高delay();//简单延时scl=1;//scl为高delay();//简单延时sda=0;//sda为低delay();//简单延时}void stop() //停止{sda=0;//sda为低delay();//简单延时scl=1;//scl为高delay();//简单延时sda=1;//sda为高delay();}void respons() //应答{uchar i;scl=1;//scl为高delay();//简单延时while((sda==1)&&(i<250))i++;//(sda==1)和(i<250)只要有一个为真就退出while循环scl=0;//scl为低delay();//简单延时}void init()//初始化{sda=1;//sda为高delay();//简单延时scl=1;//scl为高delay();//简单延时}void write_byte(uchar date)//写数据{uchar i,temp;temp=date;for(i=0;i<8;i++)//依次将8个字节写入{temp=temp<<1;scl=0;delay();sda=CY;delay();scl=1;delay();}scl=0;delay();sda=1;delay();}uchar read_byte()//读数据{uchar i,k;scl=0;delay();sda=1;delay();for(i=0;i<8;i++)//依次读出8个字节{scl=1;delay();k=(k<<1)|sda;scl=0;delay();}return k;}void delay1(uchar x)//延时{uchar a,b;for(a=x;a>0;a--)for(b=100;b>0;b--);}void write_add(uchar address,uchar date)//写{start();//开始信号write_byte(0xa0);//选择器件,并发出写信号respons();//等待应答信号write_byte(address);//发出要写数据的器件地址respons();//等待应答write_byte(date);//发出要写的数据给器件respons();//等待应答stop();//停止信号uchar read_add(uchar address)//读{uchar date;start();//开始信号write_byte(0xa0);//选择器件,并发出写信号respons();//等待应答write_byte(address);//发出要数据的器件地址respons();//等待应答start();//开始信号write_byte(0xa1);//选择器件,并发出读信号respons();//等待应答date=read_byte();//把器件地址中的数据读出后,放在date中stop();//停止信号return date;//返回值}//*********延时函数***************void delay2(int z){int x;uint y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//**********写指令**************void write_com(uchar com){uchar i;RS=0;E=0;P2=com;for(i=0;i<=3;i++){_nop_();}E=1;for(i=0;i<=3;i++){_nop_();}E=0;}//*********写数据*************void write_date(uchar date)uchar i;RS=1;E=0;P2=date;for(i=0;i<=210;i++){_nop_();}E=1;for(i=0;i<=1;i++){_nop_();}E=0;}//***********液晶显示函数************ void init1(){uchar i;E=0;RW=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);for(i=0;i<=3;i++){write_date(table0[i]);}write_com(0x80+0x06);for(i=0;i<=5;i++){write_date(table1[i]);}for(i=0;i<=2;i++){write_date(sudu1[i]+0x30);}write_com(0x80+0x40+0x02);write_date(m+0x30);write_com(0x80+0x40+0x06);for(i=0;i<=5;i++){write_date(table2[i]);}for(i=0;i<=2;i++){write_date(quanshu1[i]+0x30);}}//****************按键程序*************** uchar getkey(){uchar i,j,getSta,keyV al;for(i=0;i<4;i++){P0= setSta_[i];delay2(12);if(P0!=setSta_[i]){if(P0!=setSta_[i]){getSta=P0&0xf0;for(j=0;j<4;j++)if(getSta==getSta_[j]){keyV al=j+i*4;return keyV al;}}}}return 0xff;}//*************按键处理程序************* void chuli(){uchar k;if(temp==1){if(m==1&&getkey()==3){m=2;sudu=100;quanshu=0;b=1;sudu1[0]=sudu/100;sudu1[1]=sudu/10%10;sudu1[2]=sudu%10;quanshu1[0]=quanshu/100;quanshu1[1]=quanshu/10%10;quanshu1[2]=quanshu%10;write_com(0x80+0x40+0x02);write_date(m+0x30);write_com(0x80+0x0C);for(k=0;k<=2;k++)write_date(sudu1[k]+0x30);write_com(0x80+0x40+0x0C);for(k=0;k<=2;k++)write_date(quanshu1[k]+0x30);sudu=100*t2;}//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ if(getkey()==8){j=1;write_com(0x80+0x0C);write_com(0x0f);}if(j==1&&i<=7){if(getkey()==12){if(i==1){write_com(0x80+0x0C);write_date(0+0x30);sudu1[0]=0;}if(i==2){write_com(0x80+0x0D);write_date(0+0x30);sudu1[1]=0;}if(i==3){write_com(0x80+0xE);write_date(0+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=0;}if(i==4){write_date(0+0x30);quanshu1[0]=0;}if(i==5){write_com(0x80+0x40+0x0D);write_date(0+0x30);quanshu1[1]=0;}if(i==6){write_com(0x80+0x40+0x0E);write_date(0+0x30);quanshu1[2]=0;}i=i+1;}if(getkey()==7){if(i==1){write_com(0x80+0x0C);write_date(1+0x30);sudu1[0]=1;}if(i==2){write_com(0x80+0x0D);write_date(1+0x30);sudu1[1]=1;}if(i==3){write_com(0x80+0x0E);write_date(1+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=1;}if(i==4){write_date(1+0x30);quanshu1[0]=1;}if(i==5){write_com(0x80+0x40+0x0D);write_date(1+0x30);quanshu1[1]=1;}if(i==6){write_com(0x80+0x40+0x0E);write_date(1+0x30);quanshu1[2]=1;}i=i+1;}if(getkey()==6){if(i==1){write_com(0x80+0x0C);write_date(2+0x30);sudu1[0]=2;}if(i==2){write_com(0x80+0x0D);write_date(2+0x30);sudu1[1]=2;}if(i==3){write_com(0x80+0x0E);write_date(2+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=2;}if(i==4){write_date(2+0x30);quanshu1[0]=2;}if(i==5){write_com(0x80+0x40+0x0D);write_date(2+0x30);quanshu1[1]=2;}if(i==6){write_com(0x80+0x40+0x0E);write_date(2+0x30);quanshu1[2]=2;}i=i+1;}if(getkey()==5){if(i==1){write_com(0x80+0x0C);write_date(3+0x30);sudu1[0]=3;}if(i==2){write_com(0x80+0x0D);write_date(3+0x30);sudu1[1]=3;}if(i==3){write_com(0x80+0x0E);write_date(3+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=3;}if(i==4){write_date(3+0x30);quanshu1[0]=3;}if(i==5){write_com(0x80+0x40+0x0D);write_date(3+0x30);quanshu1[1]=3;}if(i==6){write_com(0x80+0x40+0x0E);write_date(3+0x30);quanshu1[2]=3;}i=i+1;}if(getkey()==11){if(i==1){write_com(0x80+0x0C);write_date(4+0x30);sudu1[0]=4;}if(i==2){write_com(0x80+0x0D);write_date(4+0x30);sudu1[1]=4;}if(i==3){write_com(0x80+0x0E);write_date(4+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=4;}if(i==4){write_date(4+0x30);quanshu1[0]=4;}if(i==5){write_com(0x80+0x40+0x0D);write_date(4+0x30);quanshu1[1]=4;}if(i==6){write_com(0x80+0x40+0x0E);write_date(4+0x30);quanshu1[2]=4;}i=i+1;}if(getkey()==10){if(i==1){write_com(0x80+0x0C);write_date(5+0x30);sudu1[0]=5;}if(i==2){write_com(0x80+0x0D);write_date(5+0x30);sudu1[1]=5;}if(i==3){write_com(0x80+0x0E);write_date(5+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=5;}if(i==4){write_date(5+0x30);quanshu1[0]=5;}if(i==5){write_com(0x80+0x40+0x0D);write_date(5+0x30);quanshu1[1]=5;}if(i==6){write_com(0x80+0x40+0x0E);write_date(6+0x30);quanshu1[2]=5;}i=i+1;if(getkey()==9){if(i==1){write_com(0x80+0x0C);write_date(6+0x30);sudu1[0]=6;}if(i==2){write_com(0x80+0x0D);write_date(6+0x30);sudu1[1]=6;}if(i==3){write_com(0x80+0x0E);write_date(6+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=6;}if(i==4){write_date(6+0x30);quanshu1[0]=6;}if(i==5){write_com(0x80+0x40+0x0D);write_date(6+0x30);quanshu1[1]=6;}if(i==6){write_com(0x80+0x40+0x0E);write_date(6+0x30);quanshu1[2]=6;}i=i+1;}if(getkey()==15){if(i==1)write_com(0x80+0x0C);write_date(7+0x30);sudu1[0]=7;}if(i==2){write_com(0x80+0x0D);write_date(7+0x30);sudu1[1]=7;}if(i==3){write_com(0x80+0x0E);write_date(7+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=7;}if(i==4){write_date(7+0x30);quanshu1[0]=7;}if(i==5){write_com(0x80+0x40+0x0D);write_date(7+0x30);quanshu1[1]=7;}if(i==6){write_com(0x80+0x40+0x0E);write_date(7+0x30);quanshu1[2]=7;}i=i+1;}if(getkey()==14){if(i==1){write_com(0x80+0x0C);write_date(8+0x30);sudu1[0]=8;if(i==2){write_com(0x80+0x0D);write_date(8+0x30);sudu1[1]=8;}if(i==3){write_com(0x80+0x0E);write_date(8+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=8;}if(i==4){write_date(8+0x30);quanshu1[0]=8;}if(i==5){write_com(0x80+0x40+0x0D);write_date(8+0x30);quanshu1[1]=8;}if(i==6){write_com(0x80+0x40+0x0E);write_date(8+0x30);quanshu1[2]=8;}i=i+1;}if(getkey()==13){if(i==1){write_com(0x80+0x0C);write_date(9+0x30);sudu1[0]=9;}if(i==2){write_com(0x80+0x0D);write_date(9+0x30);sudu1[1]=9;}if(i==3){write_com(0x80+0x0E);write_date(9+0x30);write_com(0x80+0x40+0x0C);sudu1[2]=9;}if(i==4){write_date(9+0x30);quanshu1[0]=9;}if(i==5){write_com(0x80+0x40+0x0D);write_date(9+0x30);quanshu1[1]=9;}if(i==6){write_com(0x80+0x40+0x0E);write_date(9+0x30);quanshu1[2]=9;}i=i+1;}}if(getkey()==4){write_com(0x0C);j=0;i=1;if(m==1){for(k=0;k<=2;k++){delay1(10);write_add(0x01+k,sudu1[k]);delay1(200);}for(k=0;k<=2;k++){delay1(10);write_add(0x04+k,quanshu1[k]);delay1(200);}}sudu=sudu1[0]*100+sudu1[1]*10+sudu1[2]*t2;quanshu=quanshu1[0]*100+quanshu1[1]*10+quanshu1[2];if(quanshu==0) b=1;else b=0;}}//^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^if(j==0&&temp==1&&getkey()==2){TR1=1;ENABLE=1;temp=2;CW=1;zs=0;fs=1;}if(j==0&&temp==1&&getkey()==1){TR1=1;ENABLE=1;temp=2;CW=0;fs=0;zs=1;}if(temp==2&&getkey()==0){TR1=0;ENABLE=0;temp=1;fs=1;zs=1;}}//*************初始化函数****************void chushihua(){uchar k;P0=0xff;P1=0xff;P2=0xff;P3=0xff;M1=0;M2=0;//if(M2==0&&M1==0)t2=1;//if(M2==0&&M1==1)//t2=4;//if(M2==1&&M1==0)//2=8;//if(M2==1&&M1==1)//2=16;sudu=0;quanshu=0;init();//24C02初始化for(k=0;k<=2;k++){delay1(10);sudu1[k]=read_add(0x01+k);delay1(200);}for(k=0;k<=2;k++){delay1(10);quanshu1[k]=read_add(0x04+k);delay1(200);}init1();sudu=sudu1[0]*100+sudu1[1]*10+sudu1[2]*t2;quanshu=quanshu1[0]*100+quanshu1[1]*10+quanshu1[2];quanshu2=quanshu;TMOD=0x11;EA=1;ET1=1;TR1=0;TH1=60000/256;TL1=60000%256;ENABLE=1;RESET=0;if(M0==0)RESET=1;ENABLE=0;}//*********报警函数****************void baojing(){uchar i;TR1=0;bj=0;E=0;RW=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);for(i=0;i<=15;i++)write_date(table3[i]);write_com(0x80+0x40);for(i=0;i<=15;i++)write_date(table3[i]);}//**********中断处理函数***************** void zhongduan(){uchar i;if(t==400*t2){t=0;if(m==1){quanshu--;if(quanshu==0){TR1=0;ENABLE=0;zs=fs=1;temp=1;quanshu=quanshu2;}}if(m==2){if(b==1){quanshu++;if(quanshu==999)quanshu=0;}else{quanshu--;if(quanshu==0){TR1=0;ENABLE=0;temp=1;zs=fs=1;}}}quanshu1[0]=quanshu/100;quanshu1[1]=quanshu/10%10;quanshu1[2]=quanshu%10;write_com(0x80+0x40+0x0C);for(i=0;i<=2;i++)write_date(quanshu1[i]+0x30);}}//***************主函数************** void main(){chushihua();while(1){getkey();if(getkey()!=0xff)chuli();if(PROTECT==0)baojing();}}//***********中断程序**************** void t1(void) interrupt 3 using 1{uint t0;CLK=!CLK;t0=65536-30000/sudu;TH1=t0/256;TL1=t0%256;t++;zhongduan();}。
单片机步进电机控制程序代码
单片机步进电机控制程序代码引言:步进电机是一种常见的电机类型,它具有准确的位置控制和高速运动的特点,在许多应用中被广泛使用。
为了实现步进电机的精确控制,我们需要编写相应的单片机控制程序代码。
本文将介绍一种常见的单片机步进电机控制程序代码,并详细解析其实现原理和使用方法。
一、控制原理:步进电机通过控制电流的方向和大小来控制转子的运动,常见的步进电机控制方式有两相和四相控制。
本文将以四相控制为例进行介绍。
四相控制是指通过控制四个线圈的电流状态来控制步进电机的运动。
具体控制方式有全步进和半步进两种。
全步进模式下,每一步都是四个线圈中的两个同时激活;半步进模式下,每一步都是四个线圈中的一个或两个同时激活。
在本文中,我们将介绍半步进模式的控制程序代码。
二、程序代码:下面是一段常见的单片机步进电机控制程序代码:```c#include <reg51.h>sbit A1 = P1^0;sbit A2 = P1^1;sbit B1 = P1^2;sbit B2 = P1^3;void delay(unsigned int t){unsigned int i, j;for (i = 0; i < t; i++)for (j = 0; j < 120; j++);}void main(){unsigned int i;unsigned char step[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09};while (1){for (i = 0; i < 8; i++){P1 = step[i];delay(1000);}}}```三、代码解析:1. 引用头文件reg51.h,该头文件定义了单片机51的寄存器等相关信息。
2. 定义了四个IO口A1、A2、B1、B2,分别对应步进电机的四个线圈。
3. 定义了一个延时函数delay,用于控制电机转动的速度。
步进电机两轴联动控制程序
/* 数控钻控制系统程序*/ /* 设计:** *//* 2009年5月8号*/ /* 说明:本程序控制数控钻机械部分动作,使xy工作台先按输入孔*/ /* 的坐标找到孔位置,工作台停稳以后,z轴开始慢速进给,到达加工深*/ /* 度以后z轴保持在该深度一段时间,以确保孔的加工完成,然后z轴快*/ /* 速返回到进给前的位置,为下一个孔的加工做好准备。
*/ /*****************************************************************************/ #include <reg52.h>#define uint unsigned int#define uchar unsigned charuchar temp,num,temp1,xoy;uint a,b,c,bai,shi,ge;uint BI_xe,BI_ye,BI_nxy;sbit MotorD1=P0^0;sbit MotorS1=P0^1;sbit MotorD2=P0^2;sbit MotorS2=P0^3;sbit MotorD3=P0^4;sbit MotorS3=P0^5;sbit speaker=P3^2; //I/O口定义unsigned int g_iMotorSpeedNum = 10;void MotorOneStep(uint,uchar,uint);void BeelineInterpolation(uint,uint,uint);void display(uchar,uchar,uchar);void display1(uchar);void MotorZStep(uint);uchar keyscan();uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //共阳极接法段码void DelayMs(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); //延时1微秒函数}void main(){P1=0xef;P0=0xff;bai=0;shi=0;ge=0;while(1){num=keyscan();while(num==16){display(bai,shi,ge);num=keyscan();while((num==1)||(num==13)||(num==14)||(num==2)||(num==3)||(num==4)){switch(num){case 1:{xoy=1;while((num==1)||(num==13)){num=keyscan();display1(xoy);if(num==13){xoy++;num=1;if(xoy==5){xoy=1;}}if(num==9){xoy--;num=1;if(xoy==0){xoy=4;}}}}break; //输入孔坐标所在象限值(1——4)case 2:{a=0;while((num==2)||(num==13)){num=keyscan();bai=a/100;shi=a%100/10;ge=a%10; / /分离出x坐标值的百位十位和个位display(bai,shi,ge);if(num==13){a++;num=2;}if(num==9){a--;num=2;}}}break; //输入孔坐标x坐标值case 3:{b=0;while((num==3)||(num==13)){num=keyscan();bai=b/100;shi=b%100/10;ge=b%10; / /分离出y坐标值的百位十位和个位display(bai,shi,ge);if(num==13){b++;num=3;}if(num==9){b--;num=3;}}}break; //输入孔坐标y坐标值case 4:{c=0;while((num==4)||(num==13)){num=keyscan();bai=c/100;shi=c%100/10;ge=c%10; //分离出进给深度的百位十位和个位display(bai,shi,ge);if(num==13){c++;num=4;}if(num==9){c--;num=4;}}}break; //输输入z轴进给深度}while(num==14) //确定输入值{display(0,0,0);num=keyscan();}}}while(num==15){P0=0xff;BeelineInterpolation(a,b,xoy); //工作台按输入坐标移动MotorD1=1;MotorD2=1;DelayMs(500);DelayMs(500);DelayMs(500);DelayMs(500);MotorZStep(c); //工作移动完毕稳定以后z轴进给if(BI_nxy==0){num=17;}}}}//x、y电机走一步void MotorOneStep(uint MotorNum,uchar MotorDirect,uint MotorSpeed){uint i;if(MotorNum == 0){MotorD1=MotorDirect;for(i=0;i<MotorSpeed;i++){DelayMs(1);}MotorS1 = 0;for(i=0;i<MotorSpeed;i++){DelayMs(1);}MotorS1 = 1;}if(MotorNum == 1){MotorD2=MotorDirect;for(i=0;i<MotorSpeed;i++){DelayMs(1);}MotorS2 = 0;for(i=0;i<MotorSpeed;i++){DelayMs(1);}MotorS2 = 1;}}//直线插补运算void BeelineInterpolation(uint BI_xe,uint BI_ye,uint BI_xoy){uint BI_nxy,BI_zf;int BI_fm;BI_nxy=BI_xe+BI_ye;BI_fm=0;while(BI_nxy) //终点判别{if(BI_fm>0||BI_fm==0){if(BI_xoy==1||BI_xoy==4){BI_zf=1; //x轴电机正方向运动MotorOneStep(0,0,g_iMotorSpeedNum);}else{BI_zf=2; //x轴电机负方向运动MotorOneStep(0,1,g_iMotorSpeedNum);}BI_fm=BI_fm-BI_ye;}else{if(BI_xoy==1||BI_xoy==2){BI_zf=3; //y轴电机正方向运动MotorOneStep(1,0,g_iMotorSpeedNum);}else{BI_zf=4; //y轴电机负方向运动MotorOneStep(1,1,g_iMotorSpeedNum);}BI_fm=BI_fm+BI_xe;}BI_nxy = BI_nxy-1;}}/*显示程序段(三位显示xy坐标以及z轴进给深度)*/void display(uchar bai,uchar shi,uchar ge){P0=table[bai];P1=0xfb;DelayMs(1);P1=0xff;P0=table[shi];P1=0xfd;DelayMs(1);P1=0xff;P0=table[ge];P1=0xfe;DelayMs(1);P1=0xff;}void display1(uchar xiang) //只显示象限值1—4{P0=table[xiang];P1=0xfe;}//z轴进给函数(z轴慢进,加工完成停顿一段时间以后快速返回)void MotorZStep(uint z){uint z1,j;for(z1=z;z1>0;z1--){MotorD3=0;for(j=0;j<g_iMotorSpeedNum;j++){DelayMs(5);}MotorS3 = 0;for(j=0;j<g_iMotorSpeedNum;j++){DelayMs(5);}MotorS3 = 1;}DelayMs(500);DelayMs(500);DelayMs(500);DelayMs(500);for(z1=z;z1>0;z1--){MotorD3=1;for(j=0;j<g_iMotorSpeedNum;j++){DelayMs(3);}MotorS3 = 0;for(j=0;j<g_iMotorSpeedNum;j++){DelayMs(3);}MotorS3 = 1;}}/*键盘扫描程序段*/uchar keyscan() //返回键值{P2=0x7f;temp=P2;temp=temp&0x0f;while(temp!=0x0f){DelayMs(5);temp=P2;temp=temp&0x0f;while(temp!=0x0f){temp=P2;switch(temp){case 0x77:num=1;break;case 0x7b:num=2;break;case 0x7d:num=3;break;case 0x7e:num=4;break;}temp=0x0f; //第一行不加撒手检测}}P2=0xbf;temp=P2;temp=temp&0x0f;while(temp!=0x0f){DelayMs(5);temp=P2;temp=temp&0x0f;while(temp!=0x0f){temp=P2;switch(temp){case 0xb7:num=5;break;case 0xbb:num=6;break;case 0xbd:num=7;break;case 0xbe:num=8;break;}while(temp!=0x0f) //撒手检测,撒手以后才跳出while循环{temp=P2;temp=temp&0x0f;}}}P2=0xdf;temp=P2;temp=temp&0x0f;while(temp!=0x0f){DelayMs(5);temp=P2;temp=temp&0x0f;while(temp!=0x0f){temp=P2;switch(temp){case 0xd7:num=9;break;case 0xdb:num=10;break;case 0xdd:num=11;break;case 0xde:num=12;break;}while(temp!=0x0f){temp=P2;temp=temp&0x0f;}}}P2=0xef;temp=P2;temp=temp&0x0f;while(temp!=0x0f){DelayMs(5);temp=P2;temp=temp&0x0f;while(temp!=0x0f){temp=P2;switch(temp){case 0xe7:num=13;break;case 0xeb:num=14;break;case 0xed:num=15;break;case 0xee:num=16;break;}while(temp!=0x0f){temp=P2;temp=temp&0x0f;}}}return num;}。
两相步进电机 控制程序
两相步进电机控制程序一、初始化设置在控制步进电机之前,需要进行一些初始化设置。
这包括:1. 配置微控制器:选择适合的微控制器,并为其分配必要的资源和接口。
2. 电机参数设定:根据步进电机的规格和性能,设定合适的参数,如步进角度、驱动电流等。
3. 接口配置:配置微控制器与步进电机驱动器之间的接口,包括电源、信号线等。
二、电机驱动脉冲生成为了使步进电机按照设定的方向和步数转动,需要生成合适的驱动脉冲。
这通常通过微控制器实现,具体步骤如下:1. 确定目标位置:根据应用需求,确定步进电机需要转到的目标位置。
2. 计算步数:根据目标位置和步进电机的步进角度,计算出需要转动的步数。
3. 生成驱动脉冲:根据步数和电机的工作模式(单拍、双拍等),生成合适的驱动脉冲序列。
三、电机方向控制步进电机的方向可以通过改变驱动脉冲的顺序来控制。
一般来说,有两种方式来控制电机的方向:1. 通过改变脉冲的顺序:正向或反向发送脉冲序列,可以控制电机向正向或反向转动。
2. 通过使用不同的工作模式:一些步进电机驱动器支持不同的工作模式,如全步、半步、1/4步等。
通过选择不同的工作模式,可以改变电机的转动方向和速度。
四、电机速度调节调节步进电机的速度可以通过改变驱动脉冲的频率来实现。
一般来说,脉冲频率越高,电机转速越快。
同时,也可以通过改变工作模式来调节电机的速度。
五、电机状态监测与保护为了确保步进电机的安全运行,需要实时监测电机的状态,并进行必要的保护措施。
这包括:1. 温度监测:监测电机的温度,防止过热。
2. 电流监测:监测电机的驱动电流,防止过流。
3. 位置监测:通过编码器等传感器监测电机的实际位置,防止位置丢失或错误。
4. 故障诊断:通过分析监测数据,判断电机是否出现故障,并采取相应的处理措施。
六、异常处理与故障诊断为了提高控制程序的鲁棒性,需要设计异常处理与故障诊断机制。
这包括:1. 异常情况检测:通过分析监测数据和运行状态,检测出异常情况。
单片机步进电机控制程序代码
单片机步进电机控制程序代码近年来,随着科技的不断发展,单片机步进电机控制技术在各个领域得到了广泛应用。
单片机步进电机控制程序代码是实现步进电机控制的关键,本文将介绍该代码的基本原理和实现方法。
一、步进电机控制基本原理步进电机是一种将电脉冲信号转换为角位移的电机。
它具有精准定位、高转矩、低噪音等优点,因此被广泛应用于各种设备中。
步进电机控制的基本原理是通过给步进电机提供一系列的脉冲信号,使其按照一定的步进角度旋转。
而单片机则是控制步进电机的核心部件,通过编写控制程序代码来实现对步进电机的控制。
二、单片机步进电机控制程序代码实现方法1. 硬件连接在编写单片机步进电机控制程序代码之前,我们首先需要完成硬件的连接。
一般来说,步进电机的控制需要使用到驱动模块,如ULN2003或者A4988等。
我们需要将单片机的输出引脚与驱动模块的输入引脚相连接,同时将驱动模块的输出引脚与步进电机的控制引脚相连接。
2. 编写控制程序代码接下来,我们可以开始编写单片机步进电机控制程序代码了。
以C 语言为例,下面是一个简单的步进电机正转程序代码示例:```c#include <reg52.h>sbit IN1 = P1^0;sbit IN2 = P1^1;sbit IN3 = P1^2;sbit IN4 = P1^3;void delay(unsigned int t) {unsigned int i, j;for(i = 0; i < t; i++)for(j = 0; j < 120; j++);}void main() {while(1) {IN1 = 1;IN2 = 0;IN3 = 1;IN4 = 0;delay(50);IN1 = 0;IN2 = 1;IN3 = 1;IN4 = 0;delay(50);IN1 = 0;IN2 = 1;IN3 = 0;IN4 = 1;delay(50);IN1 = 1;IN2 = 0;IN3 = 0;IN4 = 1;delay(50);}}```上述代码中,我们通过控制P1口的四个引脚来控制步进电机的旋转方向。
步进电机控制实验实验报告及程序
实验九步进电机控制实验姓名专业通信工程学号成绩一、实验目的1.掌握keil C51软件与proteus软件联合仿真调试的方法;2.掌握步进电机的工作原理及控制方法;3.掌握步进电机控制的不同编程方法;二、实验仪器与设备1.微机1台2.keil C51集成开发环境3.Proteus仿真软件三、实验内容1.用Proteus设计一四相六线步进电机控制电路。
要求利用P1口作步进电机的控制端口,通过达林顿阵列ULN2003A驱动步进电机。
基本参考电路见后面附图。
2.编写程序,实现步进电机的正反转控制。
正反转时间分别持续10S时间,如此循环。
3.设计一可调速步进电机控制电路。
P3.2~P3.5分别接按键k1~k4,其中k1为正反转控制按键,k2为加速按键,k3为减速按键,k4为启动/停止按键,要求速度7档(1~7)可调,加减速各设3档,复位时位于4档,要求每档速度变化明显。
该步进电机控制电路在以上电路的基础上自行修改。
四、实验原理1.步进电机控制原理:1)步进电机是利用电磁铁的作用原理,步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。
每来一个电脉冲,步进电机转动一定角度,带动机械移动一小段距离。
特点A.来一个脉冲,转一个步距角。
B.控制脉冲频率,可控制电机转速。
C.改变脉冲顺序,可改变转动方向。
2)以反应式步进电机为例说明步进电机的结构和工作原理。
三相反应式步进电动机的原理结构图如下,定子内圆周均匀分布着六个磁极,磁极上有励磁绕组,每两个相对的绕组组成一相。
转子有四个齿。
给A相绕组通电时,转子位置如图(a),转子齿偏离定子齿一个角度。
由于励磁磁通力图沿磁阻最小路径通过,因此对转子产生电磁吸力,迫使转子齿转动,当转子转到与定子齿对齐位置时(图b),因转子只受径向力而无切线力,故转矩为零,转子被锁定在这个位置上。
由此可见:错齿是助使步进电机旋转的根本原因。
3)三相反应式步进电动机的控制原理①三相单三拍:A 相→ B 相→ C 相→ A 相②三相六拍:A→AB →B →BC →C → CA→ A③三相双三拍:AB →BC →CA→AB4)步距角计算公式:θ—步距角 Z r—转子齿数 m —每个通电循环周期的拍数2、ULN2003A:七达林顿阵列ULN2003A是集成达林顿管反相驱动电路,内部还集成了一个消线圈反电动势的二极管,可用来驱动电机、继电器等功率器件。
西门子三轴步进电机控制程序
西门子三轴步进电机控制程序以下是一个基本的西门子三轴步进电机控制程序的示例:```Python# 导入所需的模块from pyModbusTCP.client import ModbusClientimport time# 设置Modbus TCP服务器的IP地址和端口号server_ip = '192.168.1.100'server_port = 502# 创建Modbus客户端对象client = ModbusClient(host=server_ip, port=server_port, auto_open=True)# 检查连接状态if not client.is_open():print("无法连接到Modbus TCP服务器")exit()# 定义电机轴的地址axis1_address = 0x0000axis2_address = 0x0001axis3_address = 0x0002# 定义电机的参数speed = 100 # 速度(步数/秒)acceleration = 100 # 加速度(步数/秒^2)deceleration = 100 # 减速度(步数/秒^2)try:# 启动轴client.write_single_register(axis1_address + 1, acceleration) # 设置加速度client.write_single_register(axis1_address + 2, deceleration) # 设置减速度client.write_single_register(axis1_address + 3, speed) # 设置速度client.write_single_register(axis1_address + 4, 1) # 启动轴# 等待轴到达目标位置while client.read_single_register(axis1_address + 5) != 1:time.sleep(0.1) # 等待0.1秒# 停止轴client.write_single_register(axis1_address + 4, 0) # 停止轴# 关闭连接client.close()except Exception as e:print("发生错误:", str(e))client.close()```请注意,这只是一个基本的示例,具体的控制逻辑和参数设置需要根据实际情况进行调整。
步进电机控制程序(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;
PLC如何控制步进电机
PLC如何控制步进电机PLC(可编程逻辑控制器)是一种广泛应用于工业自动化领域的控制设备,通过输入/输出模块对各种机电设备进行控制。
在PLC系统中,步进电机是常见的执行元件之一,它具有准确的位置控制和高的加减速性能。
本文将介绍PLC如何控制步进电机,包括步进电机的驱动方式、PLC的控制原理及步进电机控制的程序设计。
一、步进电机的驱动方式1.串行通信驱动方式:步进电机通过串行通信驱动方式与PLC进行通信和控制。
首先,将PLC与串行通信模块相连,通过串行通信模块与步进电机控制器进行通信。
PLC通过串行通信模块发送指令,步进电机控制器接收指令后控制步进电机运动。
2.并行通信驱动方式:步进电机通过并行通信驱动方式与PLC进行通信和控制。
与串行通信驱动方式类似,首先将PLC与并行通信模块相连,通过并行通信模块与步进电机控制器进行通信。
PLC通过并行通信模块发送指令,步进电机控制器接收指令后控制步进电机运动。
3.脉冲驱动方式:步进电机通过脉冲驱动方式与PLC进行通信和控制。
在脉冲驱动方式中,需要PLC输出脉冲信号控制步进电机。
通常情况下,PLC将脉冲信号传递给步进电机驱动器,在驱动器中产生相应的控制信号,实现对步进电机的控制。
二、PLC的控制原理PLC作为控制器,一般采用扫描运行方式。
其运行原理如下:1.输入信号读取:PLC将外部输入信号输入到输入模块中,采集输入信号,并将其从输入模块传递给中央处理器(CPU)进行处理。
2. 程序执行:CPU根据事先编写好的程序进行处理,包括数据处理、逻辑运算和控制计算等。
PLC程序一般采用ladder diagram(梯形图)进行编写。
3.输出信号控制:根据程序的执行结果,CPU将处理好的数据通过输出模块发送给外部设备,用于控制和操作外部设备。
三、步进电机控制的程序设计步进电机的控制程序主要包括参数设定、模式选择、起停控制、运动控制等部分。
下面以一个简单的例子来说明步进电机控制的程序设计过程:1.参数设定:首先需要设定步进电机的一些参数,如电机型号、步距角度、运动速度等。
STM32控制步进电机程序
STM32控制步进电机程序1.主函数#include\#include\#include\#include\#include\#include\intmain(void){u8t;u32v=1 00;stm32_clock_init(9);//系统时钟设置delay_init(72);//延时初始化uart_init(72,9600);//串口初始化led_init();//初始化与led连接的硬件接口key_init();//初始化与按键连接的硬件接口rcc->apb2enr|=1<<2;//使能porta时钟gpioa->crl&=0x0fffffff;gpioa->crl|=0x30000000;//pa7推挽输出gpioa->odr|=1<<7;//pa7输出高gpioa->crl&=0xff0fffff;gpioa->crl|=0x00300000;//pa5推挽输出gpioa->odr|=1<<5;//pa5输出高led1=1;led0=1;while(1){t=key_scan(0);//得到键值switch(t){casekey0_pres:v=v+10;tim3_int_init(v,7199);//10khz的计数频率tim3->cr1|=0x01;break;casekey1_pres:v=v-10;tim3_int_init(v,7199);//10khz的计数频率tim3->cr1|=0x01;//CX600X定时器3break;casewkup_pres:tim3->cr1&=0xfe;//关定时器3;break;}}}2.led初始化#include\#include\voidled_init(void){rcc->apb2enr|=1<<2;//CX600Xporta时钟rcc->apb2enr|=1<<5;//CX600Xportd时钟gpioa->crh&=0xfffffff0;gpioa->crh|=0x00000003;//pa8推挽输出gpioa->odr|=1<<8;//pa8输出高gpiod->crl&=0xfffff0ff;}gpiod->crl|=0x00000300;//pd.2推挽输入gpiod->odr|=0x0004;//pd.2输入低3.按键初始化#include\#include\voidkey_init(void){rcc->apb2enr|=1<<2;//CX600Xporta时钟rcc->apb2enr|=1<<4;//CX600Xportc时钟jtag_set(swd_enable);//停用jtag,打开swdgpioa->crl&=0xfffffff0;//pa0设置成输出gpioa->crl|=0x00000008;gpioa->crh&=0x0fffffff;//pa15设置成输入gpioa->crh|=0x80000000;gpioa->odr|=1<<15;//pa15上拉,pa0预设下拉gpioc->crl&=0xff0fffff;//pc5设置成输出gpioc->crl|=0x00800000;gpioc->odr|=1<<5;//pc5上拉}u8key_scan(u8mode){staticu8key_up=1;//按键按抬起标志if(mode)key_up=1;//积极支持连按if(key_up&&(key0==0||key1==0||wk_up==1)){delay_ms(10);//回去晃动key_up=0;if(key0==0)returnkey0_pres;elseif(key1==0)returnkey1_pres;elseif(wk_u p==1)returnwkup_pres;}elseif(key0==1&&key1==1&&wk_up==0)key_up=1;return0;//无按键按下}4.定时器初始化#include\#include%u32i=0;//定时器3中断服务程序voidtim3_irqhandler(void){if(tim3->sr&0x0001)//溢出中断{//gpioa->odr^=0x0100;gpioa->odr^=0x0080;led0=!led0;}tim3->sr&=~(1<<0);//去除中断标志位}voidtim3_int_init(u16arr,u16psc){rcc->apb1enr|=1<<1;//tim3时钟使能tim3->arr=arr;//设定计数器自动重装值tim3->psc=psc;//预分频器设置tim3->dier|=1<<0;//允许更新中断//tim3->cr1|=0x01;//使能定时器3my_nvic_init(3,3,tim3_irqn,2);//抢占市场3,子优先级3,组与2}。
FX1S控制步进电机的实例图与程序
FX1S控制步进电机的实例(图与程序)FX1S控制步进电机的实例(图与程序) :·采用绝对位置控制指令(DRVA),大致阐述FX1S控制步进电机的方法。
·FX系列PLC 单元能同时输出两组100KHZ脉冲,是低成本控制伺服与步进电机的较好选择!·PLS+,PLS-为步进驱动器的脉冲信号端子,DIR+,DIR-为步进驱动器的方向信号端子。
·所谓绝对位置控制(DRVA),就是指定要走到距离原点的位置,原点位置数据存放于32位寄存器D8140里。
当机械位于我们设定的原点位置时用程序把D8140的值清零,也就确定了原点的位置。
·实例动作方式:X0闭合动作到A点停止,X1闭合动作到B点停止,接线图与动作位置示例如左图(距离用脉冲数表示)。
·程序如下图:(此程序只为说明用,实用需改善。
)说明:·在原点时将D8140的值清零(本程序中没有做此功能)·32位寄存器D8140是存放Y0的输出脉冲数,正转时增加,反转时减少。
当正转动作到A点时,D8140的值是3000。
此时闭合X1,机械反转动作到B点,也就是-3000的位置。
D8140的值就是-3000。
·当机械从A点向B点动作过程中,X1断开(如在C点断开)则D8140的值就是200,此时再闭合X0,机械正转动作到A点停止。
·当机械停在A点时,再闭合X0,因为机械已经在距离原点3000的位置上,故而机械没有动作!·把程序中的绝对位置指令(DRVA)换成相对位置指令(DRVI):·当机械在B点时(假设此时D8140的值是-3000)闭合X0,则机械正转3000个脉冲停止,也就是停在了原点。
D8140的值为0·当机械在B点时(假设此时D8140的值是-3000)闭合X1,则机械反转3000个脉冲停止,也就是停在了左边距离B点3000的位置(图中未画出),D8140的值为-6000。
步进电机控制源程序
/********************************************//*电子信息工程学院*//* 作者:*//********************************************/#include "Stepper.h"/* 定时器0服务子程序*/void time0() interrupt 1 using 1 // 用定时器0中断来产生CLK时钟{/* 定时10ms,产生20ms周期的时钟,也就是50Hz的时钟*/TH0 = -T/256;TL0 = -T%256;CLK = ~CLK;}/* 键消抖延时函数*/void delay(void){uchar i;for (i=300;i>0;i--);}/* 键扫描函数*/uchar keyscan(void){uchar scancode,tmpcode;P1 = 0xf0;// 发全0行扫描码if ((P1&0xf0)!=0xf0)// 若有键按下{delay();// 延时去抖动if ((P1&0xf0)!=0xf0)// 延时后再判断一次,去除抖动影响{scancode = 0xfe;while((scancode&0x10)!=0)// 逐行扫描{P1 = scancode;// 输出行扫描码if ((P1&0xf0)!=0xf0)// 本行有键按下{tmpcode = (P1&0xf0)|0x0f;/* 返回特征字节码,为1的位即对应于行和列*/return((~scancode)+(~tmpcode));}else scancode = (scancode<<1)|0x01;// 行扫描码左移一位}}}return(0);// 无键按下,返回值为0}/* 主程序*/void main(){uchar key;TMOD = 0x01;// 设置定时器0工作模式EA = 1;ET0 = 1;/* 设置为2相激励*/M1 = 0;M2 = 0;/* 设置为环形转向轨迹*/M4 = 1;M5 = 1;EN = 0;// 切断驱动输出RET = 0;// 归位输入无效CWB = 1;// 初始设置为顺时针方向while(1){key = keyscan();// 调用键盘扫描函数switch(key){case 0x11:// 0行0列,启动键EN = 1;// 打开驱动输出TH0 = -T/256; // 改变T可以改变步进电机转动速度TL0 = -T%256;TR0 = 1;// 定时器0开始计数break;case 0x21:// 0行1列,停止键TR0 = 0;// 定时器0停止计数EN = 0;// 切断驱动输出break;case 0x41:// 0行2列,切换转向按键CWB = ~CWB;break;case 0x81:// 0行3列,归位键RET = 1;delay();RET = 0;break;default:break;}}}。
四相五线步进电机控制程序
#include <reg51.h>sbit LA=P2^0; //定义两相,选择P2口的低四位输出//LA为A,LB为B,LC为C,LD为Dsbit LB=P2^1;sbit LC=P2^2;sbit LD=P2^3;sbit key1 = P3^7; //定义按键1sbit key2 = P3^6; //定义按键2sbit key3 = P3^5; //定义按键3sbit key4 = P3^4; //定义按键4sbit key5 = P3^3; //定义按键5sbit key6 = P3^2; //定义按键6/********函数声明*************************************************************/ void right(unsigned int Speed,unsigned int road); //正转void left(unsigned int Speed,unsigned int road); //反转void mDelay(unsigned int DelayTime); //延时函数/********变量定义*************************************************************/ int MotorStep=0; //步进索引/***********主函数开始********************************************************/void main(){P2&=0XF0; //因ULN2003A直接驱动,初始时为低电平,这里一定不能少了while(1){ //循环if(key1==0) //1键按下正转right(20,32); //两个参数代表转速和步进量,以20的速度进32步if(key2==0) //2键按下反转left(20,32);if(key3==0) //3键接下正转right(10,32); //两个参数代表转速和步进量,以10的速度进32步if(key4==0) //4键接下反转left(10,32);}}/***********正转,两个参数代表转速和步进量*************************************/void right(unsigned int Speed,unsigned int road){//步进节拍:A-B-C-Dwhile(road){switch(MotorStep){case 0:LB=0;LC=0;LD=0;LA=1; //AMotorStep=1;break;case 1:LA=0;LC=0;LD=0;LB=1; //BMotorStep=2;break;case 2:LA=0;LB=0;LD=0;LC=1; //CMotorStep=3;break;case 3:LA=0;LB=0;LC=0;LD=1; //DMotorStep=0;break;}mDelay(Speed); //这里的延时即控制转速road--; //完成一步}P2&=0XF0; //将四个脚复位0,停止}/***********反转,两个参数代表转速和步进量*************************************/ void left(unsigned int Speed,unsigned int road){//步进节拍:D-C-B-Awhile(road){switch(MotorStep){case 3:LA=0;LC=0;LD=0;LB=1; //BMotorStep=2;break;case 2:LB=0;LC=0;LD=0;LA=1; //AMotorStep=1;break;case 1:LA=0;LB=0;LC=0;LD=1; //DMotorStep=0;break;case 0:LA=0;LB=0;LD=0;LC=1; //CMotorStep=3;break;}mDelay(Speed); //这里的延时即控制转速road--; //完成一步}P2&=0XF0; //将四个脚复位0}/***********延时函数*******************************************************/ void mDelay(unsigned int DelayTime){unsigned char j=0;while(DelayTime--){for(j=0;j<100;j++){}}}。
程序(51控制步进电机,执行不同角度的转动)
void counter0(void) interrupt 0 using 1
{
EX0=0;
cont++;
EX0=1;
}
/*******************************************************************************
*实验名:步进电机角度控制
*实验说明:通过不同的按键控制步进电机角度分别是5度10度30度45度
*注意:
************************************************************************r*******/
#include <reg52.h>
/*******************************************************************************
*游承RGC
*
--------------------------------------------------------------------------------
//--定义一个全局变量--//
unsigned char cont=0;
unsigned int timer1=0;
void Delay10ms(unsigned int c); //延时10ms
void Time1Config();
/*******************************************************************************
单片机步进电机控制程序代码
单片机步进电机控制程序代码在现代工业控制系统中,步进电机被广泛应用于各种场合,如数控机床、医疗设备、自动化生产线等。
而单片机作为一种集成电路,具有高度集成、体积小、功耗低等特点,成为控制步进电机的理想选择。
本文将介绍单片机步进电机控制程序代码的编写方法及其实现原理。
一、步进电机控制程序代码的编写方法步进电机的控制可以通过单片机来实现,而单片机控制步进电机的关键在于编写合适的控制程序代码。
下面将介绍一种常用的步进电机控制程序代码编写方法。
1. 确定引脚连接:首先,需要确定步进电机的引脚连接方式。
步进电机一般有两种连接方式,即单相连接和双相连接。
在单相连接方式中,步进电机只需两个控制引脚,而在双相连接方式中,步进电机需要四个控制引脚。
根据步进电机的具体型号和使用要求,选择合适的引脚连接方式。
2. 编写控制程序:根据步进电机的引脚连接方式,编写相应的控制程序。
以双相连接方式为例,步进电机的控制程序代码如下:```#include <reg52.h>sbit IN1 = P1^0; // 步进电机引脚1sbit IN2 = P1^1; // 步进电机引脚2sbit IN3 = P1^2; // 步进电机引脚3sbit IN4 = P1^3; // 步进电机引脚4void delay(unsigned int time){unsigned int i, j;for (i = time; i > 0; i--)for (j = 110; j > 0; j--);}void main(){while (1){IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 0; // 步进电机正转 delay(1000);IN1 = 0; IN2 = 1; IN3 = 0; IN4 = 0;delay(1000);IN1 = 0; IN2 = 0; IN3 = 1; IN4 = 0;delay(1000);IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 1;delay(1000);}}```上述代码中,通过控制引脚的电平状态,实现步进电机的正转。