前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单片机控制步进电机-AVR详细程序

单片机控制步进电机-AVR详细程序

作者头像
全栈程序员站长
发布2022-08-23 14:10:47
6150
发布2022-08-23 14:10:47
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

单片机控制步进电机-单片机程序(avr)

硬件线路连接图见上一篇文章:https://blog.csdn.net/LuDanTongXue/article/details/87869557

软件: ICCV7 FOR AVR-写程序 Progisp-烧程序 速度S曲线生成器(后续后单独讲解)-生成S曲线数组代码 硬件: Atmega16 ASP下载线 杜邦线

控制原理: 利用单片机定时器控制IO口高低电平产生脉冲,通过定时器控制每个脉冲的时间,以及脉冲的个数,从而控制步进电机速度以及转动角度,实现步进电机开环控制能力。步进电机常用的运动控制过程是:【静止】-【S曲线加速】-【匀速】-【S曲线减速】-【停止】,优点是速度平缓上升与下降,能够输出较大的扭矩,不容易失步、堵转。 以下会以【静止】-【正转180°】-【反转180°】-【停止】该运动控制过程进行演示,其中加减速过程均采用S曲线控制。 速度曲线具体控制过程是: 第一段S曲线加速30°:1转/秒启动,5转/秒结束 第二段匀速运动120°:5转/秒匀速 第三段S曲线减速30°:5转/秒启动,0.5转/秒结束 第四段S曲线反转加速30°:0.5转/秒启动,5转/秒结束 第五段匀速反转运动120°:5转/秒匀速 第六段S曲线反转减速30°:5转/秒启动,1转/秒结束

V-T图:

S-T图:

代码如下:(适用于Atmega16芯片,如用51芯片需要稍作改动)

代码语言:javascript
复制
//头文件
#include<iom16v.h>
#include<macros.h>//SEI()函数_NOP()BIT();
#define uint unsigned int
#define uchar unsigned char

//步进电机接口定义
#define ENA0 (PORTA &=~BIT(0))//电机由脉冲控制
#define ENA1 (PORTA |=BIT(0))//电机掉电、自由状态
#define DIR0 (PORTA &=~BIT(1))//电机正方向转动
#define DIR1 (PORTA |=BIT(1))//电机反方向转动
#define PUL0 (PORTA &=~BIT(2))//低电位
#define PUL1 (PORTA |=BIT(2))//高电位


unsigned int n0;//脉冲计数,用来控制电机转角
uchar duan;//步进电机曲线分段控制参数
uchar kaiguanflag;//该参数为0时,步进电机的启动开关才有效


//定义MEGA16接口输入输出
void port_init(void)
{
 PORTA = 0xFF; //BIT(4)为电机启动开关  BIT(5)电机释放开关
 DDRA  = 0x0F; 
 PORTB = 0xFF; 
 DDRB  = 0xFF; 
 PORTC = 0xFF; 
 DDRC  = 0xFF; 
 PORTD = 0xFF; 
 DDRD  = 0x02;
}


//ms延时函数
void delay_1ms(void) 
{  
unsigned int i;  
for(i=1;i<(unsigned int)(11.059*143-2);i++);//定义晶振频率
}  
void delay(unsigned int n)//延时微妙级 
{  
unsigned int i; 
for(i=0;i<n;i++) 
delay_1ms(); 
}


//主程序
//曲线数组的生成后续文章会单独分析
//第一段S曲线加速30°:1转/秒启动,5转/秒结束
A[67]={0XE5CF,0XE5EF,0XE614,0XE63E,0XE66E,0XE6A4,0XE6E2,0XE728,0XE777,0XE7D0,0XE832,0XE8A0,0XE919,0XE99E,0XEA2F,0XEACB,0XEB73,0XEC25,0XECE0,0XEDA3,0XEE6C,0XEF38,0XF006,0XF0D4,0XF19E,0XF264,0XF323,0XF3D9,0XF485,0XF526,0XF5BC,0XF646,0XF6C4,0XF737,0XF79E,0XF7FB,0XF84E,0XF898,0XF8D9,0XF913,0XF946,0XF972,0XF999,0XF9BB,0XF9D9,0XF9F3,0XFA09,0XFA1C,0XFA2D,0XFA3C,0XFA49,0XFA54,0XFA5D,0XFA65,0XFA6C,0XFA72,0XFA78,0XFA7C,0XFA80,0XFA83,0XFA86,0XFA89,0XFA8B,0XFA8D,0XFA8F,0XFA90,0XFA91};

//第三段S曲线减速30°:5转/秒启动,0.5转/秒结束
B[67]={0XFA8F,0XFA8D,0XFA8B,0XFA89,0XFA87,0XFA84,0XFA81,0XFA7D,0XFA79,0XFA73,0XFA6D,0XFA67,0XFA5F,0XFA55,0XFA4A,0XFA3E,0XFA2F,0XFA1F,0XFA0B,0XF9F5,0XF9DB,0XF9BD,0XF99A,0XF972,0XF944,0XF90F,0XF8D2,0XF88C,0XF83C,0XF7E0,0XF777,0XF700,0XF678,0XF5DE,0XF531,0XF46F,0XF396,0XF2A4,0XF199,0XF073,0XEF33,0XEDD9,0XEC65,0XEAD9,0XE939,0XE786,0XE5C4,0XE3FA,0XE22A,0XE05B,0XDE91,0XDCD2,0XDB21,0XD983,0XD7FB,0XD68B,0XD534,0XD3F8,0XD2D6,0XD1CF,0XD0E1,0XD00B,0XCF4C,0XCEA2,0XCE0B,0XCD86,0XCD10};

//第四段S曲线反转加速30°:0.5转/秒启动,5转/秒结束
C[67]={0XCD86,0XCE0B,0XCEA2,0XCF4C,0XD00B,0XD0E1,0XD1CF,0XD2D6,0XD3F8,0XD534,0XD68B,0XD7FB,0XD983,0XDB21,0XDCD2,0XDE91,0XE05B,0XE22A,0XE3FA,0XE5C4,0XE786,0XE939,0XEAD9,0XEC65,0XEDD9,0XEF33,0XF073,0XF199,0XF2A4,0XF396,0XF46F,0XF531,0XF5DE,0XF678,0XF700,0XF777,0XF7E0,0XF83C,0XF88C,0XF8D2,0XF90F,0XF944,0XF972,0XF99A,0XF9BD,0XF9DB,0XF9F5,0XFA0B,0XFA1F,0XFA2F,0XFA3E,0XFA4A,0XFA55,0XFA5F,0XFA67,0XFA6D,0XFA73,0XFA79,0XFA7D,0XFA81,0XFA84,0XFA87,0XFA89,0XFA8B,0XFA8D,0XFA8F,0XFA90};

//第六段S曲线反转减速30°:5转/秒启动,1转/秒结束
D[67]={0XFA90,0XFA8F,0XFA8D,0XFA8B,0XFA89,0XFA86,0XFA83,0XFA80,0XFA7C,0XFA78,0XFA72,0XFA6C,0XFA65,0XFA5D,0XFA54,0XFA49,0XFA3C,0XFA2D,0XFA1C,0XFA09,0XF9F3,0XF9D9,0XF9BB,0XF999,0XF972,0XF946,0XF913,0XF8D9,0XF898,0XF84E,0XF7FB,0XF79E,0XF737,0XF6C4,0XF646,0XF5BC,0XF526,0XF485,0XF3D9,0XF323,0XF264,0XF19E,0XF0D4,0XF006,0XEF38,0XEE6C,0XEDA3,0XECE0,0XEC25,0XEB73,0XEACB,0XEA2F,0XE99E,0XE919,0XE8A0,0XE832,0XE7D0,0XE777,0XE728,0XE6E2,0XE6A4,0XE66E,0XE63E,0XE614,0XE5EF,0XE5CF,0XE5B3};


void main(void)
{
TCCR1B=0X01;//不分频(定时小于5.9毫秒) 
TCNT1=0XE5F0;//存放初值,根据A[0]值确定
TIMSK|=0x00;//定时器中断关
SREG=0X80;//总中断开
port_init();//IO口初始化
DIR0;//定一个初始转向
ENA1;//上电后步进电机为自由状态
while(1)
{
//本程序将PA4口设置为一个开关,当PA4口与单片机GND连通时,电机开始启动,硬件图里面没有画出该部分
 if((PINA&0x10)==0 & kaiguanflag==0)//启动键
 {
  delay(10);//软件滤波
  if((PINA&0x10)==0 & kaiguanflag==0)
  {
  kaiguanflag=1;//防止在电机转动过程中再进入该部分程序
  n0=0;
  DIR1;//规定转向
  ENA0;//电机处于可操作状态
  TIMSK|=BIT(2);//开16位定时器1中中断,电机启动
  }
 }

//本程序将PA5口设置为一个开关,当PA5口与单片机GND连通时,电机处于掉电自由状态,防止在不用过程中电机一直带电发热,同时可以用手去转动电机,硬件图里面没有画出该部分
 if((PINA&0x20)==0)//切换步进电机可控状态
 {
  delay(10);
  if((PINA&0x20)==0)
  ENA1; 
 }
}
}

#pragma interrupt_handler time1:9//ATMEGA16定时器time1中断
void time1(void)
{
 switch(duan)//控制曲线处于哪个加速段
 {
//已第一段为例解释,后面几段原理一样
case 0: //第一段S曲线加速30°:1转/秒启动,5转/秒结束

  TCNT1=A[n0];//设置定时器初值
  PORTA ^=BIT(2);//PA2口取反,产生高低电平形成脉冲
  if((PINA & BIT(2))==0)//两次中断产生一个脉冲,取其中一次进行脉冲计数
   {
    n0++;
   	  if(n0==67)//判断是否到达指定脉冲数
	  {
		duan++;//到达脉冲个数之后,进入下一段速度
		n0=0;//清零
	  }
   	}break;
   	
case 1: //第二段匀速运动120°:5转/秒匀速
  TCNT1=0XFA99;//匀速5r/s;
  PORTA ^=BIT(2);
  if((PINA & BIT(2))==0)
   {
    n0++;
	if(n0==267)
	{
	 duan++;
	 n0=0;
	}
   }break;
   
case 2: //第三段S曲线减速30°:5转/秒启动,0.5转/秒结束
  TCNT1=B[n0];
  PORTA ^=BIT(2);
  if((PINA & BIT(2))==0)
   {
    n0++;
   	  if(n0==67)
	  {
	    duan++;
	    n0=0;
            DIR0;//开始换向
	  }
   	}break;
   	
case 3: //第四段S曲线反转加速30°:0.5转/秒启动,5转/秒结束
  TCNT1=C[n0];
  PORTA ^=BIT(2);
  if((PINA & BIT(2))==0)
   {
    n0++;
   	  if(n0==67)
	  {
	    duan++;
	    n0=0;
	  }
   	}break;
   	
case 4: //第五段匀速反转运动120°:5转/秒匀速
  TCNT1=0XFA99;//转速5r/s;
  PORTA ^=BIT(2);
  if((PINA & BIT(2))==0)
   {
    n0++;
   	  if(n0==267)
	  {
	    duan++;
	    n0=0;
	  }
   	}break;
case 5: //第六段S曲线反转减速30°:5转/秒启动,1转/秒结束
  TCNT1=D[n0];
  PORTA ^=BIT(2);
  if((PINA & BIT(2))==0)
   {
    n0++;
   	  if(n0==67)
	     {
		      duan=0;
		      kaiguanflag=0;//PA4开关标志清零,等待下一次PA4开关启动
		      TIMSK=0x00;//关闭中断,电机停止
	      }
   	}break;
 default:duan=0;kaiguanflag=0;TIMSK=0x00;break;
  } 
}

演示动画: 将单片机PA4口与GND口连通(时间有限没有接开关),步进电机按照上述设计的曲线进行运动,实现正转180°后反转180°回到原点。 (视频不好传,GIF质量不怎么好,将就看看)。

在这里插入图片描述
在这里插入图片描述

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/138363.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月6,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档