【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

相关文章

解决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

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

matlab读取NC文件(含group)

matlab读取NC文件(含group): NC文件数据结构: 代码: % 打开 NetCDF 文件filename = 'your_file.nc'; % 替换为你的文件名% 使用 netcdf.open 函数打开文件ncid = netcdf.open(filename, 'NC_NOWRITE');% 查看文件中的组% 假设我们想读取名为 "group1" 的组groupName