【SimpleFOC】MT9701 磁编码器的读取
测试:
前言
无刷电机控制技术,按照是否按照编码器,可以分为“有感控制”和“无感控制”
有感控制,既电机需要安装编码器,通过编码器获取转子实时位置(如霍尔传感器、磁编码器、光电编码器)
相对应的为无感控制,无感电机控制不需要编码器,位置数据通过其他方法获取,如HFI高频注入、无感隆伯格观测器、高阶滑膜观测器、拓展卡尔曼滤波等
相对于无感控制,有感控制由于需要安装编码器,所以成本较高,但算法难度更低(无感控制依赖于数学体系,且需要扎实的自动控制理论),抗干扰性更强,更适合入行者接触
一、MT6701芯片简介
MT6701高速磁性角度编码器IC是麦歌恩微电子推出的新一代基于差分水平霍尔磁感应原理的角度位置传感器芯片,支持I2C, SSI, ABZ,UVW, 模拟电压、PWM以及Z轴按压检测等多种输出方式
MT6701芯片特性:
1、3.3V~5.0V工作电压,内置EEPROM(烧写时需要保证VDD>4.5V);
2、独立输出接口: : I2C, SSI, ABZ,UVW, 模拟电压、PWM以及Z轴按压检测;
3、支持*高转速55,000 转/分钟;
4、基于霍尔技术,0~360°*对角度位置检测;
由于MT6701在各方面均领先于AS5600,所以这次选择使用他
二、MT6701 MODE引脚配置输出格式
MT6701 磁编码器的 MODE 引脚主要用于选择芯片的通信接口和工作模式。这个引脚配置不同,芯片输出的信号类型也会不同。
下面这个表格汇总了 MODE 引脚的主要配置方式,方便你快速了解:
目标通信接口/模式 | MODE 引脚接法 | 备注/其他必要条件 |
---|---|---|
I²C | 接高电平 (VDD) | 同时需将 Z 引脚(SOP-8封装的第8脚)拉高 |
SSI | 接高电平 (VDD) | 需配合特定引脚连接 |
ABZ (增量输出) | 接低电平 (GND) | 默认分辨率通常为256脉冲/圈 |
PWM (脉冲宽度调制) | 接低电平 (GND) | PWM频率默认为994.4Hz左右 |
UVW (电机换相信号) | 特定配置 | 需要通过内部寄存器编程设置对极数 |
🔌 MODE引脚的电平设置
MODE 引脚内部集成了一个约200kΩ的上拉电阻。这意味着:
-
当 MODE 引脚悬空(不连接) 时,芯片可能因其内部上拉而默认处于高电平状态。
-
为了确保通信模式的稳定,强烈建议根据目标模式将 MODE 引脚明确连接到 VDD(高电平)或 GND(低电平),而不是依赖内部上拉。
💡 配置注意事项
-
EEPROM 与配置保存:MT6701 内部集成了 EEPROM137,可用于保存对 ABZ 分辨率、UVW 对极数等参数的配置。
MODE 引脚的接线状态决定了芯片上电后与外部MCU通信的方式,而像ABZ分辨率这类更详细的参数则需要通过I²C等接口编程芯片内部的EEPROM来设定。 -
I²C 地址:当处于 I²C 模式时,MT6701 的默认从机地址是 0x06(7位地址)68。请注意,某些程序库(如STM32 HAL库)要求将7位地址左移1位(即0x0C)再进行操作。
-
电源要求:对内部EEPROM进行编程烧写时,需要保证供电电压 VDD > 4.5V。正常工作时,电压范围一般为3.3V~5.0V。
三、SPI通信方式原理图与代码
通讯接口通过XH2.54-6P接口引出,我们将其与CH32开发板连接:
+5V、GND---------连接5V供电
MISO----------------PA6
SCK------------------PA5
CS--------------------PA15
我们使用SPI方式读取MT6701(个人认为比IIC速度更快,更方便)
mt6701.c文件
/***************************************************************************/
#define SPI2_CS1_L GPIO_ResetBits(GPIOA, GPIO_Pin_15) //CS1_L
#define SPI2_CS1_H GPIO_SetBits(GPIOA, GPIO_Pin_15) //CS1_H
/***************************************************************************/
void SPI2_Init_(void) // 初始化SPI接口
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SPI3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //CS--推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_15); //CS_H
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;//PA5--CLK,PA6--MISO,PA7--MOSI,
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI1--双线全双工!!
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位数据
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //CPOL=0 CLK空闲为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //CPHA=1 建议在下降沿采集数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS 信号由硬件管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //4--9MHz,手册介绍最大速度15MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC 值计算的多项式
SPI_Init(SPI3, &SPI_InitStructure);
SPI_Cmd(SPI3, ENABLE);
}
/***************************************************************************/
unsigned char SPIx_ReadWrByte(unsigned char byte)
{
unsigned short retry = 0;
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
{
if(++retry>200)return 0;
}
SPI_I2S_SendData(SPI3, byte);
retry = 0;
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET)
{
if(++retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI3);
}
/***************************************************************************/
uint32_t ReadAngle(void)
{
uint8_t back1,back2,back3;
SPI2_CS1_L;
back1 = SPIx_ReadWrByte(0);
back2 = SPIx_ReadWrByte(0);
back3 = SPIx_ReadWrByte(0);
SPI2_CS1_H;
return (back1<<16)|(back2<<8)|back3;
}
/***************************************************************************/
ReadAngle(void)函数的原理,大家可以参考数据手册的解释:
我在这里去掉了磁场状态、校验码等信息,只保留了位置信息,将其作为返回值
需要注意的是MT6701的分辨率是14位!既输出的范围是0-16384,对应0°-360°
mt6701.h文件
#ifndef APP_MT6701_H_
#define APP_MT6701_H_
#include "ch32v30x.h"
void SPI2_Init_(void);
unsigned char SPIx_ReadWrByte(unsigned char byte);
uint32_t ReadAngle(void);
#endif /* APP_MT6701_H_ */
主函数调用:
unsigned int temp_Seat; // 存储位置数据
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SystemCoreClockUpdate();
Delay_Init();
SPI2_Init_(void); // MT6701--SPI初始化
while(1)
{
temp_Seat = ReadAngle();// 获取角度值
Delay_Ms (200);
}
}
四、自己板子的相关引脚——通过Analog方式读取
左边:IIC 和 OUT(ABZ) 二选一
(这里的OUT很让人疑惑,因为右边也有一个OUT,那个是模拟输出,个人感觉改为 ABZ 输出更好)
目标通信接口/模式 | MODE 引脚接法 | 备注/其他必要条件 |
---|---|---|
I²C | 接高电平 (VDD) | 同时需将 Z 引脚(SOP-8封装的第8脚)拉高 |
SSI | 接高电平 (VDD) | 需配合特定引脚连接 |
ABZ (增量输出) | 接低电平 (GND) | 默认分辨率通常为256脉冲/圈 |
PWM (脉冲宽度调制) | 接低电平 (GND) |
PWM频率默认为994.4Hz左右 |
右边:选择输出PUSH还是OUT(PUSH 是 Z 轴按压, OUT是模拟数据)
(其实个人感觉:右边的配置是无所谓的,可以两个都输出嘛)
总结:
推荐用模拟输出,因此 PIN 统一接 OUT。
IIC/SPI输出的话:那就MODE接高电平(反之,如果用ABZ通信,那MODE就接低电平)
X. 参考文章:
1. 【电机控制】MT6701磁编码器--绝对值位置读取
链接:https://blog.csdn.net/CYFYFUG/article/details/139361618
2. MT6701 数据手册:
链接:https://item.szlcsc.com/3489938.html