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

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


  • 📍相关篇《STM32 软件I2C方式读取AS5600磁编码器获取角度例程》

✨stm32使用硬件I2C去读取角度数据,通过STM32CubeMX工具配置工程,读取角度数据,只需要调用一个函数,即可完成数据的读取。了解函数的用法以及从设备地址命令,上手十分快速和简单。

  • 📌AS5600资料:https://pan.baidu.com/s/15UMUH5_ppb2FTju7AJgFyw

📗AS5600寄存器描述

  • 📄AS5600寄存器汇总:
    在这里插入图片描述
  • 🌿ZPOS/MPOS/MANG寄存器:这些寄存器用于配置开始位置(ZPOS)和停止位置(MPOS)或最大角度(MANG)。默认范围为全0到360度,但当配置了一个较窄的范围时,输出的全分辨率将自动缩放到所配置的角度范围。角度范围必须大于18度。
  • 🌿ANGLE/RAW ANGLE 寄存器(0x0c,0x0d):RAW角度寄存器包含未缩放和未修改的角度。缩放后和过滤后的输出值在角度寄存器中可用。(原始值范围:0 - 4095)
  • 🌿ANGLE角度值(0x0e,0x0f):角度值范围:0-360
  • 🌿STATUS 状态寄存器:状态寄存器提供指示AS5600的当前状态的位。(当前磁场强度)
    在这里插入图片描述
  • 🌿AGC寄存器:AS5600在一个闭环中使用自动增益控制来补偿由于温度变化、IC和磁体之间的气隙以及磁体退化而引起的磁场强度的变化。AGC寄存器表示增益。对于最健壮的性能,增益值应该在其范围的中心。物理系统的气隙可以被调整以达到这个值。在5V操作中,AGC范围为0-255次。在3.3V模式下,AGC范围减少到0-128个计数。
  • 🌿MAGNITUDE寄存器:MAGNITUDE寄存器表示内部CORDIC的幅度值。
  • 🌿Burn_Angle命令(ZPOS,MPOS):MCU可以使用BURN_ANGLE命令执行ZPOS和MPOS的永久编程。要执行BURN_ANGLE命令,请将值0x80写入寄存器0xFF。BURN_ANGLE命令最多可以执行3次。ZMCO显示了ZPOS和MPOS被永久写入的多少次。

  • 🌿磁场Bz和典型的间隙
    在这里插入图片描述

典型的间隙在0.5 mm到3 mm之间,这取决于所选的磁铁。一个更大和更强的磁铁允许一个更大的气隙。使用AGC值作为导轨,通过调整磁体与AS5600之间的距离,使AGC值在其范围的中心,可以找到最佳的气隙。当使用直径为6mm的磁铁时,参考磁铁的旋转轴从包装中心的最大允许位移为0.25 mm。

📑功能概要

  • 🖍首先对AS5600设备地址进行扫描,并打印设备地址,然后从指定设备的指定寄存器地址读取2个字节数据。

🛠STM32CubeMX工程配置

  • 🌿勾选I2C,参数默认即可。
    在这里插入图片描述
  • 🌿使能一路串口,方便查看数据信息。

在这里插入图片描述

📙业务代码完善

  • 📄main函数内容:
int main(void)
{/* USER CODE BEGIN 1 */uint8_t Raw_num[2];// Read angular measurementsuint16_t Angle = 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;uint8_t i;for (i=1; i<128; 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 2AS5600 i2c address:(0x6c = 0x36 << 1)*/result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i<<1), 2, 2);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");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1) {/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_I2C_Mem_Read(&hi2c1, AS5600_SLAVE_ADDRESS, addr_in, I2C_MEMADD_SIZE_8BIT, Raw_num, 2,100);int value = (Raw_num[0]<<8)|Raw_num[1];Angle = (value * 360)/4096;//换算成角度printf("Angle = %d degrees.\n", Angle);HAL_Delay(500);}/* USER CODE END 3 */
}
  • 🔖或者根据上面的寄存器,直接读取角度寄存器值:HAL_I2C_Mem_Read(&hi2c1, AS5600_SLAVE_ADDRESS, addr_in, I2C_MEMADD_SIZE_8BIT, 0x0e, 2,100);
  • 🌿开启串口打印,在usart.c中添加一下内容:(在调用printf的地方,包含stdio.h头文件,Keil option中勾选MicroLib选项)
#include <stdio.h>
//使用printf()发送数据,需要对printf函数进行重定向,且只能使用USART1。
// 重定向fputc函数,使用printf()发送数据
int fputc(int ch, FILE *f)
{// 参数1:串口句柄,参数2:要发送的数据;参数3:要发生数据的长度;参数4:超时等待时间HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);return ch;
}
  • 🔖串口输出:
    -在这里插入图片描述

📚HAL_I2C_Mem_Read(阻塞方式)读取测试工程

  • 🔖基于stm32f103
链接:https://pan.baidu.com/s/1aN1n26SNdVSn6Q1CcaKrgg?pwd=48ok 
提取码:48ok

📗HAL_I2C_Mem_Read_DMA和HAL_I2C_Mem_Read_IT方式读取数据

  • 🔧在STM32CubeMX中,配置I2C时,在DMA选项中,添加RX配置:
    在这里插入图片描述
  • 🌿勾选事件中断
    在这里插入图片描述
  • 🔖完成以上参数内容配置后,在工程代码中可以使用HAL_I2C_Mem_Read_DMAHAL_I2C_Mem_Read_IT函数都可以读取角度原始数据值。
  • 🌿添加读I2C设备是否在线函数。(可以省略,默认只查询一次。)
HAL_StatusTypeDef I2C_WaitUntilDeviceReady(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint32_t Timeout){uint32_t tickstart = HAL_GetTick();                 //获取当前时间while(HAL_GetTick()-tickstart <= Timeout){          //如果没有超时就一直尝试if(HAL_I2C_IsDeviceReady(&hi2c1, DevAddress,1, Timeout) == HAL_OK){   //如果准备好了就returnreturn HAL_OK;}}return HAL_TIMEOUT;                                 //否则return一个错误
}
  • 🌾main函数内容
int main(void)
{/* USER CODE BEGIN 1 */uint8_t Raw_num[2];// Read angular measurementsuint16_t Angle = 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_DMA_Init();MX_I2C1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */printf("Scanning I2C bus:\r\n");HAL_StatusTypeDef result;uint8_t i;for (i=1; i<128; 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 2AS5600 i2c address:(0x6c = 0x36 << 1)*/result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i<<1), 2, 2);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");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1) {/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(I2C_WaitUntilDeviceReady(&hi2c1,AS5600_SLAVE_ADDRESS, 5)==HAL_OK)//检测设备是否在线,设置5ms超时HAL_I2C_Mem_Read_DMA(&hi2c1, AS5600_SLAVE_ADDRESS, addr_in, I2C_MEMADD_SIZE_8BIT, Raw_num, 2);int value = (Raw_num[0]<<8)|Raw_num[1];Angle = (value * 360)/4096;//换算成角度printf("Angle = %d degrees.\n", Angle);HAL_Delay(500);}/* USER CODE END 3 */
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/588822.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【学习】渗透测试有哪些重要性

随着信息技术的迅猛发展&#xff0c;网络安全问题日益凸显。渗透测试作为网络安全防御的重要手段之一&#xff0c;旨在模拟黑客攻击&#xff0c;发现并修复潜在的安全漏洞&#xff0c;提高网络系统的安全性。本文将介绍渗透测试的概念、重要性、实施步骤及实践案例&#xff0c;…

[蓝桥杯练习题]出差

一道DJ题,重要的是隔离时间,把隔离时间加在边权上即可 现实生活的题大多都是无向图建图,需要边的两端点各自上邻接表和相同权重 #include<bits/stdc.h> using namespace std; #define ll long long const int N1005; const int M10005; struct edge{int to;ll w;edge(int…

Monaco Editor系列(二)Hello World 初体验

前言&#xff1a;上一篇文章我主要分享了从 Monaco Editor 入口文件以及官方提供的示例项目入手&#xff0c;对一部分源码进行剖析&#xff0c;以及分享了初始化阶段代码的大致执行步骤&#xff0c;这一篇了来讲一下我们要用 Monaco Editor 的时候该怎么用。其中会涉及到一些 A…

LeetCode 热题 100 | 动态规划(一)

目录 1 70. 爬楼梯 1.1 基本思路 1.2 官方题解 2 118. 杨辉三角 3 198. 打家劫舍 菜鸟做题&#xff0c;语言是 C 1 70. 爬楼梯 核心思想&#xff1a;把总问题拆解为若干子问题。 总问题&#xff1a;上到 5 楼的方式有多少种子问题&#xff1a;上到 4 楼的方式有多…

炫我科技:云渲染领域的佼佼者

随着数字化时代的来临&#xff0c;云渲染技术正逐渐成为影视、游戏、动画等创意产业的重要支柱。在这一领域中&#xff0c;炫我科技凭借其卓越的技术实力、优质的服务以及不断创新的精神&#xff0c;已然成为了云渲染行业的佼佼者。 炫我科技自成立之初&#xff0c;便以打造高…

SV学习笔记(二)

接口 什么是接口&#xff1f; 接口 主要用作验证 &#xff0c;国外有些团队会使用sv进行设计&#xff0c;那么接口就会用作设计。验证环境中&#xff0c;接口可以 使连接变得简洁而不易出错 。interface和module的使用性质很像&#xff0c; 可以定义端口&#xff0c;也可以定…

基于单片机的炉温控制系统设计

**单片机设计介绍&#xff0c;基于单片机的炉温控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的炉温控制系统设计是一个融合了单片机技术、温度传感技术、控制算法以及硬件电路设计等多个领域的综合性项…

在ChatGPT中,能用DALL·E 3编辑图片啦!

4月3日&#xff0c;OpenAI开始向部分用户&#xff0c;提供在ChatGPT中的DALLE 3图片编辑功能。 DALLE 3是OpenAI在2023年9月20日发布的一款文生图模型&#xff0c;其生成的图片效果可以与Midjourney、leonardo、ideogram等顶级产品媲美&#xff0c;随后被融合到ChatGPT中增强其…

【BlossomConfig】SpringCloud项目是如何对bootstrap配置文件进行加载的?

文章目录 bootstrap配置文件的读取什么是配置中心&#xff1f;以及如何实现一个配置中心&#xff1f;SpringBoot如何实现配置的管控&#xff1f;SpringCloud项目是如何对bootstrap配置文件进行加载的&#xff1f;Nacos是如何实现配置文件的读取加载的&#xff1f;开发配置中心前…

一次普通的漏洞挖掘思路分享

No.0 前言 一名web安全小白&#xff0c;自己仅学了一点思路&#xff0c;直接实战&#xff0c;运气不错&#xff0c;碰到了管理员弱口令&#xff0c;进入后台后&#xff0c;继续测试自己学会的思路挖掘深一点的漏洞&#xff0c;这里与各位分享一下&#xff0c;如果有更多的思路…

MMU关闭时Cache的缓存策略是怎样的

快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; 在学习MMU章节时&#xff0c;我们发现在页表的entry中&#xff0c;BIT[4:2]指向了MAIR寄存器&#xff0c;该寄存器描述了内存属性&#xff0c;其实就是cache的缓存策略属性&#…

洛谷-P1706 全排列问题(DFS)

目录 题目链接&#xff1a; 思路&#xff1a; 代码&#xff1a; 题目链接&#xff1a; P1706 全排列问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路&#xff1a; 如果n比较小&#xff0c;可以写n个for循环输出全排列。但是这种简单方法只能用于较小的n&#xff0…