210例子2:IO口步进电机脉冲发生

一、实验目的

用IO口模拟步进电机脉冲的输出,方向的控制;
1、有两个步进电机;

每个步进电机需要两个线控制,
**方向控制:**一根线控制DIR,方向,DIR=0,正转,DIR=1,反转;
**距离和速度控制:**一根线PUL控制脉冲,来一个脉冲,走一个步距角,一般是1.8度,看驱动器的拨码开关的设置,看驱动器的详细信息;脉冲的频率越大,转速越快。
所以,通过控制PUL的个数,可以控制距离角度;控制PUL的频率,可以控制步进电机的速度;
我们这里由于速度要求不高,所以都用延时来控制,不用定时器来产生脉冲了。
假如有个IO口控制PUL;那么可以这么写
正转走100个脉冲,然后反向走100个脉冲;100个脉冲是多少mm,根据实际的传动比等确定。

dir=1;//正方向
for(i=0;i<100;i++)
{
    
    
	pul=1;
	delayms(1);
	pul=0;
	delayms(1);
}
dir=0;  //改变方向
for(i=0;i<100;i++)
{
    
    
	pul=1;
	delayms(1);
	pul=0;
	delayms(1);
}

我们改造一下,编写一个函数,实现第一个步进电机可以指定方向和距离运动;

//头文件和c文件要设置端口和端口模式。
void MoveStepper1(unsigned char seldir,unsigned int pulnum,unsigned int selvel)
{
    
    

//判断方向
	if(seldir==1)
	DIR0=1;
	else if(seldir==0)
	DIR=0;
	//走脉冲数
	for(;pulnum>0;pulnum--)
	{
    
    
		PUL0=1;
		msleep(selvel);
		PUL0=0;
		msleep(selvel)
	}
	
}

在pin_config.h中,设置端口的映射;
在main,c中,设置端口的模式,并且在需要的地方这么使用

MoveStepper1(0,100,1);
//第一个参数,是方向,可以是0或者1;
//第二个参数是脉冲数,大于0;
//第三个参数是速度的毫秒,

上面的例子是走脉冲数,我们实际是需要走毫米,所以再改造下;
在main.c中,宏定义一个比例,比如假如1000个脉冲是1mm;那么比例是1000;
main.c中:

#define KPULMM 1000
//头文件和c文件要设置端口和端口模式。
void MoveStepper1(unsigned char seldir,unsigned int mm0,unsigned int selvel)
{
    
    
unsigned int pul0=0;
//判断方向
	if(seldir==1)
	DIR0=1;
	else if(seldir==0)
	DIR=0;
//将毫米转换成脉冲
pul0=mm0*KPULMM;//假如mm0=10,那么计算得到pul0=10*1000=10000个脉冲
	//走脉冲数
	for(;pulnum>0;pulnum--)
	{
    
    
		PUL0=1;
		msleep(selvel);
		PUL0=0;
		msleep(selvel)
	}
	
}

上面是原理讲解。

比赛要求:

在210开发板中,由于没太多IO口,所以我们将拨盘按钮和BOO0按钮作为电机控制使用,不用这个按键了,后续我们用串口屏的触摸屏来实现按钮的功能。
在这里插入图片描述
在这里插入图片描述

两个步进电机
DIR0-------(硬件IO)IO1--------------------软件映射
PUL0--------IO2
DIR1---------IO3
PUL1---------IO16
在这里插入图片描述

在这里插入图片描述
在main.c中;
设置这几个步进电机口的端口映射;
设置步进电机的端口模式
后面就能使能它为1或者0了。
pin_config.h

/**
* @par  Copyright (C): 2016-2022, Shenzhen Yahboom Tech
* @file         pin_config.c
* @author       Gengyue
* @version      V1.0
* @date         2020.05.27
* @brief        硬件引脚与软件GPIO的宏定义
* @details      
* @par History  见如下说明
*                 
* version:	由于K210使用fpioa现场可编程IO阵列,允许用户将255个内部功能映射到芯片外围的48个自由IO上
*           所以把硬件IO和软件GPIO功能抽出来单独设置,这样更容易理解。
*/
#ifndef _PIN_CONFIG_H_
#define _PIN_CONFIG_H_
/*****************************HEAR-FILE************************************/
#include "fpioa.h"

/*****************************HARDWARE-PIN*********************************/
// 硬件IO口,与原理图对应
#define PIN_LED_0             (0)   //LED灯
#define PIN_LED_1             (17)

#define PIN_LJT_0             (18)  //垃圾桶LJT
#define PIN_LJT_1             (19)
#define PIN_LJT_2             (20)
#define PIN_LJT_3             (21)
#define PIN_LJT_4             (22)
#define PIN_LJT_5             (23)

#define PIN_DIR_0             (1)  //传送步进电机0方向  IO12是普通IO
#define PIN_PUL_0             (2)   //传送步进电机0脉冲输出  普通IO
#define PIN_DIR_1             (3)   //传送步进电机1方向   
#define PIN_PUL_1             (16)   //传送步进电机1脉冲输出

/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define LED0_GPIONUM          (0)
#define LED1_GPIONUM          (1)

#define LJT0_GPIONUM          (2)
#define LJT1_GPIONUM          (3)
#define LJT2_GPIONUM          (4)
#define LJT3_GPIONUM          (5)
#define LJT4_GPIONUM          (6)
#define LJT5_GPIONUM          (7)

#define StepDir0_GPIONUM       (8)
#define StepPul0_GPIONUM       (9)
#define StepDir1_GPIONUM       (10)
#define StepPul1_GPIONUM       (11)
/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
#define FUNC_LED0             (FUNC_GPIO0 + LED0_GPIONUM)
#define FUNC_LED1             (FUNC_GPIO0 + LED1_GPIONUM)
//IO口18--23对应HS高速口,看芯片手册的引脚定义表
#define FUNC_LJT0             (FUNC_GPIOHS0 + LJT0_GPIONUM)
#define FUNC_LJT1             (FUNC_GPIOHS0 + LJT1_GPIONUM)
#define FUNC_LJT2             (FUNC_GPIOHS0 + LJT2_GPIONUM)
#define FUNC_LJT3             (FUNC_GPIOHS0 + LJT3_GPIONUM)
#define FUNC_LJT4             (FUNC_GPIOHS0 + LJT4_GPIONUM)
#define FUNC_LJT5             (FUNC_GPIOHS0 + LJT5_GPIONUM)

#define FUNC_DIR0             (FUNC_GPIOHS0 + StepDir0_GPIONUM)
#define FUNC_PUL0             (FUNC_GPIOHS0 + StepPul0_GPIONUM)
#define FUNC_DIR1             (FUNC_GPIOHS0 + StepDir1_GPIONUM)
#define FUNC_PUL1             (FUNC_GPIOHS0 + StepPul1_GPIONUM)
#endif /* _PIN_CONFIG_H_ */

main.c

//IO18---IO23,普通IO口,输入状态,判断是不是0,是0,说明垃圾满
#include <stdio.h>
#include <unistd.h>
#include "gpio.h"
#include "gpiohs.h"
#include "pin_config.h"
#include "sleep.h"
#include "sysctl.h"
#include "plic.h"
//cmake .. -DPROJ=keypad -G "MinGW Makefiles" 

#define xmmpul 2   //1000个脉冲,是1mm,测试可以修改
/**
* Function       hardware_init
* @author        Gengyue
* @date          2020.05.27
* @brief         硬件初始化,绑定GPIO口
* @param[in]     void
* @param[out]    void
* @retval        void
* @par History   无
*/
void hardware_init(void)
{
    
    
    fpioa_set_function(PIN_LED_0, FUNC_LED0);
    fpioa_set_function(PIN_LED_1, FUNC_LED1);

    fpioa_set_function(PIN_LJT_0, FUNC_LJT0);
    fpioa_set_function(PIN_LJT_1, FUNC_LJT1);
    fpioa_set_function(PIN_LJT_2, FUNC_LJT2);
    fpioa_set_function(PIN_LJT_3, FUNC_LJT3);
    fpioa_set_function(PIN_LJT_4, FUNC_LJT4);
    fpioa_set_function(PIN_LJT_5, FUNC_LJT5);

  fpioa_set_function(PIN_DIR_0, FUNC_DIR0);
    fpioa_set_function(PIN_PUL_0, FUNC_PUL0);
    fpioa_set_function(PIN_DIR_1, FUNC_DIR1);
     fpioa_set_function(PIN_PUL_1, FUNC_PUL1);

}
//步进电机运动函数,因为电机的步距角不一样
void movestepper0(int seldir ,uint32_t mm0; int vms)  //1mm----pul个脉冲
{
    
    
    uint64_t i;
    //和51单片机不一样,这个是GPIO_PV_HIGH代表高电平
    gpio_pin_value_t valuetemp = GPIO_PV_HIGH;

    gpio_pin_value_t valuehigh = GPIO_PV_HIGH;
    gpio_pin_value_t valuelow = GPIO_PV_LOW;
    //判断方向
    if(seldir==1)
    {
    
    
        valuetemp = GPIO_PV_HIGH;
    } 
    else if(seldir==0)
    {
    
    
        valuetemp = GPIO_PV_LOW;
    }
    //设置方向
   //用的是高速IO端口模式,所以是gpiohs
    gpiohs_set_pin(StepDir0_GPIONUM, valuetemp);  
    //根据mm,计算脉冲数
    for(i=0;i<mm0*xmmpul;i++)
    {
    
    
        gpiohs_set_pin(StepPul0_GPIONUM, valuehigh);
        msleep(vms);//
    
        gpiohs_set_pin(StepPul0_GPIONUM, valuelow);
        msleep(vms);//

    }

}
/**
* Function       main
* @author        Gengyue
* @date          2020.05.27
* @brief         主函数,程序的入口
* @param[in]     void
* @param[out]    void
* @retval        0
* @par History   无
*/
int main(void)
{
    
    
    int i=0;
    hardware_init();// 硬件引脚初始化

    gpio_init();    // 使能GPIO的时钟
    // 设置LED0和LED1的GPIO模式为输出
    gpio_set_drive_mode(LED0_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(LED1_GPIONUM, GPIO_DM_OUTPUT);  
    // 先关闭LED0和LED1
    gpio_pin_value_t value = GPIO_PV_HIGH;
    gpio_set_pin(LED0_GPIONUM, value);
    gpio_set_pin(LED1_GPIONUM, value);
    // 设置垃圾桶的传感器的GPIO模式为上拉输入
    gpiohs_set_drive_mode(LJT0_GPIONUM, GPIO_DM_INPUT_PULL_UP);
    gpiohs_set_drive_mode(LJT1_GPIONUM, GPIO_DM_INPUT_PULL_UP);
    gpiohs_set_drive_mode(LJT2_GPIONUM, GPIO_DM_INPUT_PULL_UP);
    gpiohs_set_drive_mode(LJT3_GPIONUM, GPIO_DM_INPUT_PULL_UP);
    gpiohs_set_drive_mode(LJT4_GPIONUM, GPIO_DM_INPUT_PULL_UP);
    gpiohs_set_drive_mode(LJT5_GPIONUM, GPIO_DM_INPUT_PULL_UP);
    //设置步进电机的方向和脉冲引脚是输出模式
    gpiohs_set_drive_mode(StepDir0_GPIONUM, GPIO_DM_OUTPUT);
    gpiohs_set_drive_mode(StepPul0_GPIONUM, GPIO_DM_OUTPUT);
    gpiohs_set_drive_mode(StepDir1_GPIONUM, GPIO_DM_OUTPUT);
    gpiohs_set_drive_mode(StepPul1_GPIONUM, GPIO_DM_OUTPUT);

    while (1)
    {
    
    
       //查询几个GPIO垃圾桶,返回传感器..参考keypad的案例代码
       gpio_pin_value_t state_LJT0 =  gpiohs_get_pin(LJT0_GPIONUM);
       gpio_pin_value_t state_LJT1 =  gpiohs_get_pin(LJT1_GPIONUM);
       gpio_pin_value_t state_LJT2 =  gpiohs_get_pin(LJT2_GPIONUM);
       gpio_pin_value_t state_LJT3 =  gpiohs_get_pin(LJT3_GPIONUM);
       gpio_pin_value_t state_LJT4 =  gpiohs_get_pin(LJT4_GPIONUM);
       gpio_pin_value_t state_LJT5 =  gpiohs_get_pin(LJT5_GPIONUM);
       //gpio_pin_value_t value = GPIO_PV_HIGH; GPIO_PV_LOW
       //LED 低电平亮,高电平不亮
       if(!state_LJT0)
              {
    
    
              //    gpio_set_pin(LED0_GPIONUM, GPIO_PV_LOW);
                  gpio_set_pin(LED1_GPIONUM, GPIO_PV_LOW);
              }
        if(!state_LJT1)
              {
    
    
                //  gpio_set_pin(LED0_GPIONUM, GPIO_PV_LOW);
                  gpio_set_pin(LED1_GPIONUM, GPIO_PV_HIGH);
              }
        if(!state_LJT2)
              {
    
    
                  //gpio_set_pin(LED0_GPIONUM, GPIO_PV_HIGH);
                  gpio_set_pin(LED1_GPIONUM, GPIO_PV_LOW);
              }
        if(!state_LJT3)
              {
    
    
                 // gpio_set_pin(LED0_GPIONUM, GPIO_PV_HIGH);
                  gpio_set_pin(LED1_GPIONUM, GPIO_PV_HIGH);
              }

         //步进电机测试,正方向,两个电机都走100000个脉冲
        gpiohs_set_pin(StepDir0_GPIONUM, GPIO_PV_HIGH);  
        gpiohs_set_pin(StepDir1_GPIONUM, GPIO_PV_HIGH);
        for(i=0;i<100000;i++)
       {
    
    
        gpiohs_set_pin(StepPul0_GPIONUM, GPIO_PV_HIGH);    
        gpiohs_set_pin(StepPul1_GPIONUM, GPIO_PV_HIGH);
        msleep(1);//5000
        gpiohs_set_pin(StepPul0_GPIONUM, GPIO_PV_LOW); 
        gpiohs_set_pin(StepPul1_GPIONUM, GPIO_PV_LOW);
        msleep(1);//5000
       }
       sleep(10);  
         //步进电机测试,反方向,两个电机都走100000个脉冲
        gpiohs_set_pin(StepDir0_GPIONUM, GPIO_PV_LOW);
        gpiohs_set_pin(StepDir1_GPIONUM, GPIO_PV_LOW);
        //步进电机测试,正方向,两个电机都走100000个脉冲
        for(i=0;i<100000;i++)
       {
    
    
        gpiohs_set_pin(StepPul0_GPIONUM, GPIO_PV_HIGH);    
        gpiohs_set_pin(StepPul1_GPIONUM, GPIO_PV_HIGH);
        msleep(1);//5000
        gpiohs_set_pin(StepPul0_GPIONUM, GPIO_PV_LOW);
        gpiohs_set_pin(StepPul1_GPIONUM, GPIO_PV_LOW);
        msleep(1);//5000
       }
       sleep(10);  
        movestepper0(0,100; 1)  //0方向,100个mm,速度是1ms
        sleep(10);
        movestepper0(1,100; 1)  //0方向,100个mm,速度是1ms
        sleep(10);  

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lmf666/article/details/111185566