【STM32+HAL】I2C+DMA读取AS5600编码器

2024-03-27 11:12

本文主要是介绍【STM32+HAL】I2C+DMA读取AS5600编码器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、DMA的应用

有关更多DMA的应用,详见【STM32+HAL】DMA应用

二、HAL库配置

1、开启I2C

开启对应DMA及中断

2、开启串口通信

至此,HAL库配置完毕

三、DMA版(高效但不稳定)

1、as5600.c
#include "AS5600.h"
#include "math.h"float angle_prev=0;
int full_rotations=0; // full rotation tracking;
uint8_t data[2]={0};float x1;
float x2;//发送单字节时序
void AS5600_Write_Reg(uint16_t reg, unsigned char value)
{HAL_I2C_Mem_Write(&hi2c1, AS5600_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, &value, 1, 50);
}//发送多字节时序
void AS5600_Write_Regs(uint16_t reg, unsigned char *value, unsigned char len)
{HAL_I2C_Mem_Write(&hi2c1, AS5600_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, value, len, 50);
}//IIC读多字节
void AS5600_Read_DMA(uint8_t regAddress, uint8_t* pData, uint16_t Size) {// 启动I2C DMA接收if (HAL_I2C_Mem_Read_DMA(&hi2c1, AS5600_ADDRESS, regAddress, I2C_MEMADD_SIZE_8BIT, pData, Size) != HAL_OK) {// 错误处理,例如打印错误信息printf("I2C DMA read failed\r\n");}
}//得到弧度制的角度,范围在0-6.28
float GetAngle_Without_Track(void)
{float angle_d;int16_t in_angle;
//	AS5600_Read_DMA( Angle_Hight_Register_Addr, data, DATA_SIZE);in_angle = ((int16_t)data[0] <<8) | (data[1]);angle_d = (float)in_angle * (2.0f*PI) / 4096;return angle_d;//angle_d为弧度制,范围在0-6.28
}//得到弧度制的带圈数角度
float GetAngle(void)
{float val = GetAngle_Without_Track();float d_angle = val - angle_prev;//计算旋转的总圈数//通过判断角度变化是否大于80%的一圈(0.8f*6.28318530718f)来判断是否发生了溢出//如果发生了,则将full_rotations增加1(如果d_angle小于0)或减少1(如果d_angle大于0)。if(fabs(d_angle) > (0.8f*2.0f*PI) ) full_rotations += ( d_angle > 0 ) ? -1 : 1;angle_prev = val;return (float)full_rotations * 2.0f * PI + angle_prev;
}// DMA传输完成回调函数
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) {if (hi2c->Instance == I2C1) {x1=GetAngle_Without_Track();x2=GetAngle();// 重新启动DMA接收以实现连续读取AS5600_Read_DMA( Angle_Hight_Register_Addr, data, DATA_SIZE);}
}

2、main.c
/* USER CODE BEGIN Includes */
#include "AS5600.h"
#include "stdio.h"
/* USER CODE END Includes *//* USER CODE BEGIN PV */
extern uint8_t data[2];extern float x1;
extern float x2;
/* USER CODE END PV *//* USER CODE BEGIN 2 */printf("Hello World\r\n");HAL_Delay(500);AS5600_Read_DMA(Angle_Hight_Register_Addr, data, DATA_SIZE);  // 启动I2C DMA接收/* USER CODE END 2 *//* USER CODE BEGIN WHILE */while (1){printf("degree:%.4f\r\n",x1);printf("circle:%.4f\r\n",x2);HAL_Delay(50);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */

四、不用DMA版(低效率但稳定)

1、AS5600.c
#include "AS5600.h"
#include "math.h"float angle_prev=0; 
int full_rotations=0; // full rotation tracking;
float angle_d;				//GetAngle_Without_Track()的返回值
float angle_cd;				//GetAngle()的返回值//发送单字节时序
void AS5600_Write_Reg(uint16_t reg, uint8_t *value)
{HAL_I2C_Mem_Write(&hi2c1, AS5600_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, value, 1, 50);
}//发送多字节时序
void AS5600_Write_Regs(uint16_t reg, uint8_t *value, uint8_t len)
{HAL_I2C_Mem_Write(&hi2c1, AS5600_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, value, len, 50);
}//IIC读多字节
void AS5600_Read_Reg(uint16_t reg, uint8_t* buf, uint8_t len)
{HAL_I2C_Mem_Read(&hi2c1, AS5600_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 50);
}//得到弧度制的角度,范围在0-6.28
float GetAngle_Without_Track(void)
{   int16_t in_angle;uint8_t temp[DATA_SIZE]={0};AS5600_Read_Reg( Angle_Hight_Register_Addr, temp, DATA_SIZE);in_angle = ((int16_t)temp[0] <<8) | (temp[1]);angle_d = (float)in_angle * (2.0f*PI) / 4096;
//angle_d为弧度制,范围在0-6.28	return angle_d;
}//得到弧度制的带圈数角度
float GetAngle(void)
{float val = angle_d;float d_angle = val - angle_prev;//计算旋转的总圈数//通过判断角度变化是否大于80%的一圈(0.8f*6.28318530718f)来判断是否发生了溢出,如果发生了,则将full_rotations增加1(如果d_angle小于0)或减少1(如果d_angle大于0)。if(fabs(d_angle) > (0.8f*2.0f*PI) ) full_rotations += ( d_angle > 0 ) ? -1 : 1; angle_prev = val;angle_cd = full_rotations * (2.0f*PI) + angle_prev;return angle_cd;
//    return (float)full_rotations * 6.28318530718f + angle_prev;
}void Track(void)
{GetAngle_Without_Track();GetAngle();
}

2、main.c 
/* USER CODE BEGIN PV */
extern uint8_t data[2];extern float angle_d;				//GetAngle_Without_Track()的返回值
extern float angle_cd;				//GetAngle()的返回值
/* USER CODE END PV *//* USER CODE BEGIN WHILE */while (1){Track();printf("%.3f   %.3f\r\n",angle_d,angle_cd);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

五、巨人之肩

STM32 HAL库 AS5600编码器程序

六、源码提供

资源【STM32+HAL】I2C+DMA读取AS5600编码器

【STM32+HAL】I2C读取AS5600编码器【不加DMA版本】

这篇关于【STM32+HAL】I2C+DMA读取AS5600编码器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851914

相关文章

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

如何使用 Python 读取 Excel 数据

《如何使用Python读取Excel数据》:本文主要介绍使用Python读取Excel数据的详细教程,通过pandas和openpyxl,你可以轻松读取Excel文件,并进行各种数据处理操... 目录使用 python 读取 Excel 数据的详细教程1. 安装必要的依赖2. 读取 Excel 文件3. 读

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

基于Python实现读取嵌套压缩包下文件的方法

《基于Python实现读取嵌套压缩包下文件的方法》工作中遇到的问题,需要用Python实现嵌套压缩包下文件读取,本文给大家介绍了详细的解决方法,并有相关的代码示例供大家参考,需要的朋友可以参考下... 目录思路完整代码代码优化思路打开外层zip压缩包并遍历文件:使用with zipfile.ZipFil

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

利用Python实现添加或读取Excel公式

《利用Python实现添加或读取Excel公式》Excel公式是数据处理的核心工具,从简单的加减运算到复杂的逻辑判断,掌握基础语法是高效工作的起点,下面我们就来看看如何使用Python进行Excel公... 目录python Excel 库安装Python 在 Excel 中添加公式/函数Python 读取

Python如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl