打印
[应用方案]

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

[复制链接]
2904|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
0、引言

实验材料



使用特权

评论回复
沙发
木木guainv|  楼主 | 2021-7-1 15:23 | 只看该作者
1、程序逻辑

1.1、程序采用PWM中断,实现对PWM脉冲计数,由此实现开环控制步进电机,设定为下降沿触发。
1.2、步进电机驱动器提供EN、Pulse、DIR、COM四个接口,其中COM接单片机的VCC,EN用于控制电机使能,DIR用于电机换向,Pulse为输入脉冲。
1.3、根据上述说明,单片机PWM持续产生脉冲,通过EN控制步进电机是否使能
1.4、流程图如下



使用特权

评论回复
板凳
木木guainv|  楼主 | 2021-7-1 15:24 | 只看该作者
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点后再开启)
*/


使用特权

评论回复
地板
木木guainv|  楼主 | 2021-7-1 15:24 | 只看该作者
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;
                }
        }
}


使用特权

评论回复
5
木木guainv|  楼主 | 2021-7-1 15:24 | 只看该作者
/****************串口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;

                                }
                        }
        }
}


使用特权

评论回复
6
木木guainv|  楼主 | 2021-7-1 15:24 | 只看该作者
/****************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)
        }
}


使用特权

评论回复
7
kiwis66| | 2021-7-19 09:49 | 只看该作者
就是通过串口数据,调整电机状态呗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

156

主题

4130

帖子

5

粉丝