TRINAMIC旗下的TMC5130和TMC5130步进电机测试deom

专注于运动控制的品牌: TRINAMIC
旗下产品芯片:TMC5130

注意手册文档中SPI时钟不能超过4MHz和8MHz,所以注意此处的分频值

编程要点:
1.初始化STM32的相关引脚的I/O口,配置所需要的要用到的SPI相关配置信息
2.初始化SPI相关引脚设置为复用功能及SPI的配置与步进电机芯片时序相匹配
3.注意到手册里P23指出TMC5130的SPI时钟不能超过4MHz和8MHz,所以在SPI配置中一项
(SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32 )
4.TMC5130是以40bit为一帧的数据方式传输,数据结构为高8位为地址和低32位为数据
5.由于STM32SPI硬件限定都是以8bit数据传输方式,我们可通过组合方式将5组8bit一块打包发送过去
6.这里也要注意手册中描述了将0x80添加到地址Addr,用于写入访问,所以在手册中寻找相应的地址的时候要将其相加。
7.以下为修改步进电机寄存器中的值:

sendData(0xEC,0x000101D5) 手册中的地址:0x6C 驱动程序寄存器集:CHOPCONF: TOFF=5, HSTRT=5, HEND=3, TBL=2, CHM=0
TOFF: 关闭时间设置控制缓慢衰减阶段的持续时间
在这里插入图片描述
HSTRT: 快速衰减时间设置
在这里插入图片描述
HEND : 斩波器的磁滞值
在这里插入图片描述
TBL: 空白时间选择
在这里插入图片描述
CHM:直升机模式
在这里插入图片描述

在这里插入图片描述
sendData(0xA4,0x000003E8) 手册中的地址:0x24----初次启动和V1之间的第一次加速度 (V1为初速度与最高末速度的中间速度)
sendData(0xA5,0x000386A0) 手册中的地址:0x25----第一加速/减速相位阈值速度
sendData(0xA6,0x00002710) 手册中的地址:0x26----V1和VMAX之间的第二次加速度 这是速度模式的加速和减速值(VMAX最高末速度)
sendData(0xA7,0x000386A0) 手册中的地址:0x27----运动斜坡目标速度(定位确保VMAX≥VSTART) 这是速度模式下的目标速度。 它可以在运动中随时改变
上面与另外一个信号一样

sendData(0xAA,0x00000578)   手册中的地址:0x2A----在V1和VSTOP之间减速
sendData(0xAB,0x0000000A)   手册中的地址:0x2B---- 马达停止速度
sendData(0xA0,0x00000001)    手册中的地址:0x20---- 四个选项 1.定位模式 2. 速度模式为正VMAX 3. 速度模式为负VMAX 4.保持状态
sendData(0x94,0x00000050)     手册中的地址:0x14---- 这是较低的阈值速度切换智能能量冷却步骤和失速保护功能
sendData(0xED,0x007E8000)   手册中的地址:0x6D---- 酷步智能电流控制寄存器和失速Guard2配置
sendData(0xB4,0x00000400)   手册中的地址:0x34---- 切换模式配置

在手册中的72页中,官方提供了一部分初始化例程
在这里插入图片描述
通过上述给出的指令信息进行配置可将步进驱动器的动作动起来

上代码不过是进行了一组测试

2.SPI总线实现驱动器芯片配置信息

#include "bsp_spi.h"

//使用SPI2进行通信配置相关信息
//MOSI-PB15		MISO-PB14		SCK-PB13		NSS-PB12
void SPI1_Configuration(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;
  	SPI_InitTypeDef  SPI_InitStructure;

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

 	GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉
	
	//SPI使能信号使用软件的方式控制
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //PB13/14/15复用推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
	
	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_16;		//STM32的SPI2用APB2 这里我直接使用最低的频率,TMC5130手册里P23指出TMC5130的SPI时钟不能超过4MHz和8MHz,所以注意此处的分频值
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 一般情况下都是以从高位传输数据
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
	SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI2, ENABLE); //使能SPI外设
}


void SPI_SendByte(char data) 
{ 
	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //检查发送是否完成,完成以后再发送数据
	SPI_I2S_SendData(SPI2, data); //发送数据

	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); //检查接受标志位,是否可以接受
	SPI_I2S_ReceiveData(SPI2); //接收数据
}

char SPI_ReceiveByte(void)
{ 
	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //检查发送是否完成,完成以后再发送数据
	SPI_I2S_SendData(SPI2, 0x0); //发送数据

	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); //检查接受标志位,是否可以接受
	return SPI_I2S_ReceiveData(SPI2); //接收数据
}

//TMC5043 takes 40 bit data: 8 address and 32 data
//由于STM32SPI硬件限定都是以8bit或16bit数据传输方式,我们可通过组合方式将5组8bit一块打包发送过去
//为了区分地址与数据的结构也方便阅读与修改进行封装函数
void sendData(unsigned long address, unsigned long datagram)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET);  	//SPI_CS片选拉低
	
	SPI_SendByte(address);
	SPI_SendByte((datagram >> 24) & 0xff);
	SPI_SendByte((datagram >> 16) & 0xff);
	SPI_SendByte((datagram >> 8) & 0xff);
	SPI_SendByte(datagram & 0xff);
	
	GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET);  	//SPI_CS片选拉高
}

unsigned long ReadData(unsigned long address)
{
	char data[4] = {0, 0, 0, 0};
	unsigned long datagram = 0;
	
	GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET);  	//SPI_CS片选拉低
	
	SPI_SendByte(address);
	data[0] = SPI_ReceiveByte();//SPI_ReceiveByte((datagram >> 24) & 0xff);
	data[1] = SPI_ReceiveByte();//SPI_ReceiveByte((datagram >> 16) & 0xff);
	data[2] = SPI_ReceiveByte();//SPI_ReceiveByte((datagram >> 8) & 0xff);
	data[3] = SPI_ReceiveByte();//SPI_ReceiveByte(datagram & 0xff);
	
	datagram = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
	
	GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET);  	//SPI_CS片选拉高
	
	return datagram;
}


#include <stdio.h>
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "timer.h"
#include "beep.h"
#include "bsp_spi.h"


#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);                    //使能串口 

/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure); 

	GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET);  	//SPI_CS片选拉高
	GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);  //DRV_ENN拉低使能
	
	
	SPI1_Configuration();


	LED_Init();//LED初始化
  KEY_Init();//按键初始化
  SysTick_Init();//延时初始化
	BEEP_Init();   //蜂鸣器初始化
	printf("\n\rUSART Printf Example: 开发板串口测试程序\r输入任何信息发送,接收到同样信息");
	
//使用SPI通信一直走行程 通过以下配置信息可以让步进电机一直运动
//		sendData(0xA4,0x000003E8);
//		sendData(0xA5,0x0000C350);
//		sendData(0xA6,0x000001F4);
//		sendData(0xA7,0x000304D0);
//		sendData(0xA8,0x000002BC);
//		sendData(0xAA,0x00000578);
//		sendData(0xAB,0x0000000A);
//		sendData(0xA0,0x00000000);
//		
//		sendData(0xAD,0xFFFF3800);
	
	
//	sendData(0xEC,0x000101D5); //CHOPCONF: TOFF=5, HSTRT=5, HEND=3, TBL=2, CHM=0 (spreadcycle)
//	sendData(0x90,0x00071402); //IHOLD_IRUN: IHOLD=3, IRUN=10 (max.current), IHOLDDELAY=6   //备用值:0x00071402

//  sendData(0xA4,0x000003E8);     	//A1=1000
//  sendData(0xA5,0x000386A0);     	//V1=100000
//  sendData(0xA6,0x00002710);     	//AMAX=50000        //备用值:0x00002710
//  sendData(0xA7,0x000386A0);     	//VMAX=100000       //备用值:
//  sendData(0xAA,0x00000578);     	//D1=1400
//  sendData(0xAB,0x0000000A);     	//VSTOP=10
//	sendData(0xA0,0x00000001); 			//RAMPMODE=1   速度模式
//	sendData(0x94,0x00000050); 			//读取0x14寄存器,其值需要大于0x12寄存器的值才能让电机停止
//	

//	sendData(0xED,0x007E8000);     //备用值?
//	sendData(0xB4,0x00000400);     //设置使能sg_stop,使能之后,当SG_RESULT为0时电机会自动停止,实现想要的功能
//	
//	sendData(0xAD,0xFFFF3800);


//使用SPI通信一直走行程 通过以下配置信息可以让步进电机一直运动
	sendData(0x80,0x00000008);
	sendData(0xEC,0x000100C5);
	sendData(0xB0,0x00011F05);
	sendData(0xAC,0x00002710);
	sendData(0x90,0x000401C8);
	sendData(0xB2,0x00061A80);
	sendData(0xB1,0x00007530);
	sendData(0xA6,0x00001388);
	sendData(0xA7,0x00004E20);
	sendData(0xA0,0x00000001);
	
	sendData(0x21,0x00000000);
	
	
  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;
}
  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

谢谢~谢先生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值