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();
}
相关推荐
inrichtt4 小时前
第十一课时:串口中断接收与回调函数实战解析
c语言·数据结构·stm32·单片机·嵌入式硬件
2501_922639586 小时前
率能半导体 SS6622E直流双向马达驱动芯片:20V/2.4A,覆盖电子锁、玩具、无线充电、机器人四大应用场景
stm32·单片机·嵌入式硬件·硬件工程
Zw-awa6 小时前
按键一按程序就像死机:阻塞式写法如何毁掉小车
stm32
意法半导体STM327 小时前
【官方原创】LAT6041 STM32MP1x USB OTG FIFO设置
stm32·单片机·嵌入式硬件·mcu·fifo·stm32mp1x
笨笨饿7 小时前
#145 _Codex 三层故障详细排查与修复步骤
开发语言·人工智能·stm32·单片机·嵌入式硬件
深圳老胡7 小时前
STM32C5A3ZG开发板网络接口配置流程详解
笔记·stm32·单片机·代码规范
深圳老胡8 小时前
STM32C5A3ZG 开发板调试笔记:USB 复用 ST-Link 与工程生成警告说明
笔记·stm32·单片机·代码规范
玄芯散人19 小时前
【元婴·100】STM32启动流程:从上电到main()经历了什么
stm32·单片机·嵌入式硬件
科芯创展1 天前
XZ5129:单节锂电池供电36V升压LED恒流驱动芯片设计解析
stm32·单片机·嵌入式硬件
羊羊一洋1 天前
ROM&RAM
c语言·stm32·学习