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 statusandSDAD 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(); }