【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多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

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编码