• MT6701磁编码器使用指南,14Bit单圈绝对值,I2C stm32 HAL库读角度


      MT6701是麦歌恩(MagnTek)公司的磁性角度传感器芯片,提供14Bit 0~360°单圈绝对角度检测,拥有 ABZ/PWM/模拟量/I2C/SSI 等多种信息输出方式,还可根据磁场强度的瞬时变化提供非接触式按压检测功能。能够以较低的成本来替代传统光电编码器,可应用于绝对值角度输出、闭环步进电机BLDC电机旋转角度检测、机器人关节、非接触按键、非接触电位器等场合。

      鉴于其数据手册的介绍已经非常详细,且有中文PDF版本,建议大家先读一遍官方手册:MT6701_Rev.1.6_中文版


    在这里插入图片描述


      MT6701提供 ABZ/UVW/PWM/模拟量/I2C/SSI 等多种信息输出方式,建议优先选择 I2C/SSI 数字接口使用。

      I2C除了获取角度外,还可用于对其内部 EEPROM编程,来更改 ABZ/UVW/模拟量/PWM 的配置参数和校准参数。
      其 SSI 与SPI兼容,仅需要 SCK、MISO、CS 三个IO。




    型号列表

      MT6701CT 封装为 SOP-8。
      MT6701QT 封装为 QFN 3x3。

      后面的尾缀 STD、AKD、AKE、ACD、A200…等,区别仅在于出厂时内部烧录的EEPROM配置不同,用户拿到手后可二次编程来适配自己的应用场景。且其EEPROM支持多次擦写,可根据自己的场合进行灵活配置。(其EEPROM真的大赞,完全不用担心像AS5047P的OTP仅能编程一次的尴尬)

      如果仅使用 I2C/SSI 接口,则不必担心其EEPROM参数对使用的影响。EEPROM多用来配置 ABZ/UVW/PWM/模拟量 的参数和校准参数,不会对 I2C/SSI 读角度有干涉。

      另外SOP-8封装的MT6701的I2C模式电路,是兼容AS5600的,快扔掉以前的AS5600,换上性能与价格更好的MT6701。(TB上现在太多的AS5600翻新片,特别便宜的一定要留意很容易中奖)


    在这里插入图片描述




    磁极安装方式

      用于检测旋转角度的磁铁,必须为 径向充磁 方式,多使用 直径6-8mm、厚度2-5mm的钕铁硼强磁。

      强磁与芯片的垂直高度应控制在 0.5-2mm的大概范围(实际可以更远一些)。

    在这里插入图片描述



    I2C接口模式电路

      MT6701 使用 I2C/SSI 接口时,需要将 MODE脚(SOP-8的PIN2)拉高。

      因其芯片内部已经集成一200K的上拉,MODE脚空置也是可以的。

      使用I2C接口时,还需将 Z脚(SOP-8的PIN8)保持拉高。

    在这里插入图片描述



    I2C读时序

      MT6701 的I2C从机地址,固定为 0x06(STM32需要左移一位,即0x0C)。

      获取角度时候,只需从 0x03 寄存器,连续读2字节,其中就包含有 14Bit 绝对角度信息。

    在这里插入图片描述



    测试电路、在售万能电机转接板

      测试过MT6701后,深被其性价比折服,结合以前的AS5047P万能电机转接板的外形,推出了 MT6701的版本。

      ABZ/UVW/PWM/模拟量/I2C/SSI 接口均已引出,PCB外形可适配 22xx、2606、2804、35xx、6010、6374、36/42/57步进 等多种电机的安装。

      现已在我TB小店批量售卖,TB店铺名:芯源艺码。


    请添加图片描述
    在这里插入图片描述
    在这里插入图片描述


    资料/原理图/源码汇总链接:Github-MT6701_Encoder_STM32




    STM32 I2C HAL库源码

      这里我使用 STM32F103C8T6,其他型号的STM32均可,HAL库只需改动头文件即可全系列使用。

      STM32CubeMX配置:SWD调试接口、UART1-115200用作串口打印、I2C1。

    在这里插入图片描述


    MT6701.c

    #include "MT6701.h"
    
    unsigned char mt6701_write_reg(unsigned char reg, unsigned char value)
    {
    	return HAL_I2C_Mem_Write(&hi2c1, MT6701_SLAVE_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &value, 1, MT6701_Timeout);
    }
    
    unsigned char mt6701_write_regs(unsigned char reg, unsigned char *value, unsigned char len)
    {
    	return HAL_I2C_Mem_Write(&hi2c1, MT6701_SLAVE_ADDR, reg, I2C_MEMADD_SIZE_8BIT, value, len, MT6701_Timeout);
    }
    
    unsigned char mt6701_read_reg(unsigned char reg, unsigned char* buf, unsigned short len)
    {
    	return HAL_I2C_Mem_Read(&hi2c1, MT6701_SLAVE_ADDR, reg, I2C_MEMADD_SIZE_8BIT, buf, len, MT6701_Timeout);
    }
    
    void mt6701_delay(unsigned int ms)
    {
    	HAL_Delay(ms);
    }
    
    // 14Bit角度信息,存储在0x03[13:6]、0x04[5:0]两个寄存器中,高位在前,原始读数0~16383,对应0-360°
    void i2c_mt6701_get_angle(int16_t *angle, float *angle_f)
    {
        uint8_t temp[2];
        mt6701_read_reg(MT6701_REG_ANGLE_14b, temp, 2);
    
        *angle = ((int16_t)temp[0] << 6) | (temp[1] >> 2);
        *angle_f = (float)*angle * 360 / 16384;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    MT6701.h

    #ifndef __MT6701_H__
    #define __MT6701_H__
    
    #include "stm32f1xx_hal.h"
    #include "i2c.h"
    #include 
    
    
    #define MT6701_SLAVE_ADDR         0x06 << 1
    #define MT6701_Timeout            50
    
    #define MT6701_REG_ANGLE_14b      0x03    // 14Bit角度信息,存储在0x03[13:6]、0x04[5:0]两个寄存器中,高位在前,原始读数0~16383
    
    #define mt6701_log		printf
    
    
    
    void i2c_mt6701_get_angle(int16_t *angle, float *angle_f);
    
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    main.c

    #include "main.h"
    #include "i2c.h"
    #include "usart.h"
    #include "gpio.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include 
    #include "MT6701.h"
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    /* USER CODE BEGIN PFP */
    int fputc(int ch,FILE *f)
    {
    	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);
    	return ch;
    }
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_I2C1_Init();
      MX_USART1_UART_Init();
      /* USER CODE BEGIN 2 */
    	printf("-------------------- MT6701 angle test --------------------\r\n");
    	HAL_Delay(200);
    	int16_t angle;
    	float angle_f;
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    		i2c_mt6701_get_angle(&angle, &angle_f);
    		printf("angle = %d\t%.03f\r\n", angle, angle_f);
    		HAL_Delay(30);
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    连接 PA6、PA7 至 MT6701 的 I2C。PA9(TXD) 至 USB转TTL 模块的 RX。
    可读出0~360°的绝对角度信息,如下图所示。

    在这里插入图片描述

    (值得一提的是,我测试其数据输出波动为±1LSB,真14Bit,只要磁极不动,其输出是一点都不会变的,效果非常好。因为以前测试过TLE5012 15Bit ±2LSB,AS5047P 14Bit ±4LSB,AS5600 10Bit都很抖。MT6701 真14BIt不说,MAX 55,000RPM,系统延时<5us,如果手册数据当真,结合其价位来看,绝对是性价比碾压的存在)


    在这里插入图片描述


    如未见输出信息。请保证 Use MicroLIB 已经被勾选,并重定向了 fputc函数。

    在这里插入图片描述

    PUSH 按钮输出就不说了,需要机械结构的配合,自己也用不上。有兴趣可以看下 smartknob
    开源项目,其中用到了MT6701,不过依旧没有用到MT6701的按钮检测,他的按压用压力传感器和HX711实现的。

    在这里插入图片描述



    小结

      对于 MT6701 这颗芯片个人表示强烈推荐,因其硬件电路简洁、使用简单(较AS5047P、TLE5012来说)、可灵活配置输出方式( ABZ/UVW/PWM/模拟量/I2C/SSI 全部支持,已经不能再全了,很难想象仅仅一颗SOP-8就能提供如此全面的功能,输出参数还可EEPROM编程,yyds)、输出角度精准(个人测试绝大多数为±1LSB,真14位)、性能优异(真14Bit,MAX 55,000RPM,系统延时<5us,结合它的价位简直杀疯了)等诸多优点。


      除了以上优异的性能,MT6701的生产公司,麦歌恩微电子现已正式加入矽睿科技,矽睿科技持有麦歌恩微电子46.75%的股权。值得一说的是矽睿也是个宝贝公司,主要生产MEMS器件,其下的 QMI8658、QMC8610 我也用在过产品上,过几星期会批量一批尺寸兼容MPU6050模块的10DOF模组,供各位开发学习使用。

      算是个小预告吧,先来张图片,QMI8658A + QMC6310u + SPL07。I2C / SPI 通信接口。

    在这里插入图片描述

  • 相关阅读:
    使用Redis解决高并发方案 以及 思路讲解
    实用技巧:Linux上实现OpenGauss数据库远程连接,方便的跨网络数据操作
    50从零开始用Rust编写nginx,原来TLS证书还可以这么申请
    Hadoop学习笔记(4)——MapReduce(1)
    Non-constant range: argument must be an integer literal
    KongA 任意用户登录漏洞分析
    3.2队列
    SEO的5大关键指标:排名+流量+会话+停留时长+跳出率
    Flask 的 ORM 模型 - 概述
    【c++】前缀和教程
  • 原文地址:https://blog.csdn.net/Mark_md/article/details/126910658