L6470步进电机驱动芯片


中文手册说明文档链接地址: L6470芯片

简介

L6470芯片自带驱动引擎,支持128微步的电机驱动器,SPI接口

ST官方搜索L6470关键字即可搜到相应的驱动代码例程,本次实验是以SMT32F103ZE的开发板来移植,在七星虫6-(德飞莱)尼莫M3S-串口1收发例程中开展下去。
该套例程中关键的工程文件名称为“dspin.c”和“dspin.h”该代码是本文的核心讲解处,我以翻译好的文件方式整理相关代码。

代码如下

#include "main.h"

dSPIN_RegsStruct_TypeDef dSPIN_RegsStruct;

u32 MotorSpeedConver(u16 Speed)
{// 马达速度转换 将步/s换算成r/min
    uint32_t tSpeed = 0;
    
    tSpeed = ((float)Speed/60)*200;           
    return MaxSpd_Steps_to_Par(tSpeed);
}

/********************************************************************
  * 函数说明:检测L6470硬件忙寄存器
  * 输    入:无
  * 返    回:返回1忙,返回0闲
  ******************************************************************/
uint8_t dSPIN_Busy_HW(u8 Num)
{
//	if(!(GPIO_ReadInputDataBit(dSPIN_BUSY_Port, dSPIN_BUSY_Pin))) 
    if(MotorWaitBusy(Num)) return 0x01;
	else return 0x00;
}  
/********************************************************************
  * 函数说明:检测L6470软件忙寄存器
  * 输    入:无
  * 返    回:返回1忙,返回0闲
  ******************************************************************/
uint8_t dSPIN_Busy_SW(void)
{
//    if(!(dSPIN_Get_Status() & dSPIN_STATUS_BUSY)) return 0x01;
//    else return 0x00;
    return 0x00;
}

/********************************************************************
  * 函数说明:发送/接收一个字节到SPI
  * 输    入:发送字节
  * 返    回:接收字节
  ******************************************************************/
uint8_t dSPIN_Write_Byte(uint8_t byte)
{
    u8 Data=0;
    
    MotorCSEnable(1); // nSS/CS片选信号 - 低  
    Data = SPIx_ReadWriteByte(1, byte);
    MotorCSEnable(0);
    
    return Data;
}

/********************************************************************
  * 函数说明:配置L6470各寄存器初值
  * 输    入:寄存器地址,对应的值
  * 返    回:无
  ******************************************************************/
void dSPIN_Registers_Set(dSPIN_RegsStruct_TypeDef *dSPIN_RegsStruct, u8 mIndex)
{// 配置寄存器
    MotorNumEnable(mIndex);
    
	dSPIN_Set_Param(dSPIN_ABS_POS, dSPIN_RegsStruct->ABS_POS);
	dSPIN_Set_Param(dSPIN_EL_POS, dSPIN_RegsStruct->EL_POS);
	dSPIN_Set_Param(dSPIN_MARK, dSPIN_RegsStruct->MARK);
	dSPIN_Set_Param(dSPIN_ACC, dSPIN_RegsStruct->ACC);
	dSPIN_Set_Param(dSPIN_DEC, dSPIN_RegsStruct->DEC);
	dSPIN_Set_Param(dSPIN_MAX_SPEED, dSPIN_RegsStruct->MAX_SPEED);
	dSPIN_Set_Param(dSPIN_MIN_SPEED, dSPIN_RegsStruct->MIN_SPEED);
	dSPIN_Set_Param(dSPIN_FS_SPD, dSPIN_RegsStruct->FS_SPD);

	dSPIN_Set_Param(dSPIN_KVAL_HOLD, dSPIN_RegsStruct->KVAL_HOLD);
	dSPIN_Set_Param(dSPIN_KVAL_RUN, dSPIN_RegsStruct->KVAL_RUN);
	dSPIN_Set_Param(dSPIN_KVAL_ACC, dSPIN_RegsStruct->KVAL_ACC);
	dSPIN_Set_Param(dSPIN_KVAL_DEC, dSPIN_RegsStruct->KVAL_DEC);
	dSPIN_Set_Param(dSPIN_INT_SPD, dSPIN_RegsStruct->INT_SPD);
	dSPIN_Set_Param(dSPIN_ST_SLP, dSPIN_RegsStruct->ST_SLP);
	dSPIN_Set_Param(dSPIN_FN_SLP_ACC, dSPIN_RegsStruct->FN_SLP_ACC);
	dSPIN_Set_Param(dSPIN_FN_SLP_DEC, dSPIN_RegsStruct->FN_SLP_DEC);
	dSPIN_Set_Param(dSPIN_K_THERM, dSPIN_RegsStruct->K_THERM);
	dSPIN_Set_Param(dSPIN_STALL_TH, dSPIN_RegsStruct->STALL_TH);
      
	dSPIN_Set_Param(dSPIN_OCD_TH, dSPIN_RegsStruct->OCD_TH);
	dSPIN_Set_Param(dSPIN_STEP_MODE, dSPIN_RegsStruct->STEP_MODE);
	dSPIN_Set_Param(dSPIN_ALARM_EN, dSPIN_RegsStruct->ALARM_EN);
	dSPIN_Set_Param(dSPIN_CONFIG, dSPIN_RegsStruct->CONFIG);

}

/**********************************************************************
* 名    称:dSPIN_Regs_Struct_Reset
* 功    能:配置1号电机各参数
* 入口参数:
* 出口参数:
* 说    明:步进电机初始化设置
***********************************************************************/
void dSPIN_Regs_Struct_Reset(u8 mIndex)
{/* 初始化L6470各寄存器初值 */
    memset(&dSPIN_RegsStruct, 0, sizeof(dSPIN_RegsStruct));
 
    dSPIN_RegsStruct.ACC 		= AccDec_Steps_to_Par(2000);    /* 加速率的设置为466 steps/s2,范围14.55至59590 steps/s2*/
    dSPIN_RegsStruct.DEC 		= AccDec_Steps_to_Par(2000);    /* 减速率的设置为466 steps/s2,范围14.55至59590 steps/s2 */  
    dSPIN_RegsStruct.MAX_SPEED 	= MotorSpeedConver(600); 
                                                                /* 最大速度900r/m, 最大速度设置为488步/秒,最大速度设置范围为15.25至15610步/秒*/    
    dSPIN_RegsStruct.FS_SPD 	= FSSpd_Steps_to_Par(1000);    /* 全步进速度设置252步/秒,范围为7.63到15625步/秒*/   
    dSPIN_RegsStruct.MIN_SPEED	= 0x1000|MinSpd_Steps_to_Par(0);/* 最小速度设置为0步/秒,取值范围为0至976.3,步骤/秒*/

    if(mIndex == MOTOR1_NUM)
    {
        if(g_ModParam.xHoldPow >= 20) g_ModParam.xHoldPow = 20;
        if(g_ModParam.xRunPow >= 25)  g_ModParam.xRunPow = 25;
        dSPIN_RegsStruct.KVAL_HOLD 	= Kval_Perc_to_Par(g_ModParam.xHoldPow);        /* 保持占空比(转矩)设定为10%,范围在0到99.6%, 65%=2.43A*/
        dSPIN_RegsStruct.KVAL_RUN 	= Kval_Perc_to_Par(g_ModParam.xRunPow);         /* 运行占空比(转矩)设定为10%,范围在0到99.6%*/
        dSPIN_RegsStruct.KVAL_ACC 	= Kval_Perc_to_Par(g_ModParam.xRunPow);         /* 加速的占空比(转矩)设定为10%,范围在0到99.6%*/        
        dSPIN_RegsStruct.KVAL_DEC 	= Kval_Perc_to_Par(g_ModParam.xRunPow);         /* 减速的占空比(转矩)设定为10%,范围在0到99.6% */  
        dSPIN_RegsStruct.INT_SPD 	= IntSpd_Steps_to_Par(100);     /* 加速/减速曲线斜率的速度值。 range 0 to 3906 steps/s */       
        dSPIN_RegsStruct.ST_SLP 	= BEMF_Slope_Perc_to_Par(0.015);/* 加减速——开始斜率(反电动势)BEMF补偿设置 0 to 0.4% s/step */
        dSPIN_RegsStruct.FN_SLP_ACC = BEMF_Slope_Perc_to_Par(0.026);/* 加速度——结束斜率(反电动势)BEMF补偿设置 0 to 0.4% s/step */      
        dSPIN_RegsStruct.FN_SLP_DEC = BEMF_Slope_Perc_to_Par(0.026);/* 减速度——结束斜率(反电动势)BEMF补偿设置 0 to 0.4% s/step */        
    }
    else
    {
        if(g_ModParam.zHoldPow >= 20) g_ModParam.zHoldPow = 20;
        if(g_ModParam.zRunPow >= 25)  g_ModParam.zRunPow = 25;
        dSPIN_RegsStruct.KVAL_HOLD 	= Kval_Perc_to_Par(g_ModParam.zHoldPow);        /* 保持占空比(转矩)设定为10%,范围在0到99.6%, 65%=2.43A*/
        dSPIN_RegsStruct.KVAL_RUN 	= Kval_Perc_to_Par(g_ModParam.zRunPow);         /* 运行占空比(转矩)设定为10%,范围在0到99.6%*/
        dSPIN_RegsStruct.KVAL_ACC 	= Kval_Perc_to_Par(g_ModParam.zRunPow);         /* 加速的占空比(转矩)设定为10%,范围在0到99.6%*/        
        dSPIN_RegsStruct.KVAL_DEC 	= Kval_Perc_to_Par(g_ModParam.zRunPow);         /* 减速的占空比(转矩)设定为10%,范围在0到99.6% */    
        dSPIN_RegsStruct.INT_SPD 	= IntSpd_Steps_to_Par(100);     /* 加速/减速曲线斜率的速度值。 range 0 to 3906 steps/s */       
        dSPIN_RegsStruct.ST_SLP 	= BEMF_Slope_Perc_to_Par(0.015);/* 加减速——开始斜率(反电动势)BEMF补偿设置 0 to 0.4% s/step */
        dSPIN_RegsStruct.FN_SLP_ACC = BEMF_Slope_Perc_to_Par(0.026);/* 加速度——结束斜率(反电动势)BEMF补偿设置 0 to 0.4% s/step */      
        dSPIN_RegsStruct.FN_SLP_DEC = BEMF_Slope_Perc_to_Par(0.026);/* 减速度——结束斜率(反电动势)BEMF补偿设置 0 to 0.4% s/step */        
    }
    
    dSPIN_RegsStruct.K_THERM 	= KTherm_to_Par(1);             /* 热补偿参数设置为1,范围为1-1.46875*/   
    dSPIN_RegsStruct.OCD_TH 	= dSPIN_OCD_TH_3000mA;          /* 过流阈值设置1500毫安 */
    dSPIN_RegsStruct.STALL_TH 	= StallTh_to_Par(2000);         /* 失速阈值设置至1000mA,范围:31.25 to 4000mA */
    dSPIN_RegsStruct.STEP_MODE 	= dSPIN_STEP_SEL_1_128;         /* 设置到128微步模式 */
    dSPIN_RegsStruct.ALARM_EN 	= 0X00                          /* dSPIN_ALARM_EN_ALL_ENABLE 报警设置 - 启用所有警报 */
                                  | dSPIN_ALARM_EN_OVERCURRENT  // 过流保护
                                  | dSPIN_ALARM_EN_THERMAL_SHUTDOWN     // 过热关闭
                                  | dSPIN_ALARM_EN_THERMAL_WARNING      // 过热警告
                                  | dSPIN_ALARM_EN_UNDER_VOLTAGE
                                  |dSPIN_ALARM_EN_STALL_DET_A
                                  |dSPIN_ALARM_EN_STALL_DET_B
                                  | dSPIN_ALARM_EN_SW_TURN_ON
                                  | dSPIN_ALARM_EN_WRONG_NPERF_CMD
                                    ;
    /* 内部振荡器,2MHz的的OSCOUT时钟,电源电压补偿禁用,启用过流关断,压摆率= 290 V /us,PWM频率为15.6kHz *///ENABLE// //过流关断
    dSPIN_RegsStruct.CONFIG 	= dSPIN_CONFIG_INT_16MHZ  
                                  | dSPIN_CONFIG_SW_HARD_STOP                       
                                  | dSPIN_CONFIG_VS_COMP_DISABLE	                 
                                  | dSPIN_CONFIG_OC_SD_DISABLE
                                  | dSPIN_CONFIG_PWM_DIV_2 //dSPIN_CONFIG_PWM_DIV_2	//(((uint16_t)0x00)<<13)
                                  | dSPIN_CONFIG_PWM_MUL_1;	                        //(((uint16_t)0x07)<<10)
    dSPIN_Registers_Set(&dSPIN_RegsStruct, mIndex);
}

/********************************************************************
  * 函数说明:向L6470发送一个空指令。(不执行任何动作)
  * 输    入:无
  * 返    回:无
  ******************************************************************/
void dSPIN_Nop(void)
{
    /* Send NOP operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_NOP);
}

/********************************************************************
  * 函数说明:Set_Param(寄存器地址,写入的值)命令,设定指定寄存器的值,
  			  有些寄存器要条件满足才可写(详见数据手册)
			  错误寄存器名或错误值会导致命令忽略;WRONG_CMD 标志位高电平
  * 输    入:寄存器名称(地址),寄存器值。1-3字节不等
  * 返    回:无
  ******************************************************************/
void dSPIN_Set_Param(dSPIN_Registers_TypeDef param, uint32_t value)
{
    /* Send SetParam operation code to dSPIN */
	dSPIN_Write_Byte((uint8_t)dSPIN_SET_PARAM | (uint8_t)param);
	switch (param)
	{
		case dSPIN_ABS_POS: ;
		case dSPIN_MARK: ;
			/* Send parameter - byte 2 to dSPIN */
			dSPIN_Write_Byte((uint8_t)(value >> 16));
		case dSPIN_EL_POS: ;
		case dSPIN_ACC: ;
		case dSPIN_DEC: ;
		case dSPIN_MAX_SPEED: ;
		case dSPIN_MIN_SPEED: ;
		case dSPIN_FS_SPD: ;
		case dSPIN_INT_SPD: ;
		case dSPIN_CONFIG: ;
		case dSPIN_STATUS:
			/* Send parameter - byte 1 to dSPIN */
		   	dSPIN_Write_Byte((uint8_t)(value >> 8));
		default:
			/* Send parameter - byte 0 to dSPIN */
		   	dSPIN_Write_Byte((uint8_t)(value));
	}
}

/********************************************************************
  * 函数说明:Get_Param(寄存器地址)命令,读取指定寄存器的值,
  			  可以随时读取
			  错误寄存器地址会导致命令忽略;WRONG_CMD 标志位高电平
  * 输    入:寄存器地址
  * 返    回:返回相应寄存器值,1-3字节不等
  ******************************************************************/
uint32_t dSPIN_Get_Param(dSPIN_Registers_TypeDef param, u8 mIndex)
{
    uint32_t temp = 0;
    uint32_t rx = 0;

    MotorNumEnable(mIndex);

	/* Send GetParam operation code to dSPIN */
	temp = dSPIN_Write_Byte((uint8_t)dSPIN_GET_PARAM | (uint8_t)param);
	/* MSB which should be 0 */
	temp = temp << 24;
	rx |= temp;
	switch (param)
	{
		case dSPIN_ABS_POS: ;
		case dSPIN_MARK: ;
		case dSPIN_SPEED:
		   	temp = dSPIN_Write_Byte((uint8_t)(0x00));
			temp = temp << 16;
			rx |= temp;
		case dSPIN_EL_POS: ;
		case dSPIN_ACC: ;
		case dSPIN_DEC: ;
		case dSPIN_MAX_SPEED: ;
		case dSPIN_MIN_SPEED: ;
		case dSPIN_FS_SPD: ;
		case dSPIN_INT_SPD: ;
		case dSPIN_CONFIG: ;
		case dSPIN_STATUS:
		   	temp = dSPIN_Write_Byte((uint8_t)(0x00));
			temp = temp << 8;
			rx |= temp;
		default:
		   	temp = dSPIN_Write_Byte((uint8_t)(0x00));
			rx |= temp;
	}
	return rx;
}

/********************************************************************
  * 函数说明:RUN(FWD/REV,speed)命令 驱动电机以speed/S速度运行,
  			  此命令可随时执行,执行时BUSY低电平,直至达到目标速度
			  speed应小于最大速度,大于最小速度
			  Go_HOME函数无法返回绝对位置
  * 输    入:FWD:反转	REV:正转	speed:速度(0-15625步/秒)
  * 返    回:无
  ******************************************************************/
void dSPIN_Run(dSPIN_Direction_TypeDef direction, uint32_t speed)
{
    /* Send RUN operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_RUN | direction);
    /* Send speed - byte 2 data dSPIN */
    dSPIN_Write_Byte((uint8_t)(speed >> 16));
    /* Send speed - byte 1 data dSPIN */
    dSPIN_Write_Byte((uint8_t)(speed >> 8));
    /* Send speed - byte 0 data dSPIN */
    dSPIN_Write_Byte((uint8_t)(speed));
}

/********************************************************************
  * 函数说明:Move(FWD/REV,steps)命令,驱动电机运行指定步数。
  			  Go_HOME函数返回绝对位置
			  电机停止状态才能用此命令,否则命令忽略,NOTPERF_CMD标志位高电平
			  执行时BUSY低电平,直至命令完成
  			  绝对位置电机锁死
  * 输    入:0000000-2097152	   Go_HOME函数返回绝对位置
  			  2097153-4194303	   Go_HOME函数返回下一HOME位置
  * 返    回:返回状态
  ******************************************************************/
void dSPIN_Move(dSPIN_Direction_TypeDef direction, uint32_t n_step, u8 mIndex)
{
    MotorNumEnable(mIndex);       // 使能1号电机
    /* Send Move operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_MOVE | direction);
    /* Send n_step - byte 2 data dSPIN */
    dSPIN_Write_Byte((uint8_t)(n_step >> 16));
    /* Send n_step - byte 1 data dSPIN */
    dSPIN_Write_Byte((uint8_t)(n_step >> 8));
    /* Send n_step - byte 0 data dSPIN */
    dSPIN_Write_Byte((uint8_t)(n_step));
}
/********************************************************************
  * 函数说明:Reset Device 命令会复位L6470重新上电。
  			  重新上电时,电源桥禁止状态。
  * 输    入:无
  * 返    回:无
  ******************************************************************/
void dSPIN_Reset_Device(u8 mIndex)
{
    MotorNumEnable(mIndex);       // 使能1号电机
    /* Send ResetDevice operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_RESET_DEVICE);
}
/********************************************************************
  * 函数说明:Reset_Pos命令会重置ABC_POS绝对位置为0,也是HOME位置
  * 输    入:无
  * 返    回:无
  ******************************************************************/
void dSPIN_Reset_Pos(u8 mIndex)
{
    MotorNumEnable(mIndex);       // 使能1号电机
    /* Send ResetPos operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_RESET_POS);
}
/********************************************************************
  * 函数说明:SoftStop命令会导致电机立即减速到零速,
  			  电机停止使用的减速值存储在DEC寄存器中
			  当电机处于高阻抗状态,一个SoftStop的命令强制退出电源桥
			  此命令可以随时随地立即执行。
			  此命令使BUSY标志低电平,直到电机停止。
  * 输    入:无
  * 返    回:返回状态
  ******************************************************************/
void dSPIN_Soft_Stop(void)
{
    /* Send SoftStop operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_SOFT_STOP);
}
/********************************************************************
  * 函数说明:Hard_Stop命令会导致任意速度的电机立即停止。(无减速停止)
			  此命令可以随时立即执行。此命令使BUSY标志电平,直到电机停止。
			  当电机处于高阻抗状态,硬停止命令会强制退出电源桥
  * 输    入:无
  * 返    回:无
  ******************************************************************/
void dSPIN_Hard_Stop(u8 mIndex)
{
    MotorNumEnable(mIndex);
    /* Send HardStop operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_HARD_STOP);
}
/********************************************************************
  * 函数说明:SoftHiZ命令禁用电源桥(高阻抗状态)后减速到零,
  			  所用的减速度值存储在DEC寄存器中。
  			  当电源桥被禁用时,HiZ标志位是高电平。
			  当电机停止时,SoftHiZ的命令强制的电源桥进入高阻抗状态。
			  此命令可以随时随地立即执行。此命令使BUSY标志低,直到电机停止。
  * 输    入:无
  * 返    回:返回状态
  ******************************************************************/
void dSPIN_Soft_HiZ(void)
{
    /* Send SoftHiZ operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_SOFT_HIZ);
}

/********************************************************************
  * 函数说明:HardHiZ命令立即关闭电源桥(高阻抗状态)。(不减速)
  			  当电源桥被禁用时,HiZ标志位是高电平。
  			  当电机停止时,HardHiZ的命令强制的电源桥进入高阻抗状态。
			  此命令可以随时随地立即执行。此命令使BUSY标志低,直到电机停止。
  * 输    入:无
  * 返    回:返回状态
  ******************************************************************/
void dSPIN_Hard_HiZ(void)
{
    /* Send HardHiZ operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_HARD_HIZ);
}
/********************************************************************
  * 函数说明:getStatus命令读取Status状态寄存器的值。
			  getStatus命令重设的状态寄存器警告标志。
			  forcesthe命令使系统的任何错误状态退出
			  The GetStatus command DOES NOT reset the HiZ flag.
  * 输    入:无
  * 返    回:2字节状态
  ******************************************************************/
uint16_t dSPIN_Get_Status(u8 mIndex)
{
    uint16_t temp = 0;
    uint16_t rx = 0;

    MotorNumEnable(mIndex);
    /* Send GetStatus operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_GET_STATUS);
    /* Send zero byte / receive MSByte from dSPIN */
    temp = dSPIN_Write_Byte((uint8_t)(0x00));
    temp = temp << 8;
    rx |= temp;
    /* Send zero byte / receive LSByte from dSPIN */
    temp = dSPIN_Write_Byte((uint8_t)(0x00));
    rx |= temp;
    return rx;
}


/********************************************************************
  * 函数说明:GoMark命令将以最短路径运行到标志位置
  			  相当于Go_To(MARK)命令
			  如果要确定电机方向,必须使用GoTo_DIR命令
			  此命令使BUSY标志低电平,直到电机停止。
			  此命令运行时不能使用其它命令,否则命令忽略,NOTPERF_CMD标志位高电平
  * 输    入:无
  * 返    回:无
  ******************************************************************/
void dSPIN_Go_Mark(void)
{
    /* Send GoMark operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_GO_MARK);
}
/********************************************************************
  * 函数说明:GoHome命令将以最短路径运行到零位置
  			  相当于Go_To(000)命令
			  如果要确定电机方向,必须使用GoTo_DIR命令
			  此命令使BUSY标志低电平,直到电机停止。
			  此命令运行时不能使用其它命令,否则命令忽略,NOTPERF_CMD标志位高电平
  * 输    入:无
  * 返    回:无
  ******************************************************************/
void dSPIN_Go_Home(u8 mIndex)
{
    MotorNumEnable(mIndex);
    /* Send GoHome operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_GO_HOME);
}

/********************************************************************
  * 函数说明:Go_To(ABC_POS)命令,驱动电机到绝对位置。Go_HOME函数返回绝对位置
  			  绝对位置电机锁死
  * 输    入:顺:0x000000-0x1FFFFF	   0 step to 2097151 step
  			  逆:0x3FFFFE-0x200000	   0 step to 2097150 step
  * 返    回:返回状态
  ******************************************************************/
void dSPIN_Go_To(uint32_t abs_pos, u8 mIndex)
{
    /* 发送 GoTo 操作码到L6470 */
    dSPIN_Write_Byte(dSPIN_GO_TO);
    /* 发送绝对位置第2字节 - byte 2 data to L6470 */
    dSPIN_Write_Byte((uint8_t)(abs_pos >> 16));
    /* 发送绝对位置第1字节 - byte 2 data to L6470  */
    dSPIN_Write_Byte((uint8_t)(abs_pos >> 8));
    /* 发送绝对位置第0字节 - byte 2 data to L6470  */
    dSPIN_Write_Byte((uint8_t)(abs_pos));
}
/********************************************************************
  * 函数说明:Go_To_Dir(FWD/REV,ABC_POS)命令,驱动电机到绝对位置。Go_HOME函数返回绝对位置
  			  绝对位置电机锁死
  * 输    入:顺:0x000000-0x200000	   0 step to 2097151 step Go_HOME函数返回绝对位置
  			  逆:0x200001-3FFFFF	   0 step to 2097150 step Go_HOME函数返回下一HOME位置 ******************
  * 返    回:返回状态
  ******************************************************************/
void dSPIN_Go_To_Dir(dSPIN_Direction_TypeDef direction, uint32_t abs_pos, u8 mIndex)
{
    MotorNumEnable(mIndex);
    /* Send GoTo_DIR operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_GO_TO_DIR | direction);
    /* Send absolute position parameter - byte 2 data to dSPIN */
    dSPIN_Write_Byte((uint8_t)(abs_pos >> 16));
    /* Send absolute position parameter - byte 1 data to dSPIN */
    dSPIN_Write_Byte((uint8_t)(abs_pos >> 8));
    /* Send absolute position parameter - byte 0 data to dSPIN */
    dSPIN_Write_Byte((uint8_t)(abs_pos));
}

/**
  * @brief  Issues dSPIN Step Clock command.设置步模式
  * @param  Movement direction (FWD, REV)
  * @retval None
  */
void dSPIN_Step_Clock(dSPIN_Direction_TypeDef direction)
{
    /* Send StepClock operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_STEP_CLOCK | direction);
}
/**
  * @brief  Issues dSPIN Go Until command.
  * @param  Action, Movement direction, Speed
  * @retval None
  */
void dSPIN_Go_Until(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction, uint32_t speed)
{
    /* Send GoUntil operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_GO_UNTIL | action | direction);
    /* Send speed parameter - byte 2 data to dSPIN */
    dSPIN_Write_Byte((uint8_t)(speed >> 16));
    /* Send speed parameter - byte 1 data to dSPIN */
    dSPIN_Write_Byte((uint8_t)(speed >> 8));
    /* Send speed parameter - byte 0 data to dSPIN */
    dSPIN_Write_Byte((uint8_t)(speed));
}

/**
  * @brief  Issues dSPIN Release SW command.
  * @param  Action, Movement direction
  * @retval None
  */
void dSPIN_Release_SW(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction)
{
    /* Send ReleaseSW operation code to dSPIN */
    dSPIN_Write_Byte(dSPIN_RELEASE_SW | action | direction);
}

注意“dspin.h”头文件SPI接口的引脚定义,此处有SPI1和SPI2的声明,为了避免SPI引脚定义错误将其中一个屏蔽掉,将SPI1的干掉不使用它

/**
  ******************************************************************************
  * @file    dspin.h 
  * @author  IMMCC Prague FA - MH
  * @version V1.0.0
  * @date    27-May-2011
  * @brief   Header for dspin.c module
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  */ 

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DSPIN_H
#define __DSPIN_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* Exported constants --------------------------------------------------------*/

/* Select one of the following two evalboard options, comment the other one --*/
/* #define STEVAL_PCC009V2 */
#define STM32_VL_Discovery

/** @defgroup dSPIN signals - Used for connection with STEVAL-PCC009V2 evalboard
  *
  * {
  */

	#define dSPIN_SPI			SPI2
	
	#define dSPIN_SCK_Pin		GPIO_Pin_13
	#define dSPIN_SCK_Port		GPIOB
	
	#define dSPIN_MOSI_Pin		GPIO_Pin_15
	#define dSPIN_MOSI_Port		GPIOB
	
	#define dSPIN_MISO_Pin		GPIO_Pin_14
	#define dSPIN_MISO_Port		GPIOB
	
	#define dSPIN_nSS_Pin		GPIO_Pin_12
	#define dSPIN_nSS_Port		GPIOB
	
	#define dSPIN_BUSY_Pin		GPIO_Pin_10
	#define dSPIN_BUSY_Port		GPIOB
	
	#define dSPIN_FLAG_Pin		GPIO_Pin_11
	#define dSPIN_FLAG_Port		GPIOB
	
	#define dSPIN_PWM1_Pin		GPIO_Pin_0
	#define dSPIN_PWM1_Port		GPIOB
	
	#define dSPIN_PWM2_Pin		GPIO_Pin_1
	#define dSPIN_PWM2_Port		GPIOB

	#define POWER_LED_Pin		GPIO_Pin_4
	#define POWER_LED_Port		GPIOC
	
	/* List all the peripherals, which CLKs have to be enabled! */
	#define dSPIN_PERIPHERAL_CLKs_APB1	(RCC_APB1Periph_SPI2)
	#define dSPIN_PERIPHERAL_CLKs_APB2	(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC)

/**
  * @}
  */

/** @defgroup dSPIN signals - Used for connection with STM32 discovery kit
  *  If another control board is used, please change the following settings
  *  according to the application board wiring diagram.
  *  Do not touch if STEVAL-PCC009V2 is used, see defs below for that evalboard.
  * {
  */
//#ifdef STM32_VL_Discovery
//	#define dSPIN_SPI			SPI1
//	
//	#define dSPIN_SCK_Pin		GPIO_Pin_5
//	#define dSPIN_SCK_Port		GPIOA
//	
//	#define dSPIN_MOSI_Pin		GPIO_Pin_7
//	#define dSPIN_MOSI_Port		GPIOA
//	
//	#define dSPIN_MISO_Pin		GPIO_Pin_6
//	#define dSPIN_MISO_Port		GPIOA
//	
//	#define dSPIN_nSS_Pin		GPIO_Pin_4
//	#define dSPIN_nSS_Port		GPIOA
//	
//	#define dSPIN_BUSY_Pin		GPIO_Pin_4
//	#define dSPIN_BUSY_Port		GPIOC
//	
//	#define dSPIN_FLAG_Pin		GPIO_Pin_5
//	#define dSPIN_FLAG_Port		GPIOC
//	
//	#define dSPIN_PWM1_Pin		GPIO_Pin_1
//	#define dSPIN_PWM1_Port		GPIOA
//	
//	#define dSPIN_PWM2_Pin		GPIO_Pin_0
//	#define dSPIN_PWM2_Port		GPIOB
//	
//	/* List all the peripherals, which CLKs have to be enabled! */
//	#define dSPIN_PERIPHERAL_CLKs_APB1	(0x00)
//	#define dSPIN_PERIPHERAL_CLKs_APB2	(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_SPI1)
//#endif
/**
  * @}
  */


/** @defgroup dSPIN register bits / masks
  * @{
  */

/* dSPIN electrical position register masks */
#define dSPIN_ELPOS_STEP_MASK			((uint8_t)0xC0)
#define dSPIN_ELPOS_MICROSTEP_MASK		((uint8_t)0x3F)

/* dSPIN min speed register bit / mask */
#define dSPIN_LSPD_OPT			((uint16_t)0x1000)
#define dSPIN_MIN_SPEED_MASK	((uint16_t)0x0FFF)


/* Exported types ------------------------------------------------------------*/

/** 
  * @brief dSPIN Init structure definition
  */
typedef struct
{
  uint32_t ABS_POS;
  uint16_t EL_POS;
  uint32_t MARK;
  uint32_t SPEED;
  uint16_t ACC;
  uint16_t DEC;
  uint16_t MAX_SPEED;
  uint16_t MIN_SPEED;
  uint16_t FS_SPD;
  uint8_t  KVAL_HOLD;
  uint8_t  KVAL_RUN;
  uint8_t  KVAL_ACC;
  uint8_t  KVAL_DEC;
  uint16_t INT_SPD;
  uint8_t  ST_SLP;
  uint8_t  FN_SLP_ACC;
  uint8_t  FN_SLP_DEC;
  uint8_t  K_THERM;
  uint8_t  ADC_OUT;
  uint8_t  OCD_TH;
  uint8_t  STALL_TH;
  uint8_t  STEP_MODE;
  uint8_t  ALARM_EN;
  uint16_t CONFIG;
}dSPIN_RegsStruct_TypeDef;

/* dSPIN overcurrent threshold options */
typedef enum {
	dSPIN_OCD_TH_375mA		=((uint8_t)0x00),
	dSPIN_OCD_TH_750mA		=((uint8_t)0x01),
	dSPIN_OCD_TH_1125mA		=((uint8_t)0x02),
	dSPIN_OCD_TH_1500mA		=((uint8_t)0x03),
	dSPIN_OCD_TH_1875mA		=((uint8_t)0x04),
	dSPIN_OCD_TH_2250mA		=((uint8_t)0x05),
	dSPIN_OCD_TH_2625mA		=((uint8_t)0x06),
	dSPIN_OCD_TH_3000mA		=((uint8_t)0x07),
	dSPIN_OCD_TH_3375mA		=((uint8_t)0x08),
	dSPIN_OCD_TH_3750mA		=((uint8_t)0x09),
	dSPIN_OCD_TH_4125mA		=((uint8_t)0x0A),
	dSPIN_OCD_TH_4500mA		=((uint8_t)0x0B),
	dSPIN_OCD_TH_4875mA		=((uint8_t)0x0C),
	dSPIN_OCD_TH_5250mA		=((uint8_t)0x0D),
	dSPIN_OCD_TH_5625mA		=((uint8_t)0x0E),
	dSPIN_OCD_TH_6000mA		=((uint8_t)0x0F)
} dSPIN_OCD_TH_TypeDef;

/* dSPIN STEP_MODE register masks */
typedef enum {
	dSPIN_STEP_MODE_STEP_SEL		=((uint8_t)0x07),
	dSPIN_STEP_MODE_SYNC_SEL		=((uint8_t)0x70),
	dSPIN_STEP_MODE_SYNC_EN			=((uint8_t)0x80)
} dSPIN_STEP_MODE_Masks_TypeDef;

 /* dSPIN STEP_MODE register options */
/* dSPIN STEP_SEL options */
typedef enum {
	dSPIN_STEP_SEL_1		=((uint8_t)0x00),
	dSPIN_STEP_SEL_1_2		=((uint8_t)0x01),
	dSPIN_STEP_SEL_1_4		=((uint8_t)0x02),
	dSPIN_STEP_SEL_1_8		=((uint8_t)0x03),
	dSPIN_STEP_SEL_1_16		=((uint8_t)0x04),
	dSPIN_STEP_SEL_1_32		=((uint8_t)0x05),
	dSPIN_STEP_SEL_1_64		=((uint8_t)0x06),
	dSPIN_STEP_SEL_1_128	=((uint8_t)0x07)
} dSPIN_STEP_SEL_TypeDef;

/* dSPIN SYNC_SEL options */
typedef enum {
	dSPIN_SYNC_SEL_1_2		=((uint8_t)0x00),
	dSPIN_SYNC_SEL_1		=((uint8_t)0x10),
	dSPIN_SYNC_SEL_2		=((uint8_t)0x20),
	dSPIN_SYNC_SEL_4		=((uint8_t)0x30),
	dSPIN_SYNC_SEL_8		=((uint8_t)0x40),
	dSPIN_SYNC_SEL_16		=((uint8_t)0x50),
	dSPIN_SYNC_SEL_32		=((uint8_t)0x60),
	dSPIN_SYNC_SEL_64		=((uint8_t)0x70)
} dSPIN_SYNC_SEL_TypeDef;

#define dSPIN_SYNC_EN		0x80

/* dSPIN ALARM_EN register options */
typedef enum {
	dSPIN_ALARM_EN_OVERCURRENT			=((uint8_t)0x01),
	dSPIN_ALARM_EN_THERMAL_SHUTDOWN		=((uint8_t)0x02),
	dSPIN_ALARM_EN_THERMAL_WARNING		=((uint8_t)0x04),
	dSPIN_ALARM_EN_UNDER_VOLTAGE		=((uint8_t)0x08),
	dSPIN_ALARM_EN_STALL_DET_A			=((uint8_t)0x10),
	dSPIN_ALARM_EN_STALL_DET_B			=((uint8_t)0x20),
	dSPIN_ALARM_EN_SW_TURN_ON			=((uint8_t)0x40),
	dSPIN_ALARM_EN_WRONG_NPERF_CMD		=((uint8_t)0x80)
} dSPIN_ALARM_EN_TypeDef;

/* dSPIN Config register masks */
typedef enum {
	dSPIN_CONFIG_OSC_SEL					=((uint16_t)0x0007),
	dSPIN_CONFIG_EXT_CLK					=((uint16_t)0x0008),
	dSPIN_CONFIG_SW_MODE					=((uint16_t)0x0010),
	dSPIN_CONFIG_EN_VSCOMP					=((uint16_t)0x0020),
	dSPIN_CONFIG_OC_SD						=((uint16_t)0x0080),
	dSPIN_CONFIG_POW_SR						=((uint16_t)0x0300),
	dSPIN_CONFIG_F_PWM_DEC					=((uint16_t)0x1C00),
	dSPIN_CONFIG_F_PWM_INT					=((uint16_t)0xE000)
} dSPIN_CONFIG_Masks_TypeDef;

/* dSPIN Config register options */
typedef enum {
	dSPIN_CONFIG_INT_16MHZ					=((uint16_t)0x0000),
	dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ		=((uint16_t)0x0008),
	dSPIN_CONFIG_INT_16MHZ_OSCOUT_4MHZ		=((uint16_t)0x0009),
	dSPIN_CONFIG_INT_16MHZ_OSCOUT_8MHZ		=((uint16_t)0x000A),
	dSPIN_CONFIG_INT_16MHZ_OSCOUT_16MHZ		=((uint16_t)0x000B),
	dSPIN_CONFIG_EXT_8MHZ_XTAL_DRIVE		=((uint16_t)0x0004),
	dSPIN_CONFIG_EXT_16MHZ_XTAL_DRIVE		=((uint16_t)0x0005),
	dSPIN_CONFIG_EXT_24MHZ_XTAL_DRIVE		=((uint16_t)0x0006),
	dSPIN_CONFIG_EXT_32MHZ_XTAL_DRIVE		=((uint16_t)0x0007),
	dSPIN_CONFIG_EXT_8MHZ_OSCOUT_INVERT		=((uint16_t)0x000C),
	dSPIN_CONFIG_EXT_16MHZ_OSCOUT_INVERT	=((uint16_t)0x000D),
	dSPIN_CONFIG_EXT_24MHZ_OSCOUT_INVERT	=((uint16_t)0x000E),
	dSPIN_CONFIG_EXT_32MHZ_OSCOUT_INVERT	=((uint16_t)0x000F)
} dSPIN_CONFIG_OSC_MGMT_TypeDef;

typedef enum {
	dSPIN_CONFIG_SW_HARD_STOP		=((uint16_t)0x0000),
	dSPIN_CONFIG_SW_USER			=((uint16_t)0x0010)
} dSPIN_CONFIG_SW_MODE_TypeDef;

typedef enum {
	dSPIN_CONFIG_VS_COMP_DISABLE	=((uint16_t)0x0000),
	dSPIN_CONFIG_VS_COMP_ENABLE		=((uint16_t)0x0020)
} dSPIN_CONFIG_EN_VSCOMP_TypeDef;

typedef enum {
	dSPIN_CONFIG_OC_SD_DISABLE		=((uint16_t)0x0000),
	dSPIN_CONFIG_OC_SD_ENABLE		=((uint16_t)0x0080)
} dSPIN_CONFIG_OC_SD_TypeDef;

typedef enum {
	dSPIN_CONFIG_SR_180V_us		=((uint16_t)0x0000),
	dSPIN_CONFIG_SR_290V_us		=((uint16_t)0x0200),
	dSPIN_CONFIG_SR_530V_us		=((uint16_t)0x0300)
} dSPIN_CONFIG_POW_SR_TypeDef;

typedef enum {
	dSPIN_CONFIG_PWM_DIV_1		=(((uint16_t)0x00)<<13),
	dSPIN_CONFIG_PWM_DIV_2		=(((uint16_t)0x01)<<13),
	dSPIN_CONFIG_PWM_DIV_3		=(((uint16_t)0x02)<<13),
	dSPIN_CONFIG_PWM_DIV_4		=(((uint16_t)0x03)<<13),
	dSPIN_CONFIG_PWM_DIV_5		=(((uint16_t)0x04)<<13),
	dSPIN_CONFIG_PWM_DIV_6		=(((uint16_t)0x05)<<13),
	dSPIN_CONFIG_PWM_DIV_7		=(((uint16_t)0x06)<<13)
} dSPIN_CONFIG_F_PWM_INT_TypeDef;

typedef enum {
	dSPIN_CONFIG_PWM_MUL_0_625		=(((uint16_t)0x00)<<10),
	dSPIN_CONFIG_PWM_MUL_0_75		=(((uint16_t)0x01)<<10),
	dSPIN_CONFIG_PWM_MUL_0_875		=(((uint16_t)0x02)<<10),
	dSPIN_CONFIG_PWM_MUL_1			=(((uint16_t)0x03)<<10),
	dSPIN_CONFIG_PWM_MUL_1_25		=(((uint16_t)0x04)<<10),
	dSPIN_CONFIG_PWM_MUL_1_5		=(((uint16_t)0x05)<<10),
	dSPIN_CONFIG_PWM_MUL_1_75		=(((uint16_t)0x06)<<10),
	dSPIN_CONFIG_PWM_MUL_2			=(((uint16_t)0x07)<<10)
} dSPIN_CONFIG_F_PWM_DEC_TypeDef;

/* Status Register bit masks */
typedef enum {
	dSPIN_STATUS_HIZ			=(((uint16_t)0x0001)),
	dSPIN_STATUS_BUSY			=(((uint16_t)0x0002)),
	dSPIN_STATUS_SW_F			=(((uint16_t)0x0004)),
	dSPIN_STATUS_SW_EVN			=(((uint16_t)0x0008)),
	dSPIN_STATUS_DIR			=(((uint16_t)0x0010)),
	dSPIN_STATUS_MOT_STATUS		=(((uint16_t)0x0060)),
	dSPIN_STATUS_NOTPERF_CMD	=(((uint16_t)0x0080)),
	dSPIN_STATUS_WRONG_CMD		=(((uint16_t)0x0100)),
	dSPIN_STATUS_UVLO			=(((uint16_t)0x0200)),
	dSPIN_STATUS_TH_WRN			=(((uint16_t)0x0400)),
	dSPIN_STATUS_TH_SD			=(((uint16_t)0x0800)),
	dSPIN_STATUS_OCD			=(((uint16_t)0x1000)),
	dSPIN_STATUS_STEP_LOSS_A	=(((uint16_t)0x2000)),
	dSPIN_STATUS_STEP_LOSS_B	=(((uint16_t)0x4000)),
	dSPIN_STATUS_SCK_MOD		=(((uint16_t)0x8000))
} dSPIN_STATUS_Masks_TypeDef;

/* Status Register options */
typedef enum {
	dSPIN_STATUS_MOT_STATUS_STOPPED			=(((uint16_t)0x0000)<<13),
	dSPIN_STATUS_MOT_STATUS_ACCELERATION	=(((uint16_t)0x0001)<<13),
	dSPIN_STATUS_MOT_STATUS_DECELERATION	=(((uint16_t)0x0002)<<13),
	dSPIN_STATUS_MOT_STATUS_CONST_SPD		=(((uint16_t)0x0003)<<13)
} dSPIN_STATUS_TypeDef;

/* dSPIN internal register addresses */
typedef enum {
	dSPIN_ABS_POS			=((uint8_t)0x01),
	dSPIN_EL_POS			=((uint8_t)0x02),
	dSPIN_MARK				=((uint8_t)0x03),
	dSPIN_SPEED				=((uint8_t)0x04),
	dSPIN_ACC				=((uint8_t)0x05),
	dSPIN_DEC				=((uint8_t)0x06),
	dSPIN_MAX_SPEED			=((uint8_t)0x07),
	dSPIN_MIN_SPEED			=((uint8_t)0x08),
	dSPIN_FS_SPD			=((uint8_t)0x15),
	dSPIN_KVAL_HOLD			=((uint8_t)0x09),
	dSPIN_KVAL_RUN			=((uint8_t)0x0A),
	dSPIN_KVAL_ACC			=((uint8_t)0x0B),
	dSPIN_KVAL_DEC			=((uint8_t)0x0C),
	dSPIN_INT_SPD			=((uint8_t)0x0D),
	dSPIN_ST_SLP			=((uint8_t)0x0E),
	dSPIN_FN_SLP_ACC		=((uint8_t)0x0F),
	dSPIN_FN_SLP_DEC		=((uint8_t)0x10),
	dSPIN_K_THERM			=((uint8_t)0x11),
	dSPIN_ADC_OUT			=((uint8_t)0x12),
	dSPIN_OCD_TH			=((uint8_t)0x13),
	dSPIN_STALL_TH			=((uint8_t)0x14),
	dSPIN_STEP_MODE			=((uint8_t)0x16),
	dSPIN_ALARM_EN			=((uint8_t)0x17),
	dSPIN_CONFIG			=((uint8_t)0x18),
	dSPIN_STATUS			=((uint8_t)0x19),
	dSPIN_RESERVED_REG1		=((uint8_t)0x1A),
	dSPIN_RESERVED_REG2		=((uint8_t)0x1B)
} dSPIN_Registers_TypeDef;

/* dSPIN command set */
typedef enum {
	dSPIN_NOP			=((uint8_t)0x00),
	dSPIN_SET_PARAM		=((uint8_t)0x00),
	dSPIN_GET_PARAM		=((uint8_t)0x20),
	dSPIN_RUN			=((uint8_t)0x50),
	dSPIN_STEP_CLOCK	=((uint8_t)0x58),
	dSPIN_MOVE			=((uint8_t)0x40),
	dSPIN_GO_TO			=((uint8_t)0x60),
	dSPIN_GO_TO_DIR		=((uint8_t)0x68),
	dSPIN_GO_UNTIL		=((uint8_t)0x82),
	dSPIN_RELEASE_SW	=((uint8_t)0x92),
	dSPIN_GO_HOME		=((uint8_t)0x70),
	dSPIN_GO_MARK		=((uint8_t)0x78),
	dSPIN_RESET_POS		=((uint8_t)0xD8),
	dSPIN_RESET_DEVICE	=((uint8_t)0xC0),
	dSPIN_SOFT_STOP		=((uint8_t)0xB0),
	dSPIN_HARD_STOP		=((uint8_t)0xB8),
	dSPIN_SOFT_HIZ		=((uint8_t)0xA0),
	dSPIN_HARD_HIZ		=((uint8_t)0xA8),
	dSPIN_GET_STATUS	=((uint8_t)0xD0),
	dSPIN_RESERVED_CMD1	=((uint8_t)0xEB),
	dSPIN_RESERVED_CMD2	=((uint8_t)0xF8)
} dSPIN_Commands_TypeDef;

/* dSPIN direction options */
typedef enum {
	FWD		=((uint8_t)0x01),
	REV		=((uint8_t)0x00)
} dSPIN_Direction_TypeDef;

/* dSPIN action options */
typedef enum {
	ACTION_RESET	=((uint8_t)0x00),
	ACTION_COPY		=((uint8_t)0x01)
} dSPIN_Action_TypeDef;
/**
  * @}
  */


/* Exported macro ------------------------------------------------------------*/
#define Speed_Steps_to_Par(steps) ((uint32_t)(((steps)*67.108864)+0.5))			/* Speed conversion, range 0 to 15625 steps/s */
#define AccDec_Steps_to_Par(steps) ((uint16_t)(((steps)*0.068719476736)+0.5))	/* Acc/Dec rates conversion, range 14.55 to 59590 steps/s2 */
#define MaxSpd_Steps_to_Par(steps) ((uint16_t)(((steps)*0.065536)+0.5))			/* Max Speed conversion, range 15.25 to 15610 steps/s */
#define MinSpd_Steps_to_Par(steps) ((uint16_t)(((steps)*4.194304)+0.5))			/* Min Speed conversion, range 0 to 976.3 steps/s */
#define FSSpd_Steps_to_Par(steps) ((uint16_t)((steps)*0.065536))				/* Full Step Speed conversion, range 7.63 to 15625 steps/s */
#define IntSpd_Steps_to_Par(steps) ((uint16_t)(((steps)*4.194304)+0.5))			/* Intersect Speed conversion, range 0 to 3906 steps/s */
#define Kval_Perc_to_Par(perc) ((uint8_t)(((perc)/0.390625)+0.5))				/* KVAL conversions, range 0.4% to 99.6% */
#define BEMF_Slope_Perc_to_Par(perc) ((uint8_t)(((perc)/0.00156862745098)+0.5))	/* BEMF compensation slopes, range 0 to 0.4% s/step */
#define KTherm_to_Par(KTherm) ((uint8_t)(((KTherm - 1)/0.03125)+0.5))			/* K_THERM compensation conversion, range 1 to 1.46875 */
#define StallTh_to_Par(StallTh) ((uint8_t)(((StallTh - 31.25)/31.25)+0.5))		/* Stall Threshold conversion, range 31.25mA to 4000mA */


/* Exported functions ------------------------------------------------------- */
void dSPIN_Peripherals_Init(void);
void dSPIN_Regs_Struct_Reset(dSPIN_RegsStruct_TypeDef* dSPIN_RegsStruct);
void dSPIN_Registers_Set(dSPIN_RegsStruct_TypeDef* dSPIN_RegsStruct);
void dSPIN_Nop(void);
void dSPIN_Set_Param(dSPIN_Registers_TypeDef param, uint32_t value);
uint32_t dSPIN_Get_Param(dSPIN_Registers_TypeDef param);
void dSPIN_Run(dSPIN_Direction_TypeDef direction, uint32_t speed);
void dSPIN_Step_Clock(dSPIN_Direction_TypeDef direction);
void dSPIN_Move(dSPIN_Direction_TypeDef direction, uint32_t n_step);
void dSPIN_Go_To(uint32_t abs_pos);
void dSPIN_Go_To_Dir(dSPIN_Direction_TypeDef direction, uint32_t abs_pos);
void dSPIN_Go_Until(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction, uint32_t speed);
void dSPIN_Release_SW(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction);
void dSPIN_Go_Home(void);
void dSPIN_Go_Mark(void);
void dSPIN_Reset_Pos(void);
void dSPIN_Reset_Device(void);
void dSPIN_Soft_Stop(void);
void dSPIN_Hard_Stop(void);
void dSPIN_Soft_HiZ(void);
void dSPIN_Hard_HiZ(void);
uint16_t dSPIN_Get_Status(void);
uint8_t dSPIN_Busy_HW(void);
uint8_t dSPIN_Busy_SW(void);
uint8_t dSPIN_Flag(void);




uint8_t dSPIN_Write_Byte(uint8_t byte);



#endif /* __DSPIN_H */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

主代码部分

/*-------------------------------------------------------------------------------
文件名称:main.c
文件描述:通过串口1,使用printf函数打印信息,编译时需勾选Use MicroLIB
硬件平台:尼莫M3S开发板
编写整理:shifang
固件库  :V3.5
技术论坛:www.doflye.net
备    注:通过简单修改可以移植到其他开发板,部分资料来源于网络。
---------------------------------------------------------------------------------*/
#include <stdio.h>
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "timer.h"
#include "beep.h"

#include "dspin.h"



  RCC_ClocksTypeDef RCC_ClockFreq;
  uint32_t dSPIN_rx_data = 0;
  dSPIN_RegsStruct_TypeDef dSPIN_RegsStruct;
  uint8_t temp;

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

	
	
int main(void)
{
	  GPIO_InitTypeDef GPIO_InitStructure;
	  USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
	 
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
 	  USART_DeInit(USART1);  //复位串口1
	  //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
   
    //USART1_RX	  PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10     
	
	  //Usart1 NVIC 配置

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	  NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  /* USARTx configured as follow:
        - BaudRate = 9600 baud  波特率
        - Word Length = 8 Bits  数据长度
        - One Stop Bit          停止位
        - No parity             校验方式
        - Hardware flow control disabled (RTS and CTS signals) 硬件控制流
        - Receive and transmit enabled                         使能发送和接收
  */
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART1, &USART_InitStructure);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
  USART_Cmd(USART1, ENABLE);                    //使能串口 

	LED_Init();//LED初始化
  KEY_Init();//按键初始化
  SysTick_Init();//延时初始化
	BEEP_Init();   //蜂鸣器初始化
	printf("\n\rUSART Printf Example: (德飞莱)尼莫M3S开发板串口测试程序\r输入任何信息发送,接收到同样信息");

	


	/*!< At this stage the microcontroller clock setting is already configured, 
	   this is done through SystemInit() function which is called from startup
	   file (startup_stm32f10x_xx.s) before to branch to application main.
	   To reconfigure the default setting of SystemInit() function, refer to
	   system_stm32f10x.c file
	 */     
	   
	/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
	//SetSysClock();
	
	/* This function fills the RCC_ClockFreq structure with the current
	 frequencies of different on chip clocks (for debug purpose) */
	//RCC_GetClocksFreq(&RCC_ClockFreq);
	
	/* SPI初始化*/ 
	dSPIN_Peripherals_Init();
	  
	/* 结构初始化默认值,为了避免空白记录*/ 
	dSPIN_Regs_Struct_Reset(&dSPIN_RegsStruct);
	
	/* 加速度速度设置到 to 466 steps/s2, range 14.55 to 59590 steps/s2 */
	dSPIN_RegsStruct.ACC 		= AccDec_Steps_to_Par(466);
	/* 减速速度设置到 to 466 steps/s2, range 14.55 to 59590 steps/s2 */
	dSPIN_RegsStruct.DEC 		= AccDec_Steps_to_Par(466); 
	/* 最高速度设置到 488 steps/s, range 15.25 to 15610 steps/s */
	dSPIN_RegsStruct.MAX_SPEED 	= MaxSpd_Steps_to_Par(488);
	/* 最低速度设置到 0 steps/s, range 0 to 976.3 steps/s */
	dSPIN_RegsStruct.MIN_SPEED	= MinSpd_Steps_to_Par(0);
	/* 完整的一步速度设置为 252 steps/s, range 7.63 to 15625 steps/s */
	dSPIN_RegsStruct.FS_SPD 	= FSSpd_Steps_to_Par(15625);
	/* 持有工作周期(扭矩)设置为10%, range 0 to 99.6% */
	dSPIN_RegsStruct.KVAL_HOLD 	= Kval_Perc_to_Par(10);
	/* 运行工作周期(扭矩)设置到10%, range 0 to 99.6% */
	dSPIN_RegsStruct.KVAL_RUN 	= Kval_Perc_to_Par(10);
	/* 加速工作周期(扭矩)设置为10%, range 0 to 99.6% */
	dSPIN_RegsStruct.KVAL_ACC 	= Kval_Perc_to_Par(10);
	/* 减速责任周期(扭矩)设置为10%, range 0 to 99.6% */
	dSPIN_RegsStruct.KVAL_DEC 	= Kval_Perc_to_Par(10);		
	/* 反电动势相交速度设置补偿  200 steps/s, range 0 to 3906 steps/s */
	dSPIN_RegsStruct.INT_SPD 	= IntSpd_Steps_to_Par(200);
	/* 反电动势开始为反电动势补偿斜率设置步骤到 0.038% step/s, range 0 to 0.4% s/step */
	dSPIN_RegsStruct.ST_SLP 	= BEMF_Slope_Perc_to_Par(0.038);
	/* 反电动势最终acc斜率设置反电动势补偿步骤到 0.063% step/s, range 0 to 0.4% s/step */
	dSPIN_RegsStruct.FN_SLP_ACC = BEMF_Slope_Perc_to_Par(0.063);
	/* 反电动势最后12月坡设置反电动势补偿步骤 0.063% step/s, range 0 to 0.4% s/step */
	dSPIN_RegsStruct.FN_SLP_DEC = BEMF_Slope_Perc_to_Par(0.063);
	/* 热补偿参数设置为 1, range 1 to 1.46875 */
	dSPIN_RegsStruct.K_THERM 	= KTherm_to_Par(1);
	/* 过电流阈值设置到1500 mA*/
	dSPIN_RegsStruct.OCD_TH 	= dSPIN_OCD_TH_1500mA;
	/* 停滞阈值设置到1000 mA, range 31.25 to 4000mA */
	dSPIN_RegsStruct.STALL_TH 	= StallTh_to_Par(4000);
	/* 步模式设置到128微步*/
	dSPIN_RegsStruct.STEP_MODE 	= dSPIN_STEP_SEL_1_128;
	/* 启用报警设置——所有的警报*/
	dSPIN_RegsStruct.ALARM_EN 	= dSPIN_ALARM_EN_OVERCURRENT | dSPIN_ALARM_EN_THERMAL_SHUTDOWN
		| dSPIN_ALARM_EN_THERMAL_WARNING | dSPIN_ALARM_EN_UNDER_VOLTAGE | dSPIN_ALARM_EN_STALL_DET_A
		| dSPIN_ALARM_EN_STALL_DET_B | dSPIN_ALARM_EN_SW_TURN_ON | dSPIN_ALARM_EN_WRONG_NPERF_CMD;
	/* Internal oscillator, 2MHz OSCOUT clock, supply voltage compensation disabled, *
	 * overcurrent shutdown enabled, slew-rate = 290 V/us, PWM frequency = 15.6kHz   */
	dSPIN_RegsStruct.CONFIG 	= dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ | dSPIN_CONFIG_SW_HARD_STOP
		| dSPIN_CONFIG_VS_COMP_DISABLE | dSPIN_CONFIG_OC_SD_ENABLE | dSPIN_CONFIG_SR_290V_us
		| dSPIN_CONFIG_PWM_DIV_2 | dSPIN_CONFIG_PWM_MUL_1;	

	/* 项目所有dSPIN寄存器*/
	dSPIN_Registers_Set(&dSPIN_RegsStruct);

	/*举动60000步rorward, 0到4194303之间*/
	dSPIN_Move(FWD, (uint32_t)(4194303));
	
	/*等待直到没有忙——忙针测试*/
	while(dSPIN_Busy_HW());
	
	/*发送dSPIN命令改变持有责任周期的0.5%*/
	dSPIN_Set_Param(dSPIN_KVAL_HOLD, Kval_Perc_to_Par(0.5));
	
	/*发送dSPIN命令改变运行责任周期的5%*/
	dSPIN_Set_Param(dSPIN_KVAL_RUN, Kval_Perc_to_Par(5));
	
	/* 恒速运行50 / s反方向的步骤*/
	dSPIN_Run(REV, Speed_Steps_to_Par(500));

	/* Wait few seconds - motor turns */
//	Delay(0x00FFFFFF);
		Delay_ms(2000);	
	/* Perform SoftStop commmand 执行SoftStop commmand*/
	dSPIN_Soft_Stop();
	
	/*等待直到没有忙——忙状态寄存器的状态检查 */
	while(dSPIN_Busy_SW());
	
	/* Move by 100,000 steps forward, range 0 to 4,194,303 举动100000步向前,0到4194303之间*/
	dSPIN_Move(FWD, (uint32_t)(100000));
	
	/* Wait untill not busy 等待直到不忙*/
//	while(dSPIN_Busy_SW());
	
	/*测试国旗胸针的轮询,在无尽的等待周期是否检测到的问题*/
	if(dSPIN_Flag()) while(1);
	
	/*发出dSPIN回家命令*/
	dSPIN_Go_Home();
	/*等待直到没有忙——忙针测试*/
	while(dSPIN_Busy_HW());
	
	/*发出dSPIN去命令*/
	dSPIN_Go_To(0x0000FFFF);
	/*等待直到没有忙——忙针测试*/
	while(dSPIN_Busy_HW());
	
	/*发出dSPIN去命令*/
	dSPIN_Go_To_Dir(FWD, 0x0001FFFF);
	/*等待直到没有忙——忙针测试*/
	while(dSPIN_Busy_HW());
	
	/*阅读从dSPIN运行周期性(dSPIN_KVAL_RUN)参数*/
	dSPIN_rx_data = dSPIN_Get_Param(dSPIN_KVAL_RUN);
	
	/*从dSPIN读取相交的速度(dSPIN_INT_SPD)参数*/
	dSPIN_rx_data = dSPIN_Get_Param(dSPIN_INT_SPD);

	/*读状态寄存器的内容*/
	dSPIN_rx_data = dSPIN_Get_Status();
	
	/*从dSPIN读取(dSPIN_ABS_POS)绝对位置参数*/
	dSPIN_rx_data = dSPIN_Get_Param(dSPIN_ABS_POS);
	
//	printf("绝对位置参数 = %f \r\n", dSPIN_rx_data);

	/*复位位置计数器*/
	dSPIN_Reset_Pos();

	/*从dSPIN读取(dSPIN_ABS_POS)绝对位置参数*/
	dSPIN_rx_data = dSPIN_Get_Param(dSPIN_ABS_POS);

	/*发出dSPIN硬HiZ命令禁用功率级(高阻抗)*/
	dSPIN_Hard_HiZ();
	


  while (1)
  {
	//使用printf函数循环发送固定信息
	Delay_ms(500);	
  LED2_REV;	
  }
	
}


PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* 循环等待直到发送结束*/
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

/*----------------------德飞莱 技术论坛:www.doflye.net--------------------------*/

硬件连接图附上

在这里插入图片描述

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢谢~谢先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值