单片机
返回首页

N76E003控制双路步进电机(开环)

2022-06-24 来源:eefocus

0、引言

实验材料

image.png

1、程序逻辑

1.1、程序采用PWM中断,实现对PWM脉冲计数,由此实现开环控制步进电机,设定为下降沿触发。

1.2、步进电机驱动器提供EN、Pulse、DIR、COM四个接口,其中COM接单片机的VCC,EN用于控制电机使能,DIR用于电机换向,Pulse为输入脉冲。

1.3、根据上述说明,单片机PWM持续产生脉冲,通过EN控制步进电机是否使能

1.4、流程图如下


在这里插入图片描述

2、程序代码

#include 'N76E003.h'

#include 'Common.h'

#include 'Delay.h'

#include 'SFR_Macro.h'

#include 'Function_define.h'


#define uint unsigned int

#define uchar unsigned char 


uint time;//频率

uint temp[10];//存放输入捕获值

int i=0;


uint PWM_Value;//需要改变的占空比值


uchar UART0_RX_BUF[11];//串口0,串口1数据接收缓冲区

uchar UART0_RX_STA=0;//串口0,串口1接收计数器

uchar uFlag=0;//串口中断指令接收完成标志




char start=0;


//用于数据记录

uint ct1,ct2;

//脉冲期望值(0-6700)

uint evt1,evt2;

//状态机:

//0——初始状态

//1——串口

//2——运行到了指定距离。

uchar Flag1=0,Flag2=0;


//PWM中断计数器控制器

//0:关闭

//1:开启

char CEP1=0,CEP2=0;



//用于回到零点

sbit KEY1=P0^4;

sbit KEY2=P1^4;

//使能

sbit EN1=P1^0;

sbit EN2=P1^1;

//换向

sbit DIR1=P1^2;

sbit DIR2=P1^3;

//指示灯

sbit LED1=P0^5;

sbit LED2=P3^0;




void delay1(uint ms);

void PWM_DEAD_TIME_VALUE(UINT16 DeadTimeData);



/*

程序说明:

1、PWM一直保持输出,使用EN来控制步进电机输出

2、使用PWM中断,实现脉冲计数,设置为全局变量

3、串口接收数据,数据包见下'A1234B1234E'其中A为第一个步进电机、B为第二个,1234为期望脉冲数

4、程序流程:收到指令——》步进电机运动——》到指定位置,延时1S,返回0点——》等待下一次



Tips:程序仍存在问题:

1、在运行过程中不能二次接收数据(应对串口中断关闭,回到0点后再开启)

*/



void main (void) 

{

//———————管脚配置 ——————————

Set_All_GPIO_Quasi_Mode;//所有IO设置为双向模式

P03_PushPull_Mode;

// P30_Input_Mode;//key1

EN1=0;EN2=0;//关闭步进电机

DIR1=0;DIR2=0;//向前方向

LED1=1;LED2=1;

Flag1=0;

Flag2=0;

CEP1=0;CEP2=0;

//----------串口0配置----------------

InitialUART0_Timer1(9600);

//在不配置SM1,SM2寄存器的情况下,默认工作在模式0(半双工)

RI=0;

TI=0;

Timer0_Delay1ms(100);

//—————1KHz的50%占空比——————————

PWM5_P03_OUTPUT_ENABLE;//使能PWM5,通过P03引脚输出

clr_PWMTYP;//边沿对齐模式

clr_PWMMOD0;//设置为独立输出模式

clr_PWMMOD1;

PWM_CLOCK_DIV_8;

PWMPH = 0x07;

PWMPL = 0xcf;

    set_SFRPAGE;//PWM4 and PWM5 duty seting is in SFP page 1

    PWM5H = 0x03;             

    PWM5L = 0xe8;

    clr_SFRPAGE;                                            

    set_LOAD;//载入周期和占空比

    set_PWMRUN;//开始输出PWM


//———————PWM配置————————————

EA=1;

set_EPWM;//使能pwm中断

// clr_EPWM;

PWM_INT_PWM5;//设定中断源为PWM5

PWM_FALLING_INT;//下降沿触发

Timer3_Delay100ms(1);

ES=1;//串口中断使能

//------------中断优先级---------------------

set_PSH;//设置串口0最高优先级:1

set_PS;//设置串口0最高优先级:1

clr_PPWMH;//设置PWM中断优先级低位:0

clr_PPWM;//设置PWM中断优先级低位:0



//---------输入你自己的代码-------------------

while(1)

{

//哪个电机先到,哪个先关闭使能

if(Flag2==2&&Flag1!=2)EN2=0;

if(Flag1==2&&Flag2!=2)EN1=0;

//两个电机均运行到指定位置,准备返航

if(!KEY1&&(Flag2==2&&Flag1==2))

{

LED2=0;//返航指示灯

CEP1=1;//重启PWM计数器

CEP2=1;//重启PWM计数器

EN1=1;//开始返航

EN2=1;//开始返航

Flag1=3;Flag2=3;

}

//初始化保持步进电机停车

if(Flag1==0){EN1=0;}

if(Flag2==0){EN2=0;}

if(!Flag1&&!Flag2)

{

LED1=1;

LED2=1;

}

//该状态为接收到指令,前向运动

if(Flag1==1&&Flag2==1)

{

LED1=0;//正向指示灯

EN1=1;//使能步进电机

EN2=1;

}

}

}





/****************串口0中断服务程序*****************/

void Uart0_test() interrupt 4

{

if(RI)//串口0接收中断标志(有数据时,硬件置1)

{

RI=0;//软件置0

TI=0;//同时打开,需要对TI也置低

UART0_RX_BUF[UART0_RX_STA]=SBUF;//从SBUF缓存中读取接收到的数据

UART0_RX_STA++ ;                //计算接收长度

//进行数据校验,通过RX_BUF&RX_STA

if(UART0_RX_STA==11&&UART0_RX_BUF[10]==0X45)

{

if(UART0_RX_BUF[0]==0x41&&UART0_RX_BUF[5]==0x42)

{

//收到期望值

evt1=(UART0_RX_BUF[1]-48)*1000+(UART0_RX_BUF[2]-48)*100+(UART0_RX_BUF[3]-48)*10+(UART0_RX_BUF[4]-48);

evt2=(UART0_RX_BUF[6]-48)*1000+(UART0_RX_BUF[7]-48)*100+(UART0_RX_BUF[8]-48)*10+(UART0_RX_BUF[9]-48);

Send_Data_To_UART0(0x4f);

Send_Data_To_UART0(0x4b);

if(evt1>6700)evt1=6700;

if(evt2>6700)evt2=6700;


TI=0;

UART0_RX_STA=0;

Flag1=1;

Flag2=1;

ct1=0;

ct2=0;

DIR1=0;

DIR2=0;


CEP1=1;//开启计数器使能

CEP2=1;

EN1=1;//使能步进电机

EN2=1;


}

}

}

}



/****************PWM中断服务程序*****************/

void PWMISR() interrupt 13

{

if(PWMF)//检测到中断标志位

{

if(CEP1)

{

ct1++;

//检测是否达到指定位置

if(ct1>=evt1&&Flag1==1)//达到设定值,清空ct1,EN1=0;,正向移动

{

ct1=0;

EN1=0;//停止步进电机转动。

DIR1=1;//准备返航

Flag1=2;

CEP1=0;

}

//-----------------1号返航-------------------

if(ct1>=evt1&&Flag1==3)//回到零点

{

ct1=0;

EN1=0;//停止步进电机转动。

Flag1=0;

CEP1=0;

}

}

if(CEP2)

{

ct2++;

//检测是否达到指定位置

if(ct2>=evt2&&Flag2==1)

{

ct2=0;

EN2=0;//停止步进电机转动。

DIR2=1;//准备返航

Flag2=2;

CEP2=0;

}

//-----------------2号返航-------------------

if(ct2>=evt2&&Flag2==3)//回到零点

{

ct2=0;

EN2=0;//停止步进电机转动。

Flag2=0;

CEP2=0;

}

}

clr_PWMF;//清楚PWM中断标志位Timer0_Delay1ms(1)

}

}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章