STM32 SPI获取磁性角度传感器AS5048A角度数据

AS5048A是14位精度的磁性角度检测传感器,采用SPI接口。实际上稳定精度还是只有12位,也就是在检测环境静止情况下,数据输出的最后两位在变化而不恒定。AS5048A可用于旋转角度检测如旋转编码器等,尤其可以用于Z轴的旋转检测如云台角度检测。

如下为官方模块:

因为AS5048A可以通过SPI也可以通过PWM线输出角度数据,第三方模块有单独输出PWM的类型,也有单独输出SPI的类型。这里只介绍SPI的角度输出方式。

检测原理

如下所示为磁性角度传感器的角度检测原理,需要半圆磁极的磁片配合,在磁片旋转时,AS5048A检测磁力线的变动获得角度信息。

AS5048A是360度检测传感器,用户可以设置0角度位置。优点是直接输出角度而不需要做角速度到角度的转换,且经过测试验证长时间运行没有零点漂移现象。

SPI协议

AS5048A采用16位的SPI访问格式,操作地址设定命令发送格式如下:

写数据格式如下:

读出的数据格式如下:

AS5048A内部寄存器功能如下:

读取角度操作方式

根据时序要求,读取角度的操作方式可为:

  1. 清除错误寄存器指令
  2. 空操作指令
  3. 读角度指令
  4. 空操作指令
    因此会发送4次SPI指令,由于采用发收全双工方式,最后一个空操作指令周期内收到的数据包含角度数据。

角度数据处理

对于角度数据有两种处理方式:

  1. 设置零点位置,然后直接用读出的角度数据
  2. 不设置零点位置,STM32芯片上电时先读取当前位置数据作为“零点”,在后面进行算法处理。

下面例程采用第二种方式的实现。

STM32例程

例程采用STM32F103ZET6芯片开发板,以及采用STM32CUBEIDE开发环境。
首先建立工程并设置时钟,将外部8MHz时钟倍频到系统时钟。


采用USART1异步串口输出数据,配置USART1为115200波特率:


采用SPI1作为AS5048A的通讯接口,进行配置:


SPI片选信号由GPIO逻辑控制,需要单独配置:

然后实现代码,通过串口将角度数据输出,帧头为0x55 0xaa, 然后是2个字节16位的角度数据。360度范围对应0 ~ (16384-1)的输出。

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
//Written by Pegasus Yu
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define __AS5048A2_CS_ENABLE() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define __AS5048A2_CS_DISABLE() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)#define __Read_NOP 0xc000
#define __Read_Clear_Error_Flag 0x4001
#define __Read_Angle 0xffff/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;UART_HandleTypeDef huart1;/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint16_t SPI_TX_DATA[10]={0};
uint16_t SPI_RX_DATA[10]={0};const uint8_t op_num = 4;
uint16_t origin_value = 0;
uint8_t i;uint8_t TXD[4]={0};
uint16_t post_process_value=0;
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* 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_SPI1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */TXD[0]=0x55; TXD[1]=0xaa;//frame headSPI_TX_DATA[0] =  __Read_Clear_Error_Flag;SPI_TX_DATA[1] =  __Read_NOP;SPI_TX_DATA[2] =  __Read_Angle;SPI_TX_DATA[3] =  __Read_NOP;for (i = 0; i<op_num; i++){__AS5048A2_CS_ENABLE();HAL_SPI_TransmitReceive (&hspi1, &SPI_TX_DATA[i], &SPI_RX_DATA[i], 1, 2710);__AS5048A2_CS_DISABLE();HAL_Delay(1);}origin_value = SPI_RX_DATA[3]&0x3fff;/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */for (i = 0; i<op_num; i++){__AS5048A2_CS_ENABLE();HAL_SPI_TransmitReceive (&hspi1, &SPI_TX_DATA[i], &SPI_RX_DATA[i], 1, 2710);__AS5048A2_CS_DISABLE();HAL_Delay(1);}if ( (SPI_RX_DATA[3]&0x3fff)>=origin_value ) post_process_value= (SPI_RX_DATA[3]&0x3fff)-origin_value;else post_process_value= 16384-origin_value+(SPI_RX_DATA[3]&0x3fff);TXD[2] = (post_process_value&0xff00)>>8;TXD[3]= post_process_value&0x00ff;HAL_UART_Transmit(&huart1, TXD, 4, 0xffff); HAL_Delay(1);}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/*** @brief SPI1 Initialization Function* @param None* @retval None*/
static void MX_SPI1_Init(void)
{/* USER CODE BEGIN SPI1_Init 0 *//* USER CODE END SPI1_Init 0 *//* USER CODE BEGIN SPI1_Init 1 *//* USER CODE END SPI1_Init 1 *//* SPI1 parameter configuration*/hspi1.Instance = SPI1;hspi1.Init.Mode = SPI_MODE_MASTER;hspi1.Init.Direction = SPI_DIRECTION_2LINES;hspi1.Init.DataSize = SPI_DATASIZE_16BIT;hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;hspi1.Init.NSS = SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;hspi1.Init.TIMode = SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial = 10;if (HAL_SPI_Init(&hspi1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */}/*** @brief USART1 Initialization Function* @param None* @retval None*/
static void MX_USART1_UART_Init(void)
{/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);/*Configure GPIO pin : PA4 */GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state *//* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

此例程持续向USART1输出从AS5048A读取到的角度数据。

–End–

STM32 SPI获取磁性角度传感器AS5048A角度数据相关推荐

  1. STM32多通道ADC采样获取GY-25A倾角传感器模拟输出数据

    STM32多通道ADC采样获取GY-25A倾角传感器模拟输出数据 GY-25A模块是新型的倾角传感器模块,具有X和Y两轴模拟角度输出和串口角度输出的功能.这里介绍STM32获取GY-25A模拟输出的角 ...

  2. STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码

    STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码 本文采用的芯片为STM32F103RCT6 温度芯片为MAX6675 因为芯片的spi口只有3个,有部分需要外接W25Q128 ...

  3. STM32+MAX6675利用SPI获取实时温度数据程序及代码

    之前写的STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码 本文采用的芯片为STM32F103RCT6 温度芯片为MAX6675 模拟spi之前写过 里面的部分代码摘取的正点原子 ...

  4. STM32 MCO+SPI获取24位模数转换(24bit ADC)高速芯片ADS1271采样数据

    STM32 MCO+SPI获取24位模数转换(24bit ADC)高速芯片ADS1271采样数据 STM32大部分芯片只有12位的ADC采样性能,如果要实现更高精度的模数转换如24位ADC采样,则需要 ...

  5. STM32 BMP280模块 获取气压温度高度传感器数据 TFT显示

    STM32 BMP280模块 获取气压温度高度传感器数据 TFT显示 简介 BMP280是博世最新推出的数字气压传感器,具有卓越的性能和低廉的价格,相对精度为±0.12 hPa(相当于±1米),传感器 ...

  6. STM32+MAX6675 获取4路温度数据原理图及代码

    STM32+MAX6675 获取4路温度数据原理图及代码 说明:1.片选任意IO管脚即可,低电平有效! 2.K型热电偶分别接T+,T-: 3.介于STM32只读,就只用3根线,SO,SCL,CS 见图 ...

  7. 通俗理解STM32 SPI通信(主从双机SPI通信)

    STM32 SPI通信 高速全双工的通信总线 SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK.MOSI.MISO,片选线为NSS(CS) NSS 信号线由高变低 ,是 SPI 通讯的起 ...

  8. STM32——SPI接口

    STM32--SPI接口 宗旨:技术的学习是有限的,分享的精神是无限的. 一.SPI协议[SerialPeripheral Interface] 串行外围设备接口,是一种高速全双工的通信总线.在ADC ...

  9. stm32 SPI、FLASH

    main.c FLASH:掉电后数据不丢失,U 盘.SD 卡.SSD 固态硬盘.STM32 芯片内部用于存储程序的设备,都是 FLASH 类型的存储器.FLASH芯片(W25Q64)是一种使用 SPI ...

  10. stm32 SPI架构

    STM32 芯片集成了专门用于 SPI 协议通讯的外设. 通讯引脚:SPI 硬件架构从 MOSI.MISO.SCK 及 NSS 线展开:STM32 芯片有多个 SPI 外设,它们的 SPI 通讯信号引 ...

最新文章

  1. 矩阵计算在计算机科学中,开发者必读:计算机科学中的线性代数(附论文)
  2. R使用lm构建单变量线性回归模型
  3. Unity中有两种Animation Clip
  4. 10万点击率的“干货”,其实人人都写得出来
  5. 没推送功能,你好意思叫APP嘛?
  6. C++ 指向类成员的指针
  7. 数据结构 —— 树状数组
  8. java因子的计算方法是_JAVA分解质因子
  9. c# 低功耗蓝牙_C#建立从笔记本电脑内部蓝牙4.0到蓝牙低功耗(BLE)外设的流
  10. 〖Linux〗以后台方式启动/结束指定程序/命令(不受 exit 或点击窗口关闭按钮等终端退出操作的影响)...
  11. weka安装需要java不_如何下载安装Weka机器学习工作平台
  12. IDEA设置主题样式
  13. gitlab 多人协同工作
  14. 只有英语四级和计算机二级,通过英语四级和计算机二级用英语怎么说
  15. tablayou设置固定下划线和根据文字显示长短显示下划线
  16. 服务器UDIMM, LRDIMM,RDIMM三种内存的区别
  17. 微信小程序创建节点选择器获取宽高wx.createSelectorQuery
  18. Android6.0以上系统搜索不到 蓝牙BLE 设备问题
  19. 数据分析-面试(SQL真题)
  20. RV1126RV1109 buildroot 增加串口屏测试

热门文章

  1. 解读2017年云计算发展趋势 — 简本
  2. Flutter Animation动画
  3. 苹果CMS v10模板:大橙子vfed完美版视频网站模板
  4. 苹果cms大橙子和B站模板教程
  5. git push 遇到的rejected问题
  6. Java中的私有权限(private)
  7. 靶机渗透练习21-Noob
  8. 铲雪车(snow) UVA10203 Snow Clearing 题解
  9. Discuz大气游戏风格模板/仿lol英雄联盟游戏DZ游戏模板GBK
  10. 66个求职应聘技巧性问答(六)