DRV8711的通用步进电机驱动器和直流电机驱动器

芯片说明

DRV8711 是一款步进式电机控制器,此控制器使用外部 N 通道 MOSFET 来驱动一个双极步进式电机或两个有刷直流电机。 集成了一个微步进分度器,此分度器能够支持全步长至 1/256 步长的步进模式。
通过使用自适应消隐时间和包括自动混合衰减模式在内的多种不同的电流衰减模式,可实现非常平滑的运动系统配置。 电机停止转动由一个可选反电势 (EMF) 输出报告。
一个简单的步进/方向或脉宽调制 (PWM) 接口可轻松连接至控制器电路。 一个 SPI 串行接口被用来设定器件运行。 输出电流(扭矩)、步进模式、衰减模式和停止转动检测功能都可通过 SPI 串行接口进行编程。

1.先上原理图做一个简易的电路板

在这里插入图片描述

2.程序代码部分,结合手册中的寄存器看看寄存器有哪些说明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

写“0”清除故障
在这里插入图片描述

3.代码有着注释就不讲了

#ifndef __drv8711_driver_H__
#define __drv8711_driver_H__
/*
移植时头文件使用说明:
1.改SPI管脚定义和电机管脚定义;
2.根据应用设置运行模式是驱动直流电机还是步进电机;
3.一共三个APP接口函数,改完硬件配置,调用初始化,就可以调用接口函数设置电流等功能;
4.操作相应的管脚驱动电机.
//app接口
int Drv8711_init(u8 Mode,u8 Microstep,float Stepper_current,u8 Attenuation);
void Drv8711set_current(float Current);        //设置DRV8711驱动器步进电机电流 
void Drv8711read_current(float Current);			 //读取DRV8711驱动器步进电机电流
*/
#include <stm32f10x.h>
//宏定义区
//SPI硬件引脚宏
#define DRV8711_SPI                         SPI2
#define DRV8711_SPI_GPIO                    GPIOB
#define DRV8711_SPI_CLK                     RCC_APB1Periph_SPI2

#define DRV8711_SPI_SCK_CLK                 RCC_APB2Periph_GPIOB    
#define DRV8711_SPI_SCK_PIN                 GPIO_Pin_13

#define DRV8711_SPI_MISO_CLK                RCC_APB2Periph_GPIOB    
#define DRV8711_SPI_MISO_PIN                GPIO_Pin_14

#define DRV8711_SPI_MOSI_CLK                RCC_APB2Periph_GPIOB    
#define DRV8711_SPI_MOSI_PIN                GPIO_Pin_15

#define DRV8711_SPI_CS_CLK                  RCC_APB2Periph_GPIOB    
#define DRV8711_SPI_CS_PIN                  GPIO_Pin_12

#define SPI_FLASH_CS0_LOW()       GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define SPI_FLASH_CS0_HIGH()      GPIO_SetBits(GPIOB, GPIO_Pin_12)

//直流电机管脚宏

//步进电机管脚宏

#define DC_MOTOR      0
#define STEPPER_MOTOR 1
#define MAXSIZE 1
//细分宏
#define  STEP_4   2
#define  STEP_8   3
#define  STEP_16  4
#define  STEP_32  5
#define  STEP_64  6
#define  STEP_128 7
#define  STEP_256 8


#define CURRENT_MAX 3 //HH
#define R_ISGAIN 0.22 //采样电阻值
//寄存器地址
#define  STATUS_ADDR  0x07  
#define  DRIVE_ADDR   0x06 
#define  DECAY_ADDR   0x04 
#define  BLANK_ADDR   0x03  
#define  OFF_ADDR     0x02 
#define  TORQUE_ADDR  0x01
#define	 CTRL_ADDR    0x00   

 /**
  * 函数功能: Drv8711芯片初始化,完成spi接口配置和参数初始化,调用初始化之前先修改.h文件使用的硬件管脚宏
  * 输入参数1: mode 驱动器模式选择 ; 0=直流电机;1=步进电机;
  * 输入参数2: Microstep 步进电机细分;4~256细分,在.h里面宏定义	
  * 输入参数3: Stepper_current 步进电机电流;//最大值要补充上
	* 输入参数4: Attenuation 步进电机衰减模式 //衰减模式宏也要加上去
  * 返 回 值: >0正确;<0错误
  * 说    明:无
  */
//app接口
int Drv8711_init(u8 Mode,u8 Microstep,float Stepper_current,u8 Attenuation);
void Drv8711set_current(float Current);        //设置DRV8711驱动器步进电机电流 
void Drv8711read_current(float Current);			 //读取DRV8711驱动器步进电机电流
//底层函数
void Drv8711mode_mots(u8 Mode,u8 Step,float Current,u8 Attenuation);//DRV8711驱动器初始化
void Spi_configuration(void);						//配置SPI2通讯协议初始化
u8 Spi_flash_sendbyte(u8 Byte);						//SPI2外设发送与接收数据
u16 Spi_drv8711_read(u8 Addr);						//DRV8711读取数据
void Spi_drv8711_write(u8 Addr,u16 Data);	//DRV8711写入数据
#endif




#include "drv8711_driver.h"
#include <stdlib.h>
#include <stdio.h>
/*
 * 说    明:
 * 本参数为默认属性赋值,基本上只需更改OFF 寄存器就可驱动直流或步进
 * 如需改动需要配合DRV8711产品说明文档调配 页面P25
 *  
 */
 
//变量定义区

//CTRL 寄存器
u16 RDIR  = 0x0001 | (1<<1); 			 		//1为顺时针方向旋转
u16 DTIME  = 0x0001 | (3<<10);		 	  //死区时间设置
//TORQUE 寄存器
u16 TORQUE = 0x0000 | 0xFF; 					//输出电流比例,用于计算设置电流的参数
u16 SMPLTH = 0x0000 | (1<<8);  			 //反电动势采样时间
//OFF 寄存器
u16 TOFF = 0x0000;										//设置MOS管固定关闭时间------------衰减模式下可用到,可保持默认状态
u16 PWMMODE = 0x0000 | (1<<8);				//0为步进电机模式  或  1为直流电机模式
//BLANK 寄存器
u16 TBLANK = 0x0040;									//设置MOS管固定打开时间------------衰减模式下可用到,可保持默认状态
u16 ABT = 0x0000 | (0<<8);						//blanjing时间自适应
//DECAY 寄存器
u16 TDECAY = 0x0010;								//混合衰减模式转换时间------------衰减模式下可用到,可保持默认状态
u16 DECMOD = 0x0000 | (5<<8);				//电流衰减模式,此处使用自动混合衰减
//DRIVE 寄存器
u16 OCPTH    = 0x0000| (0<<0);				//过流检测门限
u16 OCPDEG   = 0x0000| (1<<2);				//过流误动作防止时间
u16 TDRIVEN  = 0x0000| (1<<4);				//低侧棚极驱动时间
u16 TDRIVEP  = 0x0000| (1<<6);				//高侧棚极驱动时间
u16 IDRIVEN  = 0x0000| (1<<8);				//低侧棚极驱动峰值电流
u16 IDRIVEP  = 0x0000| (1<<10);		  	//高侧棚极驱动峰值电流
//STATUS 寄存器
u16 STATUS_Register = 0x0000; 				//清除所有异常故障包括过温、过流


u16 Ctrl_register   = 0xFFFF;  	//CTRL集合
u16 Torque_register =	0xFFFF;	 //TORQUE集合
u16 Off_register    = 0xFFFF;		//OFF集合
u16 Blank_register  = 0xFFFF;		//BLANK集合
u16 Decay_register  = 0xFFFF;	//DECAY集合
u16 Drive_register  = 0xFFFF;		//DRIVE集合
u16 Drv8711_model   =  0x0001 | (5<<3);  //步进细分设置为32 
u16 Drv8711_isgain  = 0x0001 | (0<<8);			   //电流采样增益,用于计算设置电流的参数
//APP函数
 /**
  * 函数功能: Drv8711芯片初始化,完成spi接口配置和参数初始化,调用初始化之前先修改.h文件使用的硬件管脚宏
  * 输入参数1: mode 驱动器模式选择 ; 0=直流电机;1=步进电机;
  * 输入参数2: Microstep 步进电机细分;4~256细分,在.h里面宏定义	
  * 输入参数3: Stepper_current 步进电机电流;//最大值要补充上
	* 输入参数4: Attenuation 步进电机衰减模式 //衰减模式宏也要加上去
  * 返 回 值: >0正确;<0错误
  * 说    明:无
  */
int Drv8711_init(u8 Mode,u8 Microstep,float Stepper_current,u8 Attenuation)
{
	if(Mode>1)
	{
	  return -1;
	}
	if(Stepper_current>CURRENT_MAX)
	{
	  Stepper_current = CURRENT_MAX;
	}
	
  Spi_configuration();
  Drv8711mode_mots(Mode,Microstep,Stepper_current,Attenuation);
}
 /**
  * 函数功能: DRV8711驱动器设置电流大小
  * 输入参数: current;步进电机电流
  * 返 回 值: 无
  * 说    明:无
  */
void Drv8711set_current(float Current)
{
	unsigned int Set_current =255;
	 Set_current =(unsigned int)((256*5*R_ISGAIN)*Current)/2.75;
	 Torque_register = Set_current; 				//输出电流比例,用于计算设置电流的参数
   Spi_drv8711_write(0x01,Torque_register);  //TORQUE   
   Spi_drv8711_write(0x00,Ctrl_register);    //CTRL
}

 /**
  * 函数功能: DRV8711驱动器读取电流大小
  * 输入参数: current;返回当前步进电机电流
  * 返 回 值: 无
  * 说    明:无
  */
void Drv8711read_current(float Current)
{
	float data = 0;
	data= (float)(Spi_drv8711_read(0x01) & 0xFF);
	Current =(unsigned int) ((data*2.75)/(256*5*R_ISGAIN));
}

 /**
  * 函数功能: 配置SPI通讯协议初始化
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void Spi_configuration(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );		//PORTB时钟使能 
	RCC_APB1PeriphClockCmd(	DRV8711_SPI_CLK,  ENABLE );		//SPI2时钟使能 	
 
	GPIO_InitStructure.GPIO_Pin = DRV8711_SPI_SCK_PIN | DRV8711_SPI_MISO_PIN | DRV8711_SPI_MISO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        		//PB13/14/15复用推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DRV8711_SPI_GPIO, &GPIO_InitStructure);								 		//初始化DRV8711_SPI_GPIO

 	GPIO_SetBits(DRV8711_SPI_GPIO,DRV8711_SPI_SCK_PIN|DRV8711_SPI_MISO_PIN|DRV8711_SPI_MISO_PIN);  //PB13/14/15上拉

	GPIO_InitStructure.GPIO_Pin = DRV8711_SPI_CS_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 				  //PB13/14/15复用推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DRV8711_SPI_GPIO, &GPIO_InitStructure);										//初始化DRV8711_SPI_GPIO
	
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;							//设置SPI工作模式:设置为主SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;					//设置SPI的数据大小:SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;								//串行同步时钟的空闲状态为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;							//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;									//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;		//STM32的SPI1用APB2的72MHz,TMC5130手册里P23指出TMC5130的SPI时钟不能超过4MHz和8MHz,所以注意此处的分频值 
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;				//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
//	SPI_InitStructure.SPI_CRCPolynomial = 7;								//CRC值计算的多项式
	SPI_Init(DRV8711_SPI, &SPI_InitStructure);  											//根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(DRV8711_SPI, ENABLE); 																		//使能SPI外设
}



 /**
  * 函数功能: DRV8711驱动器设置为直流电机或步进电机模式
  * 输入参数: mode;驱动器模式选择 step;步进电机细分;步进电机电流 attenuation;步进电机衰减模式
  * 返 回 值: 无
  * 说    明:
  *          选择直流电机模式时后面参数克忽略
  *          步进电机电流的幅值为:(2.75*ISGAIN[取值0~FF])/(255*ISGAIN[电流增益为5]*0.22[采样电阻值])用采样电阻0.22R最大电流为2.5A
  *          衰减模式有六种选择:1.一直慢衰减 2.电流增加时使用慢衰减,电流减少时使用混合衰减 3.一直快衰减 4.开始为快衰减,TDECAY时间后转为慢衰减 
  *          5.电流增加时使用慢衰减,电流减少时使用自动混合衰减 6.。。。。.
  */
void Drv8711mode_mots(u8 Mode,u8 Step,float Current,u8 Attenuation)
{
    unsigned int Set_current =255;
	
		if (Mode == DC_MOTOR)
		{
			PWMMODE = 0x0000 | (1<<8);	
		}
     else if(Mode ==STEPPER_MOTOR)
				{
					PWMMODE = 0x0000 | (0<<8);
				//步进电机细分
							 switch(Step)
							 {
								 case STEP_4 : 
														Drv8711_model = 0x0001 | (2<<3);
								 break;
				        //细分4
								 case STEP_8 : 
														Drv8711_model = 0x0001 | (3<<3); 
								 break;		
				         //细分8				 
								 case STEP_16 : 
														Drv8711_model = 0x0001 | (4<<3);
								 break;	
				         //细分16				 
								 case STEP_32 : 
														Drv8711_model = 0x0001 | (5<<3);
								 break;	
				         //细分32 
								 case STEP_64 : 
														Drv8711_model = 0x0001 | (6<<3);
								 break;				
				         //细64 				 
								 case STEP_128 : 
														Drv8711_model = 0x0001 | (7<<3);
								 break;		
				         //细分128 					 
								 case STEP_256 : 
														Drv8711_model = 0x0001 | (8<<3);
								 break;		
				         //细分256 
								 default:
									 
								 break;					 			 
							 }

							//步进电机电流
							Set_current =(unsigned int)((256*5*R_ISGAIN)*Current)/2.75;
							Drv8711_isgain = 0x0001 | (0<<8);			//电流采样增益,用于计算设置电流的参数
							//TORQUE = Set_current; 				//输出电流比例,用于计算设置电流的参数
						//步进电机衰减模式 
							//DECMOD = 0x0000 | (Attenuation<<8);				//电流衰减模式,此处使用自动混合衰减			 
				}
				Ctrl_register =  Drv8711_model | Drv8711_isgain | DTIME |RDIR ;  	//CTRL集合
				Torque_register = Set_current|SMPLTH;
				Off_register = PWMMODE | TOFF;		//OFF集合
				Blank_register = TBLANK | ABT;		//BLANK集合
				Decay_register = TDECAY | 0x0000 | (Attenuation<<8);	//DECAY集合
				Drive_register = OCPTH | OCPDEG | TDRIVEN | TDRIVEP | IDRIVEN | IDRIVEP;		//DRIVE集合

				 Spi_drv8711_write(STATUS_ADDR,STATUS_Register);  //STATUS	
				 Spi_drv8711_write(DRIVE_ADDR,Drive_register);   //DRIVE   
				 Spi_drv8711_write(DECAY_ADDR,Decay_register);   //DECAY
				 Spi_drv8711_write(BLANK_ADDR,Blank_register);   //BLANK	
				 Spi_drv8711_write(OFF_ADDR,Off_register);  	 //OFF				
				 Spi_drv8711_write(TORQUE_ADDR,Torque_register);  //TORQUE      
				 Spi_drv8711_write(CTRL_ADDR,Ctrl_register);    //CTRL
}

 /**
  * 函数功能: SPI2外设发送与接收数据
  * 输入参数: 要发送的数据
  * 返 回 值: 接收的数据
  * 说    明:无
  */
u8 Spi_flash_sendbyte(u8 Byte)
{
  /* 检测发送数据通道是否空闲状态,一直等待中 */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

  /* 发送一个数据 */
  SPI_I2S_SendData(SPI2, Byte);

  /* 检测接收数据通道是否空闲状态,一直等待中 */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

  /* 返回最近接收的数据 */
  return SPI_I2S_ReceiveData(SPI2);
}

 /**
  * 函数功能: DRV8711读取数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:DRV8711驱动器以低11位数据结构、高4位地址结构格式进行访问
  */
u16 Spi_drv8711_read(u8 Addr)
{
  u8 Temp = 0, Temp0 = 0, Temp1 = 0;
  u16 Temp2;
  //使能DRV8711的SPI通讯引脚 
  SPI_FLASH_CS0_HIGH();
  Temp=(0x08|Addr)<<4;	
  /* Read a byte from the FLASH */
  Temp0 = Spi_flash_sendbyte(Temp);
  /* Read a byte from the FLASH */
  Temp1 = Spi_flash_sendbyte(0xff);
  /* 失能DRV8711的SPI通讯引脚 */
  SPI_FLASH_CS0_LOW();

  Temp2 = ( (Temp0&0x0f)<<8 ) | Temp1;

  return Temp2;
}
 /**
  * 函数功能: DRV8711写入数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:DRV8711驱动器以低11位数据结构、高4位地址结构格式进行访问
  */
void Spi_drv8711_write(u8 Addr,u16 Data)
{
  u8 Temp = 0;
  /* 使能DRV8711的SPI通讯引脚 */
  SPI_FLASH_CS0_HIGH();
//  SPI_FLASH_CS1_HIGH();

  Temp=((Data>>8)&0x0f)	| (Addr<<4);
  Spi_flash_sendbyte(Temp);
	
  Temp=(u8)(Data&0x00ff);	
  Spi_flash_sendbyte(Temp);	
	
  /* 失能DRV8711的SPI通讯引脚 */
  SPI_FLASH_CS0_LOW();
}



Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐