TLE5012的使用和3线SPI通信(SSC)说明

一、TLE5012介绍

        TLE5012是采用巨磁阻原理的15位绝对磁编码器,支持SSC、PWM、IIF、HSM、SPC通信接口,其中SSC是兼容传统SPI的3线接口,通讯频率可达8M。安装方式如下:

TLE5012的使用和3线SPI通信(SSC)说明_第1张图片

二、SSC通信

1、硬件电路连接

        SSC包含3根数据线:DATA、SCK、CSQ。如果单片机的MOSI接口配置为推挽输出,就采用下面的电路:

TLE5012的使用和3线SPI通信(SSC)说明_第2张图片

        如果单片机的MOSI接口配置为开漏输出,就采用下面的电路:

TLE5012的使用和3线SPI通信(SSC)说明_第3张图片

2、SSC读写数据帧的组成

TLE5012的使用和3线SPI通信(SSC)说明_第4张图片

       如上图,数据帧由3部分组成:COMMAND、Data、SAFETY-WORD。

1)、COMMAND

TLE5012的使用和3线SPI通信(SSC)说明_第5张图片

TLE5012的使用和3线SPI通信(SSC)说明_第6张图片

        COMMAND是每帧数据的开头。TLE5012B寄存器中的位有3种操作标志:r、w、u。r代表该位可以读,w代表该位可以写,u代表该位带有update buffer功能。

TLE5012的使用和3线SPI通信(SSC)说明_第7张图片

        当你要在同一个时间读多个寄存器的值,因为通讯过程也有时间,这就会导致读取到的多个寄存器实际上并不是同一个时间的。update buffer功能就应运而生。你只需要在开始读寄存器前发送一个Update-Signal(把CSQ拉低tCSupdate时间),TLE5012E就会把具有update buffer功能的寄存器的值更新到update buffer中,然后你把COMMAND中的UPD设置为1,就会去读相应寄存器的update buffer值。无论你等多久去读,update buffer中的值都是你发送Update-Signal时的值,直到你再次发送Update-Signal,update buffer中的值才会更新。

TLE5012的使用和3线SPI通信(SSC)说明_第8张图片

2)、Data

        读数据或写数据操作的数据内容。

3)、SAFETY-WORD

TLE5012的使用和3线SPI通信(SSC)说明_第9张图片

        当发生错误,SAFETY-WORD中对应的位会拉低,直到通过SSC接口读取了STAT(地址0)寄存器,读完后,SAFETY-WORD中对应的位会自动拉高。

3、读写示例

TLE5012的使用和3线SPI通信(SSC)说明_第10张图片

TLE5012的使用和3线SPI通信(SSC)说明_第11张图片

TLE5012的使用和3线SPI通信(SSC)说明_第12张图片

三、程序

        程序中需要注意的是,因为MOSI和MISO共用一根线,因此当主机通过DATA线传完数据后,要把DATA线配置为输入模式,释放DATA线的控制权,让从机可以控制DATA线。否则,主机对于DATA线一直是推挽输出模式,从机是改变不了DATA线的电平的。

#define READ_STATUS 0x8001      //8000
#define READ_ANGLE_VALUE 0x8021 //8020
#define READ_SPEED_VALUE 0x8031 //8030
#define SPI_TX_OFF {GPIOA->CRL&=0x0FFFFFFF;GPIOA->CRL|=0x40000000;}//把PA7(MOSI)配置成开漏--输入模式
#define SPI_TX_ON  {GPIOA->CRL&=0x0FFFFFFF;GPIOA->CRL|=0xB0000000;}//把PA7(MOSI)配置成推挽--输出模式(50MHz)

void SPI1_Init(void)
{
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1,ENABLE );

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PA5--CLK--复用推挽
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;   //PA6--MISO--输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//PA7--MOSI--推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;       //PA8--CS--推挽输出
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIO_CS_Pin_Type, &GPIO_InitStructure);

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI1--双线全双工!!
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init(SPI1, &SPI_InitStructure);
	SPI_Cmd(SPI1, ENABLE);
}

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u16 SPI1_ReadWriteByte(u16 TxData)
{
	u8 retry=0;
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) { //检查指定的SPI标志位设置与否:发送缓存空标志位
		retry++;
		if(retry>200)return 0;
	}
	SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
	retry=0;

	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) { //检查指定的SPI标志位设置与否:接受缓存非空标志位
		retry++;
		if(retry>200)return 0;
	}
	return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}

uint16_t ReadValue(uint16_t u16RegValue)
{
	uint16_t u16Data;

	SPI_CS_ENABLE;
	SPI1_ReadWriteByte(u16RegValue);
	SPI_TX_OFF;

	u16Data = ( SPI1_ReadWriteByte(0xffff) & 0x7FFF ) << 1;//0x12/0xff*100k
	SPI_CS_DISABLE;
	SPI_TX_ON;
	return(u16Data);
}

//得到 0~359 度
uint16_t ReadAngle(void)
{
    return ( ReadValue(READ_ANGLE_VALUE) * 360 / 0x10000 );
}

 

你可能感兴趣的:(器件&传感器,电机,驱动器,编码器)