中文手册说明文档链接地址: 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>© 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--------------------------*/