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设备地址扫描实现:
	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真正的地址。
  • 🌿读取角度数据实现:
/*	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;
}
  • 🌿方向读取
#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输出分辨率(脉冲圈)读取
#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编程,改变编码器方向。(默认是逆时针递增)
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);
	
	
}

在这里插入图片描述
在这里插入图片描述

  • 📝测试代码
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方式
链接:https://pan.baidu.com/s/1l4gElhcqn6mg6cWYaHG4Wg?pwd=kuub 
提取码:kuub
  • 🌿硬件I2C中断方式
链接:https://pan.baidu.com/s/1W2vZRmQPNe4VU6dKFc9xJQ?pwd=tzfl 
提取码:tzfl
  • 🌿硬件I2C中断+DMA方式
链接:https://pan.baidu.com/s/138bIpgdeMii6GkKLJEPeMg?pwd=sl8a 
提取码:sl8a
  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F1系列是意法半导体(STMicroelectronics)推出的一款32位MCU系列产品,具有丰富的外设和强大的性能。其中,I2C总线是一种常见的串行通信总线,用于连接微控制器和其他设备进行数据传输。 在STM32F1的HAL库中,提供了I2C例程,以方便开发者快速使用I2C总线进行数据通信。下面简要介绍一下STM32F1 HAL库中I2C例程的主要功能和使用方法: 1. 初始化I2C总线 (HAL_I2C_Init函数):通过配置I2C的时钟速度、地址模式等参数,初始化I2C总线。在初始化过程中,需要指定I2C的外设号以及总线的时钟源。 2. 写入数据到I2C总线 (HAL_I2C_Master_Transmit函数):通过指定I2C的外设号、目标设备地址、发送的数据缓冲区和数据长度,可以将数据写入到I2C总线。在写入数据之前,需要确保目标设备已经准备好接收数据。 3. 读取I2C总线上的数据 (HAL_I2C_Master_Receive函数):通过指定I2C的外设号、目标设备地址、接收数据的缓冲区和数据长度,可以从I2C总线上读取数据。在读取数据之前,需要确保目标设备已经准备好发送数据。 4. 发送和接收数据(HAL_I2C_Master_Transmit_Receive函数):通过指定I2C的外设号、目标设备地址、发送的数据缓冲区、发送数据的长度、接收数据的缓冲区和接收数据的长度,可以在一次函数调用中同时发送和接收数据。 以上是STM32F1 HAL库中I2C例程的基本功能和使用方法。开发者可以根据具体需求,使用这些例程来实现自己的应用。注意,在使用I2C例程之前,需要在CubeMX工具中正确配置I2C外设的引脚映射和时钟源。 总而言之,STM32F1 HAL库提供了丰富的I2C例程,方便开发者在STM32F1系列MCU上使用I2C总线进行数据通信。通过合理使用这些例程,可以快速开发出各种I2C设备的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值