IC-MU128编码器使用教程

IC-MU128磁编码器芯片通信验证_ic-mu200-CSDN博客文章浏览阅读428次。该芯片是使用BISS或者SPI去通信的。由于我使用的是STM32作为MCU,所以只能使用SPI去通信。从手册上面了解到的是该款芯片是只支持SPI0和SPI3模式。目前的话我使用的是软件SPI去验证通信的,没有使用硬件SPI的原因很简单,硬件工程师那边画错了。由于目前我还不是很熟悉这款芯片,等后面供应商过来校准后,开发更详细的资料后,后续我还会再写一篇文档补充,目前只是记录一下如何验证该款芯片的通信。目前和供应商那边沟通的情况是,SPI通信波特率小于10Mbit即可,具体多少手册上面也没有写。_ic-mu200https://blog.csdn.net/m0_74541086/article/details/159566708?spm=1001.2014.3001.5501

之前写的这篇文档只是简单验证一下IC-MUx的使用。并没有深入的去了解这款芯片,说实战话,供应商的技术支持是真的不行(简单吐槽一下)。搞的我这边不得不使用逻辑分析器去抓取上位机的数据进行验证。

(1)激活操作功能:在出始化的阶段需要通过ACTIVATE去激活芯片。通过发送0xB0、0x83去激活芯片,芯片会返回0xB0、0x20进行应答。

手册上面没有提到与ACTIVATE register相关的任何操作。所以具体应该写那边位去激活芯片也不明确。

文档中提到,如果不激活芯片的情况下去通讯,Read REGISTER (single), Write REGISTER (single),SDAD status and SDAD transmission都会导致REGISTER status/data里面的ERROR bit会报错。

ACTIVATE激活之后,0xAD里面的低四位会重新置位(清0)。

(2)读取寄存器状态。每次进行SPI操作的时候都需要进行状态访问来查看上一次的访问是否失败

通过OPCODE = 0xAD。一般是0xAD、0x00、0x00。

返回0xAD、0x01、0x0。其中0x1表示VALID = 1,表示上一次的数据是有效的。其中0x00的表示读取到的数据(读寄存器操作才会有效)。

**(3)写寄存器操作功能:**写寄存器的OPCODE是0xD2。指令:OPCODE + ADDR + CODE。

比如软件复位是0xD2、0x75、0x07就是对应写寄存器,写地址0x75,写命令是0x07是软复位操作。通过0xAD、0x00、0x00来判断写操作是否生效。比如返回了0xAD、0x01、0x0。

(4)读寄存器操作功能:读寄存器的OPCODE是0x97,指令:OPCODE + ADDR

比如:0x97+0x74去获取编码器的型号,然后通过0xAD、0x00、0x00来查看读操作是否生效和获取数据。返回数据是0xAD、0x01、0x15。

下面的代码仅供参考:

复制代码
uint8_t wdata[4]  = {0xA6,0xFF,0xFF,0xFF};
uint8_t rHdata[4] = {0};
uint8_t rLdata[4] = {0};

uint32_t EncoderFault;

static void spi_xfer(SPI_HandleTypeDef *hspi, uint8_t *txbuf, uint8_t *rxbuf, uint16_t size, uint32_t wait_ms)
{
	if(hspi->Instance == SPI1)
	{
		SPI1_CS_L;
		HAL_SPI_TransmitReceive(hspi, txbuf, rxbuf, size, 2);
		SPI1_CS_H;
	}
	
	if(hspi->Instance == SPI2)
	{
        SPI2_CS_L;
		HAL_SPI_TransmitReceive(hspi, txbuf, rxbuf, size, 2);
        SPI1_CS_H;
	}
	
	if(wait_ms) HAL_Delay(wait_ms);
}

static bool icmu_activate(SPI_HandleTypeDef *hspi)
{
	bool ret = false;
	uint8_t txbuf[2] = {0xB0, 0x83}, rxbuf[2] = {0};
	for(uint8_t i = 0; i < 3 ; i++)
	{
		spi_xfer(hspi, txbuf, rxbuf, 2, 1);
		if(rxbuf[1] == 0x20)
		{
			ret = true;
			break;
		}
		HAL_Delay(1);
	}
	return ret;
}

static bool icmu_read_reg(SPI_HandleTypeDef *hspi, uint8_t addr, uint8_t *rxbuf)
{
	bool ret = false;
	uint8_t txbuf1[2] = {0x97, addr}, rxbuf1[2] = {0};
  uint8_t txbuf2[3] = {0xAD, 0x00, 0x00}, rxbuf2[3] = {0};
	
	spi_xfer(hspi, txbuf1, rxbuf1, 2, 1);
	
	for(uint8_t i = 0; i < 3 ; i++)
	{
		spi_xfer(hspi, txbuf2, rxbuf2, 3, 1);
		
		if(rxbuf2[1] & 0x0C)
			return false;
		
		if(rxbuf2[1] & 0x02)
			continue;
		
		if(rxbuf2[1] & 0x01)
		{
			ret = true;
			break;
		}
	}
	
	*rxbuf = rxbuf2[2];
	
  return ret;
}


static bool icmu_write_reg(SPI_HandleTypeDef *hspi, uint8_t addr,uint8_t data,uint8_t *rxbuf)
{
	bool ret = false;
	uint8_t txbuf1[3] = {0xD2, addr,data}, rxbuf1[3] = {0};
  uint8_t txbuf2[3] = {0xAD, 0x00, 0x00}, rxbuf2[3] = {0};
	
	spi_xfer(hspi, txbuf1, rxbuf1, 3, 1);
	
	for(uint8_t i = 0; i < 3 ; i++)
	{
		spi_xfer(hspi, txbuf2, rxbuf2, 3, 1);
		
		if(rxbuf2[1] & 0x0C)
			return false;
		
		if(rxbuf2[1] & 0x02)
			continue;
		
		if(rxbuf2[1] & 0x01)
		{
			ret = true;
			break;
		}
	}
	
	*rxbuf = rxbuf2[2];
	
	return ret;
}

static bool soft_reset(SPI_HandleTypeDef *hspi)
{
	bool ret = false;
	uint8_t rxbuf;
	
	if(icmu_write_reg(hspi,0x75,0x07,&rxbuf))
	{
		if(rxbuf == 0x07)
		{
			ret = true;
		}
	}
	
	return ret;
}

static void Encoder1_Init(void)
{
	uint8_t rxbuf;
	uint8_t i;
	
	for(i = 0; i < 3; i++)
	{
		if(!icmu_activate(&hspi1))
		{
			EncoderFault |= 0x00000080;
			return;
		}
		
		if(icmu_read_reg(&hspi1,0x76,&rxbuf))
		{
			if(rxbuf != 0x00)
			{
				if(rxbuf & 0x10)
					EncoderFault |= 0x00000001;
				
				if(rxbuf & 0x0F)
					EncoderFault |= 0x00000002;
			}
			rxbuf = 0x00;
		}
		if(icmu_read_reg(&hspi1,0x77,&rxbuf))
		{
			if(rxbuf != 0x0)
			{
				if(rxbuf & 0x37)
					EncoderFault |= 0x00000004;
				
				if(rxbuf & 0x08)
					EncoderFault |= 0x00000008;
				
				if(rxbuf & 0x40)
					EncoderFault |= 0x00000010;
				
				if(rxbuf & 0x80)
					EncoderFault |= 0x00000020;
				
			}
			rxbuf = 0x00;
		}
		
		if(EncoderFault == 0x1)
		{
			if(soft_reset(&hspi1))
				EncoderFault = 0;
			else
				EncoderFault |= 0x00000040;
		}
		else if(EncoderFault == 0x0)
		{
			break;
		}
		else
		{
			return;
		}
	}
	
	rxbuf = 0;
	if(icmu_read_reg(&hspi1,0x1E,&rxbuf))
	{
		if(rxbuf & 0x1)
		{
			EncoderFault |= 0x00000100;
		}
	}
}

static void Encoder2_Init(void)
{
	uint8_t rxbuf;
	uint8_t i;
	
	for(i = 0; i < 3; i++)
	{
		if(!icmu_activate(&hspi2))
		{
			EncoderFault |= 0x00800000;
			return;
		}
		
		if(icmu_read_reg(&hspi2,0x76,&rxbuf))
		{
			if(rxbuf != 0x00)
			{
				if(rxbuf & 0x10)
					EncoderFault |= 0x00010000;
				
				if(rxbuf & 0x0F)
					EncoderFault |= 0x00020000;
			}
			rxbuf = 0x00;
		}
		if(icmu_read_reg(&hspi2,0x77,&rxbuf))
		{
			if(rxbuf != 0x0)
			{
				if(rxbuf & 0x37)
					EncoderFault |= 0x00040000;
				
				if(rxbuf & 0x08)
					EncoderFault |= 0x00080000;
				
				if(rxbuf & 0x40)
					EncoderFault |= 0x00100000;
				
				if(rxbuf & 0x80)
					EncoderFault |= 0x00200000;
				
			}
			rxbuf = 0x00;
		}
		
		if(EncoderFault == 0x1)
		{
			if(soft_reset(&hspi2))
				EncoderFault = 0;
			else
				EncoderFault |= 0x00400000;
		}
		else if(EncoderFault == 0x0)
		{
			break;
		}
		else
		{
			return;
		}
	}
	
	rxbuf = 0;
	if(icmu_read_reg(&hspi2,0x1E,&rxbuf))
	{
		if(!(rxbuf & 0x1))
		{
			EncoderFault |= 0x01000000;
		}
	}
}

bool Encoder1_Homing(void)
{
	bool ret = false;
	uint8_t rxbuf;
	if(icmu_write_reg(&hspi1,0x75,0x08,&rxbuf))
	{
		if(rxbuf == 0x08)
			ret = true;
	}
	
	return ret;
}

bool Encoder1_WriteEEPROM(void)
{
	uint8_t rxbuf,txbuf[8];
	if(!icmu_read_reg(&hspi1,0x78,&txbuf[0])) return false;
	if(!icmu_read_reg(&hspi1,0x79,&txbuf[1])) return false;
	if(!icmu_read_reg(&hspi1,0x7A,&txbuf[2])) return false;
	if(!icmu_read_reg(&hspi1,0x7B,&txbuf[3])) return false;
	if(!icmu_read_reg(&hspi1,0x7C,&txbuf[4])) return false;
	if(!icmu_read_reg(&hspi1,0x7D,&txbuf[5])) return false;
	if(!icmu_read_reg(&hspi1,0x7E,&txbuf[6])) return false;
	if(!icmu_read_reg(&hspi1,0x7F,&txbuf[7])) return false;
	
	icmu_write_reg(&hspi1,0x42,0x00,&rxbuf);
	icmu_write_reg(&hspi1,0x43,0x00,&rxbuf);
	
	icmu_write_reg(&hspi1,0x78,txbuf[0],&rxbuf);
	if(rxbuf != txbuf[0]) return false;
	
	icmu_write_reg(&hspi1,0x79,txbuf[1],&rxbuf);
	if(rxbuf != txbuf[1]) return false;
	
	icmu_write_reg(&hspi1,0x7A,txbuf[2],&rxbuf);
	if(rxbuf != txbuf[2]) return false;
	
	icmu_write_reg(&hspi1,0x7B,txbuf[3],&rxbuf);
	if(rxbuf != txbuf[3]) return false;
	
	icmu_write_reg(&hspi1,0x7C,txbuf[4],&rxbuf);
	if(rxbuf != txbuf[4]) return false;
	
	icmu_write_reg(&hspi1,0x7D,txbuf[5],&rxbuf);
	if(rxbuf != txbuf[5]) return false;
	
	icmu_write_reg(&hspi1,0x7E,txbuf[6],&rxbuf);
	if(rxbuf != txbuf[6]) return false;
	
	icmu_write_reg(&hspi1,0x7F,txbuf[7],&rxbuf);
	if(rxbuf != txbuf[7]) return false;
	
	icmu_write_reg(&hspi1,0x75,0x01,&rxbuf);
	if(rxbuf != 0x01) return false;
	
	rxbuf = 0x0;
	
	HAL_Delay(1000);
	
	if(icmu_read_reg(&hspi1,0x76,&rxbuf))
	{
		if(rxbuf != 0x00)
		{
			if(rxbuf & 0x10)
				EncoderFault |= 0x00000001;
			
			if(rxbuf & 0x0F)
				EncoderFault |= 0x00000002;
		}
		rxbuf = 0x00;
	}
	
	HAL_Delay(10);
	
	if(icmu_read_reg(&hspi1,0x77,&rxbuf))
	{
		if(rxbuf != 0x0)
		{
			if(rxbuf & 0x37)
				EncoderFault |= 0x00000004;
			
			if(rxbuf & 0x08)
				EncoderFault |= 0x00000008;
			
			if(rxbuf & 0x40)
				EncoderFault |= 0x00000010;
			
			if(rxbuf & 0x80)
				EncoderFault |= 0x00000020;
			
		}
		rxbuf = 0x00;
	}
	
	HAL_Delay(10);
	
	icmu_read_reg(&hspi1,0x78,&rxbuf);
	if(rxbuf == txbuf[0])
		return true;
	
	return false;
}

void Encoder_Init(void)
{
	Encoder1_Init();
	Encoder2_Init();
}
相关推荐
周洲08301 小时前
STM32片内Flash读写深度详解|掉电参数保存、底层原理
linux·前端·stm32
WD137298015576 小时前
WD5030K输入工作电压 7.5‑30V,适合12A 及以内量产项目
stm32·单片机·嵌入式硬件·51单片机
光子物联单片机7 小时前
STM32传感器模块编程实践(二十二)DIY智能WIFI视频控制小车
c语言·stm32·单片机·嵌入式硬件·音视频
新晨单片机设计8 小时前
S010C-基于STM32单片机水温控制系统(OLED显示)【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·水温控制系统
lhbweilai8 小时前
从底层了解STM32八大功能(下)
stm32·单片机
新晨单片机设计9 小时前
S009C-基于STM32单片机语音出租车计价器【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·出租车计价器
Zw-awa10 小时前
volatile 与寄存器:SysTick->VAL 到底在读什么
stm32
Zw-awa1 天前
PWM 为什么能调速:从 LED 亮度变化到直流电机转起来
stm32
送外卖的工程师1 天前
STM32智能家庭安防系统
stm32·单片机·嵌入式硬件