DRV10983电机驱动

目录

一、寄存器配置

二、上电驱动流程

三、踩的坑

四、电机寄存器读写

1、写电机寄存器

2、寄存器写入EEPROM固化

3、读取寄存器值

五、代码驱动部分


一、寄存器配置

         首先寄存器配置官方推荐的我驱动不起来,最后用的这一套可以去驱动maxon的微型无刷电机。具体配置的注释在后面代码里有

addressvalue
0X20

0XFC

0X210X98
0X220XBF
0X230X00
0X240X18
0X250XC0
0X260X9D
0X270X7C
0X280X11
0X290X37
0X2A0X0D
0X2B0X2

二、上电驱动流程

三、踩的坑

1、如果你用iic写寄存器去驱动电机速度,就要把speed引脚给悬空,如果接地则转不了,因为speed可以通过输入信号去控制速度。

2、电机的uvw三相,地接上也不能转,这个可能因电机而异,我这个是这样。

四、电机寄存器读写

1、写电机寄存器

2、寄存器写入EEPROM固化

        在加载寄存器之后,下一步是将它们写入EEPROM,这样设备就可以维护这些设置。图中描述了写入EEPROM的命令链。首先,输入程序键(0xB6)在设备控制寄存器(0x02),然后立即,在EEPROM控制寄存器(0x03)中设置eeWrite bit到1(0x50)。如果eeWrite位在程序键进入后没有直接设置,则程序键将被重置。

3、读取寄存器值

        上电默认会将EEPRO里的值刷新到寄存器,写这个寄存器也能刷新

五、代码驱动部分

上述的寄存器读写和固化以及电机驱动代码都已经写好了。

#include <stdio.h>
#include "xparameters.h"
#include "netif/xadapter.h"
#include "xil_printf.h"
#include "sleep.h"
#include "xil_cache.h"
//#include "hdl_ps_iic.h"
#include "hdl_i2cps_polled.h"
#include "motor.h"
#include "data.h"


u8 M1,M2,M3,S1,S2,S3,S4,S5,S6,S7,S8,S9;

static XIicPs I2cInst0;
I2C_ADDR8 I2C_WINST_8ps;
I2C_ADDR8 I2C_RINST_8ps;

/**************************************************
 * 功能:PS IIC初始化

 * 返回值:无
 * 说明: I2C初始化
 ***************************************************/
void IIC_init(void)
{
	u8 n = i2cps_init(&I2cInst0, IIC_DEVICE_ID0, 50*1000);//initial ps i2c controller
}

u8 DRV10983_REG_single_READ(u8 address)//单次读一个寄存器值
{
	//24c02 2kbits read all
			I2C_RINST_8ps.reg_addr=address;
			i2cps_rd8(&I2cInst0, 0x52, &I2C_RINST_8ps, 1);
			return I2C_RINST_8ps.reg_buf;
			//return 0;
}

void DRV10983_REG_single_WRITE(u8 address,u8 Value)//这是用指令进行单次写一个寄存器值,会刷新到eeprom
{
	//使能sidata写位
	I2C_WINST_8ps.reg_addr= EECtrl;
	I2C_WINST_8ps.reg_buf = 0x40;
	i2cps_wr8(&I2cInst0, 0x52, &I2C_WINST_8ps, 1);
	usleep(1000);
	//写寄存器值
	I2C_WINST_8ps.reg_addr= address;
	I2C_WINST_8ps.reg_buf = Value;
	i2cps_wr8(&I2cInst0, 0x52, &I2C_WINST_8ps, 1);
	usleep(1000);
	//写入电机芯片的EEPROM缓存,此后得延时24ms,才能进行新的一次刷新
	I2C_WINST_8ps.reg_addr= DevCtrl;
	I2C_WINST_8ps.reg_buf = 0xB6;
	i2cps_wr8(&I2cInst0, 0x52, &I2C_WINST_8ps, 1);
	usleep(1000);

	I2C_WINST_8ps.reg_addr= EECtrl;
	I2C_WINST_8ps.reg_buf = 0x50;
	i2cps_wr8(&I2cInst0, 0x52, &I2C_WINST_8ps, 1);
	usleep(25000);
}


void IIC_WD(u8 address,u8 Value)//只是往寄存器写,不会刷新到eeprom
{
	I2C_WINST_8ps.reg_addr= address;
	I2C_WINST_8ps.reg_buf = Value;
//	u8 Data;
//	u8 *SendBufferPtr;
//	SendBufferPtr = &I2C_WINST_8ps;
//	Data = *SendBufferPtr;
//	SendBufferPtr += 1;
//	Data = *SendBufferPtr;

	 i2cps_wr8(&I2cInst0, 0x52, &I2C_WINST_8ps, 1);

}

void DRV10983_all_REG_READ(void)//串口打印所有配置寄存器的值
{
	M1=DRV10983_REG_single_READ(MotorParam1);
	M2=DRV10983_REG_single_READ(MotorParam2);
	M3=DRV10983_REG_single_READ(MotorParam3);
	S1=DRV10983_REG_single_READ(SysOpt1);
	S2=DRV10983_REG_single_READ(SysOpt2);
	S3=DRV10983_REG_single_READ(SysOpt3);
	S4=DRV10983_REG_single_READ(SysOpt4);
	S5=DRV10983_REG_single_READ(SysOpt5);
	S6=DRV10983_REG_single_READ(SysOpt6);
	S7=DRV10983_REG_single_READ(SysOpt7);
	S8=DRV10983_REG_single_READ(SysOpt8);
	S9=DRV10983_REG_single_READ(SysOpt9);
//	xil_printf(" MotorParam1-%X\n",M1);
//	xil_printf(" MotorParam2-%X\n",M2);
//	xil_printf(" MotorParam3-%X\n",M3);
//	xil_printf(" SysOpt1-%X\n",S1);
//	xil_printf(" SysOpt2-%X\n",S2);
//	xil_printf(" SysOpt3-%X\n",S3);
//	xil_printf(" SysOpt4-%X\n",S4);
//	xil_printf(" SysOpt5-%X\n",S5);
//	xil_printf(" SysOpt6-%X\n",S6);
//	xil_printf(" SysOpt7-%X\n",S7);
//	xil_printf(" SysOpt8-%X\n",S8);
//	xil_printf(" SysOpt9-%X\n",S9);
}







void motor_initj(void)//竞品配置
{


	IIC_WD(EECtrl, 0x40);//写sidata位
	IIC_WD(MotorParam1, 0XFC);//相间电阻14.8欧姆,驱动电机的输出的频率是50Hz
	IIC_WD(MotorParam2, 0X98);//含有BEMF速度常数14.6mV/Hz,闭环调节模式设置为半周期调节
	IIC_WD(MotorParam3, 0XBF);//换相提前角(供电电压相位提前与BEMF电压)设置为基于供电和电机速度动态匹配
	IIC_WD(SysOpt1, 0X00);//不做初始速度检测ISD,直接跳到判断制动使能,不会做反向驱动
	IIC_WD(SysOpt2, 0X18);//对齐开环电流:0.2A;开环电流上升速率:0.7 VCC/s;关闭制动(no break)
	IIC_WD(SysOpt3, 0XC0);//闭环控制反馈系数:1;开环加速一阶二阶都为最快档位,即最快加速到闭环速度

	IIC_WD(SysOpt4, 0X9D);//电机最大转速的1/3作为进入闭环的阈值速度;对齐时间设置为0.16s
	//异常检测都打开;
	//AVS打开,设置为BEMF电压到达VCC时开启限制降速,此功能作用是当速度急速下降时,电机自己产生的BEMF电压可能会高于VCC;
	//IPD释放模式:循环模式
	IIC_WD(SysOpt5, 0X7C);
	IIC_WD(SysOpt6, 0X11);//加速电流限制阈值0.2A;电流阈值0A:超过则停止转动(没有使能)
	IIC_WD(SysOpt7, 0X37);//闭环加速限制0.77VCC/s;死区时间24V电压建议为400ns,12V电压建议为360ns,我们是8v用的320ns
	IIC_WD(SysOpt8, 0X0D);//关闭初始位置检测;稳压器电压选择3.3V;IPD释放模式为“循环模式”下电流衰减到0的时间:12Hz(没有开启IPD)
	IIC_WD(SysOpt9, 0X2C);//在开环和闭环都输出FG;FG设置为2个周期对应一个脉冲(可以按需设置);异常Kt检测的阈值:2Kt~1/2Kt;速度输入模式为PWM输入;达到速度阈值进入闭环


	//写电机速度
	IIC_WD(0X01,0X80);
	IIC_WD(0X00,0X6F);

	//写入电机芯片的EEPROM缓存,此后得延时24ms,才能进行新的一次刷新
	I2C_WINST_8ps.reg_addr= DevCtrl;
	I2C_WINST_8ps.reg_buf = 0xB6;
	i2cps_wr8(&I2cInst0, 0x52, &I2C_WINST_8ps, 1);
	usleep(10000);

	I2C_WINST_8ps.reg_addr= EECtrl;
	I2C_WINST_8ps.reg_buf = 0x10;
	i2cps_wr8(&I2cInst0, 0x52, &I2C_WINST_8ps, 1);
	usleep(25000);
}


float get_xiafen_speed(void)
{
	u32 speed_r=0;
	float xiafen_speed = 0;
	speed_r = Xil_In32(REG_SPEED);
	if(speed_r == 0)
	{
		xiafen_speed = 0;
	}
	else
	{
		xiafen_speed =  100000000.0/speed_r; //REG_SPEED地址获取的是360度以10ns为单位的时钟数量,也就是一圈的时间
	}
	return xiafen_speed;

}

float get_motor_speed(void)
{
	u16 M1,M2;
	float motorspeed = 0;
	M1=DRV10983_REG_single_READ(0X11);
	M2=DRV10983_REG_single_READ(0X12);
	motorspeed = ((M1<<8)|M2)/40.0;
	return motorspeed;

}

void set_xiafen_speed(float xia_speed)
{

	u16 motor_speed = 0;

	if(xia_speed<0)//设定速率在2~20之间,做一个超值保护
	{
		xia_speed = 0;
	}
	else if(xia_speed>20)
	{
		xia_speed = 20;
	}
	Motor_stru.xiafen_set_speed = xia_speed;
	Motor_stru.flag = 1;
	motor_speed = ((int)(50+xia_speed*20))|0X8000;//计算电机速度,,轮转比为60比11,但是实际跑就是设置250输入给电机驱动芯片,对应就是20Hz
	Motor_stru.reg_data = motor_speed;
	IIC_WD(0X01,motor_speed>>8);
	IIC_WD(0X00,motor_speed);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值