HAL STM32 I2C方式读取MT6701磁编码器获取角度例程

HAL STM32 I2C方式读取MT6701磁编码器获取角度例程


📙MT6701 IIC接口电路


  • 🔖 第八引脚,直接接到VCC,或者增加上拉电阻也可以。

⛳MT6701 I2C 读取角度操作

MT6701做为I2C从机的地址是b'0000110(这一地址可以通过编程改为b'1000110 )。14位绝对角度数据(2的14次方,16384)保存在0x03和0x04寄存器中,请按照如图-20所示的读取0x03和0x04的角度数据。
注意:要先读0x03,再读0x04。

⛳注意事项

  • ✨在MT6701芯片和径向磁铁一定要保持稳定的空间距离,一旦空间距离有较大的变化,在读取MT6701芯片寄存器数据就可能出现最大值情况。在检测时,芯片和径向磁铁轴向和径向都需要相对稳定。
  • 🌟在选择通讯线材上,尽量选择好一点的线材,如果使用杜邦线连接,最好将连接线独立分开的单根进行连接,不要使用并排的杜邦线进行连接,对使用硬件I2C通讯有很大的影响。甚至读取不到,软件方式对这方面要求没有这么高。

📒EEPROM编程

  • 🌿相关寄存器位:
  • 📜编程步骤:

📓STM32CubeMX配置

  • 🌿选择一个I2C接口:(快速模式:400KHz,普通模式:100KHz)

📙业务代码

  • 🌿对I2C设备地址扫描实现:
c 复制代码
	printf("Scanning I2C bus:\r\n");
	HAL_StatusTypeDef result;

 	for (uint8_t i=1; i<255; i++)
 	{
 	  /*
 	   * the HAL wants a left aligned i2c address
 	   * &hi2c1 is the handle
 	   * (uint16_t)(i<<1) is the i2c address left aligned
 	   * retries 2	重复次数
 	   * timeout 20    超时
		MT6701 i2c address:(0xC = 0x6 << 1)
 	   */
 	  result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i<<1), 2, 20);
 //	  result = HAL_I2C_Master_Transmit(&hi2c1,(uint16_t)i<<1,0,0,20); //同上
 	  if (result != HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
 	  {
 		  printf("."); // No ACK received at that address
 	  }
 	  if (result == HAL_OK)
 	  {
 		  printf("0x%X", i); // Received an ACK at that address
 	  }
 	}
 	printf("\r\n");
  • 可以扫描到3个地址,其中第一个0x6为MT6701真正的地址。
  • 🌿读取角度数据实现:
c 复制代码
/*	SlaveAddress:0x6<<1 
 * IIC 方式读取角度信息
 * 返回数据为 0 ~ 360 之间的浮点数
 */
float Read_Angle(void)
{
    uint32_t angle = 0;
    float fangle = 0.0f;
    uint8_t ReadBuffer1,ReadBuffer2;

    HAL_I2C_Mem_Read(&hi2c1,0xc,0x3,I2C_MEMADD_SIZE_8BIT,&ReadBuffer1,1,0XFF);
    angle = ReadBuffer1;
    angle <<= 8;
    HAL_I2C_Mem_Read(&hi2c1,0xc,0x4,I2C_MEMADD_SIZE_8BIT,&ReadBuffer2,1,0XFF);
    angle += ReadBuffer2;
    angle >>= 2;            //取数据高 14 位
    fangle = (float)(angle * 360.0f) / 16384.0f;

    return fangle;
}
  • 🌿方向读取
c 复制代码
#define DIR_RES    0X29        //数据高位寄存器地址
uint8_t Read_DIR(void)
{
	uint8_t  DIR=0;
	HAL_I2C_Mem_Read(&hi2c1,SlaveAddress,DIR_RES,I2C_MEMADD_SIZE_8BIT,&DIR,1,0XFF);
	 return (DIR&0x2);
}
  • 🌿ABZ输出分辨率(脉冲圈)读取
c 复制代码
#define Abz_ResH    0X30        //数据高位寄存器地址
#define Abz_ResL    0X31        //数据低位寄存器地址
uint16_t Read_ABZ(void)
{
    uint16_t AbzRes = 0;
    uint8_t ReadBuffer1,ReadBuffer2;

    HAL_I2C_Mem_Read(&hi2c1,SlaveAddress,Abz_ResH,I2C_MEMADD_SIZE_8BIT,&ReadBuffer1,1,0XFF);
    AbzRes = ReadBuffer1&0x3;
    AbzRes <<= 8;
    HAL_I2C_Mem_Read(&hi2c1,SlaveAddress,Abz_ResL,I2C_MEMADD_SIZE_8BIT,&ReadBuffer2,1,0XFF);
    AbzRes += ReadBuffer2;
    return AbzRes;
}
  • 🌿通过 EEPROM编程,改变编码器方向。(默认是逆时针递增)
c 复制代码
void programmEEPROM(void)
{
	uint8_t  DIR=0;
	uint8_t KEY1=0xB3;
	uint8_t KEY2=0x05;
	HAL_I2C_Mem_Read(&hi2c1,SlaveAddress,DIR_RES,I2C_MEMADD_SIZE_8BIT,&DIR,1,0XFF);
	DIR ^= 1<<1;  //方向翻转
	HAL_I2C_Mem_Write(&hi2c1,SlaveAddress,DIR_RES,I2C_MEMADD_SIZE_8BIT,&DIR,1,0XFF);
	HAL_I2C_Mem_Write(&hi2c1,SlaveAddress,0x09,I2C_MEMADD_SIZE_8BIT,&KEY1,1,0XFF);
	HAL_I2C_Mem_Write(&hi2c1,SlaveAddress,0x0A,I2C_MEMADD_SIZE_8BIT,&KEY2,1,0XFF);
	HAL_Delay(800);
	
	
}


  • 📝测试代码
c 复制代码
int main(void)
{

  /* USER CODE BEGIN 1 */
	int16_t angle;
	float angle_f;
	uint8_t  dir=0;
  /* 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("Scanning I2C bus:\r\n");
	HAL_StatusTypeDef result;

 	for (uint8_t i=1; i<255; i++)
 	{
 	  /*
 	   * the HAL wants a left aligned i2c address
 	   * &hi2c1 is the handle
 	   * (uint16_t)(i<<1) is the i2c address left aligned
 	   * retries 2	重复次数
 	   * timeout 20    超时
		MT6701 i2c address:(0xC = 0x6 << 1)
 	   */
// 	  result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i<<1), 2, 20);
 	  result = HAL_I2C_Master_Transmit(&hi2c1,(uint16_t)i<<1,0,0,20); //同上
		if (result != HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
 	  {
 		  printf("."); // No ACK received at that address
 	  }
 	  if (result == HAL_OK)
 	  {
 		  printf("0x%X", i); // Received an ACK at that address
 	  }
 	}
 	printf("\r\n");
		
	  dir = Read_DIR() ;
	printf("DIR:%d",dir);
	HAL_Delay(200);	
#if defined(PROGRAM_ENABLE)
	printf("-------------------- MT6701 programm test --------------------\r\n");
	programmEEPROM();
#endif

	HAL_Delay(3000);
	dir = Read_DIR() ;
		printf("-------------------- MT6701 angle test --------------------\r\n");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
//		i2c_mt6701_get_angle(&angle, &angle_f);
//		printf("angle = %d\t%.03f\r\n", angle, angle_f);
//		angle_f = Read_Angle();
//		printf("angle= %.1f\r\n",  angle_f);
		i2c_mt6701_get_angle(&angle, &angle_f);
		uint16_t AbzRes = Read_ABZ();		
		printf("Raw_Angle = %d\tAngle:%.1f,AbzRes:%d DIR:%d\r\n", angle, angle_f,AbzRes,dir);

		HAL_Delay(500);
		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
  }
  /* USER CODE END 3 */
}

📚测试工程

  • 🌿硬件I2C方式
c 复制代码
链接:https://pan.baidu.com/s/1l4gElhcqn6mg6cWYaHG4Wg?pwd=kuub 
提取码:kuub
  • 🌿硬件I2C中断方式
c 复制代码
链接:https://pan.baidu.com/s/1W2vZRmQPNe4VU6dKFc9xJQ?pwd=tzfl 
提取码:tzfl
  • 🌿硬件I2C中断+DMA方式
c 复制代码
链接:https://pan.baidu.com/s/138bIpgdeMii6GkKLJEPeMg?pwd=sl8a 
提取码:sl8a
相关推荐
打地基的小白1 小时前
软件I2C-基于江科大源码进行的原理解析和改造升级
stm32·单片机·嵌入式硬件·通信模式·i2c
Echo_cy_2 小时前
STM32 DMA+AD多通道
stm32·单片机·嵌入式硬件
朴人2 小时前
【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
stm32·单片机·嵌入式硬件·foc
追梦少年时2 小时前
STM32中断——外部中断
stm32·单片机·嵌入式硬件
bai_lan_ya2 小时前
stm32定时器中断和外部中断
stm32·单片机·嵌入式硬件
玄奕子2 小时前
GPT对话知识库——在STM32的平台下,通过SPI读取和写入Flash的步骤。
stm32·单片机·gpt·嵌入式·嵌入式驱动
py.鸽鸽3 小时前
王者农药更新版
stm32
星汇极客3 小时前
【星汇极客】单片机竞赛之2024睿抗机器人大赛-火线速递赛道(持续更新)
stm32·单片机·嵌入式硬件·机器人
Daemon.Chen4 小时前
【STM32开发之寄存器版】(五)-窗口看门狗WWDG
stm32·单片机·嵌入式硬件
嵌入式杂谈6 小时前
STM32中断编程详解:配置外部中断和中断服务例程
stm32·单片机·嵌入式硬件