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
相关推荐
LateBloomer7776 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos
wenchm6 小时前
细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的另一种方法
stm32·单片机·嵌入式硬件
嵌新程11 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575
Lin20123011 小时前
STM32 Keil5 attribute 关键字的用法
stm32·单片机·嵌入式硬件
电工小王(全国可飞)11 小时前
STM32 RAM在Memory Map中被分为3个区域
stm32·单片机·嵌入式硬件
maxiumII11 小时前
Diving into the STM32 HAL-----DAC笔记
笔记·stm32·嵌入式硬件
时光の尘15 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
日晨难再18 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
PegasusYu1 天前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
文弱书生6561 天前
输出比较简介
stm32