【STM32】软件SPI读取14位编码器AS5047D的代码分享
·
1.代码思路
给AS5047D发指令,AS5047D回传数据。但是发指令需要注意是16位数据(校验位+读写位+寄存器地址),接收的 数据也是16位数据(校验位+错误位+14绝对位置编码值0~16384)。
硬件连接:
PC8 -> CSN
PC7 -> SCK
PC6 -> MISO
PC0 -> MOSI
2.SPI时序图

3.寄存器地址

4.写指令读数据框架图

5.代码
main.c
#include "main.h"
uint8_t mg_data=0;
uint16_t angle_data=0;
float angle=0;
uint32_t data1=0;
/**
* @brief 上电初始化
*/
void setup(void)
{
NVIC_Conflg();
OLED_Init();
Key_Init();
Beep_Init();
AS5047D_Init();
OLED_ShowString(1,1,"all init");
}
/**
* @brief while(1)
*/
void loap(void)
{
for(;;)
{
angle_data = AS5047D_GetAngleComData(); // 0~16384
angle = (float)angle_data / 16384.0f * 360.0f;
OLED_ShowBinNum(2, 1, angle_data, 16);
OLED_ShowNum(3, 1, angle_data, 6);
OLED_ShowFloat(4, 1, angle, 3, 2);
}
}
AS5047D.h
#ifndef __AS504D_H_
#define __AS5047D_H_
/**** 头文件 ****/
#include "main.h"
/**** 宏定义 ****/
/**** 函数 ****/
void AS5047D_Init(void);
uint16_t AS5047D_GetAngleUncData(void);
uint16_t AS5047D_GetAngleComData(void);
#endif // __AS5047D_H_
AS5047D.c
#include "AS5047D.h"
#define AS5047D_Enable() GPIOC->BRR |= GPIO_PIN_8
#define AS5047D_Disable() GPIOC->BSRR |= GPIO_PIN_8
static void AS5047D_W_SCK(uint8_t bit)
{
if(bit)
GPIOC->BSRR |= GPIO_PIN_7;
else
GPIOC->BRR |= GPIO_PIN_7;
}
static uint8_t AS5047D_R_MISO(void)
{
return HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_6);
}
static void AS5047D_W_MOSI(uint8_t bit)
{
if(bit)
GPIOC->BSRR |= GPIO_PIN_0;
else
GPIOC->BRR |= GPIO_PIN_0;
}
/**
* @brief AS5047D 软件SPI 初始化
*/
void AS5047D_Init(void)
{
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct={0};
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_7 | GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
AS5047D_Disable();
AS5047D_W_SCK(0);
}
/***********************************************************
*@fuction : AS5047D_GetAngleUncData
*@brief : AS5047D 读取无动态补偿角度的原始数据 0~16384
*@param : None
*@return : 角度数据 0~16384
*@author : HongScholar
*@date : 2025.09.08
***********************************************************/
uint16_t AS5047D_GetAngleUncData(void)
{
uint16_t tx_data=0; // 校验位 + 读写位 + 寄存器地址
uint16_t rx_data=0; // 校验位 + 错误位 + 数据
AS5047D_Enable();
/**** 校验位 + 读写位 + 寄存器地址 ****/
tx_data = (1 << 15) | (1 << 14) | (0x3FFE);
/**** 发命令 ****/
for (uint8_t i=0; i<16; i++)
{
AS5047D_W_MOSI(tx_data & (0x8000 >> i));
AS5047D_W_SCK(1);
if(AS5047D_R_MISO() == 1)
{
rx_data |= (0x8000 >> i);
}
AS5047D_W_SCK(0);
}
/**** 获取角度信息 ****/
for (uint8_t j=0; j<16; j++)
{
AS5047D_W_MOSI(1); // 无效数据位
AS5047D_W_SCK(1);
if(AS5047D_R_MISO() == 1)
{
rx_data |= (0x8000 >> j);
}
AS5047D_W_SCK(0);
}
rx_data &= 0x3fff; // 高二位不要
AS5047D_Disable();
return rx_data;
}
/***********************************************************
*@fuction : AS5047D_GetAngleComData
*@brief : AS5047D 读取动态补偿角度的原始数据 0~16384
*@param : None
*@return : 角度数据 0~16384
*@author : HongScholar
*@date : 2025.09.08
***********************************************************/
uint16_t AS5047D_GetAngleComData(void)
{
uint16_t tx_data=0; // 校验位 + 读写位 + 寄存器地址
uint16_t rx_data=0; // 校验位 + 错误位 + 数据
AS5047D_Enable();
/**** 校验位 + 读写位 + 寄存器地址 ****/
tx_data = (0 << 15) | (1 << 14) | (0x3FFF);
/**** 发命令 ****/
for (uint8_t i=0; i<16; i++)
{
AS5047D_W_MOSI(tx_data & (0x8000 >> i));
AS5047D_W_SCK(1);
if(AS5047D_R_MISO() == 1)
{
rx_data |= (0x8000 >> i);
}
AS5047D_W_SCK(0);
}
/**** 获取角度信息 ****/
for (uint8_t j=0; j<16; j++)
{
AS5047D_W_MOSI(1); // 无效数据位
AS5047D_W_SCK(1);
if(AS5047D_R_MISO() == 1)
{
rx_data |= (0x8000 >> j);
}
AS5047D_W_SCK(0);
}
rx_data &= 0x3fff; // 高二位不要
AS5047D_Disable();
return rx_data;
}
6.演示视频
软件SPI读取AS5047D的演示视频
路还很长,感谢陪伴...
更多推荐



所有评论(0)