This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LAUNCHXL-F28027F:CAN#39;t 使用 SPI 接口读取 AS5048绝对编码器

Guru**** 649970 points
Other Parts Discussed in Thread: LAUNCHXL-F28027F, C2000WARE, TMS320F280039C, LAUNCHXL-F28069M, BOOSTXL-DRV8301, MOTORWARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1113944/launchxl-f28027f-can-t-read-the-as5048-absolute-encoder-using-spi-interface

器件型号:LAUNCHXL-F28027F
主题中讨论的其他器件: C2000WARETMS320F280039CLAUNCHXL-F28069MBOOSTXL-DRV8301MOTORWARE

您好!

我尝试使用 SPI 接口读取绝对编码器值(AS5048A)。  

由于我可以在 Github 上找到 AS5048A -C2000头文件、因此 我使用 它。

我发现代码 在下面的 while 循环中保持运行

 AS5048A.c 文件中的" while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){"。

我使用了该社区上的其他不使用 AS5048A.h 文件的 SPI 代码 - Link、 代码仍会进入 while 循环、无法输出。

我认为这一点低于 SPI_getRxFifoStatus 函数中的点。

  SPI_FifoStatus_e status =(SPI_FifoStatus_e)(SPI->SPIFFRx 和 SPI_SPIFFRX_FIFO_ST_BITS);<-在第二张图片中

SPI->SPIFFRX = 8196

SPI_SPIFFRX_FIFO_ST_BITS =(31<8)

请给我一些 建议来解决这个问题。

谢谢你。

这是 main.c 代码

//########################################################################################################################
//
//适用于 C2000的 AS5048A 库示例:LaunchXL-F28027F
//使用具有 FIFO 的 SPI 进行通信
//!
//########################################################################################################################


#include "DSP28x_Project.h"//器件头文件和示例 include 文件

#include "F2802x_common/include/adc.h"
#include "F2802x_common/include/clk.h"
#include "F2802x_common/include/flash.h"
#include "F2802x_common/include/gpio.h"
#include "F2802x_common/include/pie.h"
#include "F2802x_common/include/PLL.h"
#include "F2802x_common/include/SPI.h"
#include "F2802x_common/include/wdog.h"
#include "AS5048A.h"

clk_handle myClk;
Flash_handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
SPI_Handle mySpi;

AS5048A_Vars_t gAs5048aVars;

void main (void)

cpu_handle myCpu;
pll_handle myPll;
WDOG_Handle myWDog;

//初始化此应用程序所需的所有句柄
myClk = CLK_init ((void *) CLK_base_ADDR、sizeof (CLK_Obj));
myCpu = cpu_init ((void *) NULL、sizeof (cpu_Obj));
myFlash = flash_init ((void *) flash_base_ADDR、sizeof (flash_Obj));
myGpio = GPIO_init ((void *) GPIO_base_ADDR、sizeof (GPIO_Obj));
myPie = PI_init ((void *) PIE_BASE_ADDR、sizeof (PIE_Obj));
myPll = PLL_init ((void *) PLL_base_ADDR、sizeof (PLL_Obj));
mySpi = SPI_init ((void *) SPIA_BASE_ADDR、sizeof (SPI_Obj));
myWdDog = WDOG_INIT ((void *) WDOG_BASE_ADDR、sizeof (WDOG_Obj));

//执行基本系统初始化
WDOG_DISABLE (myWDog);
CLK_enableAdcClock (myClk);
(*Device_cal)();

//选择内部振荡器1作为时钟源
CLK_setOscSrc (myClk、CLK_OscSrc_Internal);

//将 PLL 设置为 x10 /2、这将产生50MHz = 10MHz * 10/2
PLL_setup (myPll、PLL_Multiplier_10、PLL_DivideSelect_CLKIN_BY_2);

//禁用 PIE 和所有中断
PIE_DISABLE (myPie);
PI_DisableAllInts (myPie);
CPU_disableGlobalInts (myCpu);
CPU_clearIntFlags (myCpu);

//如果从闪存运行,则只将 RAM 复制到 RAM
#ifdef _flash
memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
#endif

AS5048A_GPIO_init (myGpio);//初始化 SPI GPIO

//设置调试矢量表并启用 PIE
// PI_setDebugIntVectorTable (myPie);
PIE_ENABLE (myPie);

AS5048A_SPI_init (mySpi、myClk);//初始化 SPI
AS5048A_fifo_init (mySpi);//初始化 SPI FIFO

for (;;){

//如果错误标志为高电平,则读取错误寄存器并清除该标志
if (gAs5048aVars.errorFlag){
AS5048A_clearErrorReg (mySpi、&gAs5048aVars);
DELAY_US (500);

否则{
//获取角度
AS5048A_getAngle (mySpi、&gAs5048aVars);
DELAY_US (500);
//获取幅度
AS5048A_getMagnitude (mySpi、&gAs5048aVars);
DELAY_US (500);
//读取诊断寄存器
AS5048A_readDiagnosteReg (mySpi、&gAs5048aVars);
DELAY_US (500);
//写入偏移寄存器。 扩展值= 15.50
AS5048A_writeZeroPosReg (mySpi、15.50);
DELAY_US (500);
//读取偏移寄存器。
AS5048A_readZeroPosReg (mySpi、&gAs5048aVars);
DELAY_US (500);
//读取编程寄存器
AS5048A_readProgrammingReg (mySpi、&gAs5048aVars);
DELAY_US (500);


//====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
//不再需要。
//====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

这是 AS5048A.c 代码

#include
AS5048A_Obj as5048a;

//! \brief 设置 SPI 以便与 AS5048A 传感器通信
//! \param[IN] SPI_Handle、CLK_Handle
void AS5048A_SPI_init (SPI_Handle spiHandle、CLK_Handle clkHandle)

CLK_enableSpiaClock (clkHandle);

//复位打开、上升沿、16位字符位
SPI_setCharLength (spiHandle、SPI_CharLength _16_Bits);

//启用主控模式、正常相位、
SPI_setMode (spiHandle、SPI_Mode_Master);
SPI_enableTx (spiHandle);

SPI_setBaudRate (spiHandle、SPI_BAUDRAATE_1_MBaud);
SPI_setClkPhase (spiHandle、SPI_ClkPhase_Normal);
SPI_setClkPolarity (spiHandle、SPI_ClkPolarity_OutputRisingEdge_InputFallingEdge);

SPI_disableLoopBack (spiHandle);
SPI_ENABLE (spiHandle);

//设置断点以使断点不会干扰 xmission
SPI_setPriority (spiHandle、SPI_Priority_freeRun);//SPI_Priority_freeRun

//! \brief 设置 SPI FIFO 以与 AS5048A 传感器通信
//! \param[IN] SPI_Handle
void AS5048A_fifo_init (SPI_Handle spiHandle)

//初始化 SPI FIFO 寄存器
SPI_enableChannels (spiHandle);
SPI_enableFifoEnh (spiHandle);
SPI_resetTxFifo (spiHandle);
SPI_clearTxFifoInt (spiHandle);
SPI_resetRxFifo (spiHandle);
SPI_clearRxFifoInt (spiHandle);
SPI_setRxFifoIntLevel (spiHandle、SPI_FifoLevel_4_words);

//! \brief 设置 SPI GPIO 以与 AS5048A 传感器通信
//! param[IN] GPIO_Handle
void AS5048A_GPIO_init (GPIO_handle gpioHandle){
//初始化 GPIO
GPIO_setPullUp (gpioHandle、GPIO_Number_16、GPIO_PULLUP_Enable);
GPIO_setPullUp (gpioHandle、GPIO_Number_17、GPIO_PULLUP_Enable);
GPIO_setPullUp (gpioHandle、GPIO_Number_18、GPIO_PULLUP_Enable);
GPIO_setPullUp (gpioHandle、GPIO_Number_19、GPIO_PULLUP_Enable);
GPIO_setQualification (gpioHandle、GPIO_Number_16、GPIO_Qual_异 步);
GPIO_setQualification (gpioHandle、GPIO_Number_17、GPIO_Qual_Async);
GPIO_setQualification (gpioHandle、GPIO_Number_18、GPIO_Qual_Async);
GPIO_setQualification (gpioHandle、GPIO_Number_19、GPIO_Qual_异 步);
GPIO_setMode (gpioHandle、GPIO_Number_16、GPIO_16_Mode_SPISIMOA);
GPIO_setMode (gpioHandle、GPIO_Number_17、GPIO_17_Mode_SPISOMIA);
GPIO_setMode (gpioHandle、GPIO_Number_18、GPIO_18_Mode_SPICLKA);
GPIO_setMode (gpioHandle、GPIO_Number_19、GPIO_19_Mode_SPISTEA_not);

//! \brief 计算命令的偶校验
//! \param[in] uint16_t 值
uint16_t AS5048A_CalculateEvenParity (const uint16_t value){
uint16_t x =值;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
返回((~x)& 1)<<15;

//! \brief 计算命令的奇数奇偶校验
//! \param[in] uint16_t 值
uint16_t AS5048A_CalculateOddParity (const uint16_t value){
uint16_t x =值;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
返回((x)和1)<<15;

//! \brief 发送一个寄存器的读取命令,然后发送一个空命令来读取反馈
//! \param[in] spi_handle、(uint16_t)地址
uint16_t AS5048A_read (spi_handle spiHandle、const uint16_t address、bool *错误){
//添加奇偶校验
uint16_t recivedData;
uint16_t ctrlAddress;
ctrlAddress =地址| AS5048A_CalculateEvenParity (地址);
//添加读取掩码
ctrlAddress |= AS5048A_rw_mask;
//将 Rx FIFO 指针重置为零
SPI_resetRxFifo (spiHandle);
SPI_enableRxFifo (spiHandle);
//写入要读取的地址
SPI_WRITE (spiHandle、ctrlAddress);
while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){}
//阅读最后一条消息
spi_read (spiHandle);
//写入 NOP 以恢复新值
SPI_WRITE (spiHandle、AS5048A_NOP);

while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){}

//从寻址的寄存器中读取值
recivedData=SPI_Read (spiHandle);
if (recivedData & 0x4000){
*ERROR=1;

返回 RecivedData &~0xC000;

//! \brief 读取 AS5048A 上的编程寄存器
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_readProgrammingReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars){
uint16_t newData = AS5048A_read (spiHandle、AS5048A_programming_control、&SPI_AS5048A_Vars->errorFlag);
SPI_AS5048A_Vars->ProgrammingRegister.PRG_Enable =(bool)(newData &(uint16_t) AS5048A_programming_enable)?1:0;
SPI_AS5048A_Vars->ProgrammingRegister.PRG_burn =(bool)(newData &(uint16_t) AS5048A_programming_burn)?1:0;
SPI_AS5048A_Vars->ProgrammingRegister.PRG_verify =(bool)(newData &(uint16_t) AS5048A_programming_verify)?1:0;

//! \brief 读取错误寄存器并清除 AS5048A 上的错误标志
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_clearErrorReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars){
uint16_t newData = AS5048A_read (spiHandle、AS5048A_clear_error_flag、&SPI_AS5048A_Vars->errorFlag);
SPI_AS5048A_Vars->ErrorRegister.ERR_framingError =(bool)(newData &(uint16_t) AS5048A_error_frame)?1:0;
SPI_AS5048A_Vars->ErrorRegister.ERR_invalidCommand =(bool)(newData &(uint16_t) AS5048A_ERROR_INVALID_COMMAND)?1:0;
SPI_AS5048A_Vars->ErrorRegister.ERR_parityError =(bool)(newData &(uint16_t) AS5048A_error_parity)?1:0;
SPI_AS5048A_Vars->errorFlag=0;

//! \brief 从 AS5048A 读取诊断寄存器
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_readDiagnosteReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars){
uint16_t newData = AS5048A_read (spiHandle、AS5048A_DIAG_AGC、&SPI_AS5048A_Vars->errorFlag);
SPI_AS5048A_Vars->DiagnosteRegister.DIAG_AGC_AutomaticGain =(字符) newData&0xFF;
SPI_AS5048A_Vars->DiagnosteRegister.DIAG_AGC_ocf =(bool)(newData &(uint16_t) AS5048A_DIAG_AGC_OCF)?1:0;
SPI_AS5048A_Vars->DiagnosteRegister.DIAG_AGC_cof =(bool)(newData &(uint16_t) AS5048A_DIAG_AGC_COF)?1:0;
SPI_AS5048A_Vars->DiagnosteRegister.DIAG_AGC_Comp_Low =(bool)(newData &(uint16_t) AS5048A_DIAG_AGC_COMP_LOW)?1:0;
SPI_AS5048A_Vars->DiagnosteRegister.DIAG_AGC_Comp_High =(bool)(newData &(uint16_t) AS5048A_DIAG_AGC_COMP_HIGH)?1:0;

//! \brief 从 AS5048A 读取零位置
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_readZeroPosReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars){
uint16_t newDataHigh = AS5048A_read (spiHandle、0x0016、&SPI_AS5048A_Vars->errorFlag);
uint16_t newDataLow = AS5048A_read (spiHandle、0x0017、&SPI_AS5048A_Vars->errorFlag);

SPI_AS5048A_Vars->ZeroPosition .zero_POS_HI =(uint16_t) newDataHigh &(uint16_t) 0xFF;
SPI_AS5048A_Vars->ZeroPosition .zero_POS_LOW =(uint16_t) newDataLow &(uint16_t) 0x3F;
SPI_AS5048A_VARs->zeroAngle =(float)(uint16_t)(SPI_AS5048A_Vars->ZeroPosition .zero_POS_HI <6)|(uint16_t)(SPI_AS5048A_Vars->ZeroPosition.zero_low)/384.0;36384.0/Vars*s)

//! 将零点偏移位置\brief 写入 AS5048A
//! \param[IN] SPI_Handle、浮点数零角度(度数)
void AS5048A_writeZeroPosReg (SPI_Handle spiHandle、const float zeroAngle){
uint16_t 数据;
uint16_t 低电平;
uint16_t HIGH;
数据=((零角/360.0)* 16384.0);
低电平= 0x003F &数据;
HIGH =(0x3FC0 & DATA)>>6;
AS5048A_write (spiHandle、AS5048A_OTP_REGISTER_ZERO _POS_HIGH、HIGH);
AS5048A_write (spiHandle、AS5048A_OTP_register_zero_POS_low、low);

//! \brief 返回绝对(多转)旋转。 这使用 MCU 的计算
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_getAngle (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars){
float angle=AS5048A_read (spiHandle、AS5048A_angle、&SPI_AS5048A_Vars->errorFlag)*(360.0/16384.0);

float angleDiff =角度- SPI_AS5048A_Vars->angleLastCycle;
IF (angleDiff >200){
SPI_AS5048A_Vars->count--;

否则、如果(angleDiff <-200){
SPI_AS5048A_Vars->count++;

SPI_AS5048A_Vars->angleLastCycle =角度;
SPI_AS5048A_Vars->angleSingleturn =角度;
SPI_AS5048A_Vars->angleMultiTurn =SPI_AS5048A_Vars->count *360.0+SPI_AS5048A_Vars->angleSingleturn;

//! \brief 发送一个用于读取寄存器的读取命令并读取接收寄存器。(最后一个软件包)
//! \param[in] spi_handle、(uint16_t)地址
uint16_t AS5048A_stream (SPI_Handle spiHandle、uint16_t address){
//添加读取掩码
地址=地址| AS5048A_RW_MASK;
//添加奇偶校验
address |= AS5048A_CalculateEvenParity (address);
SPI_WRITE (spiHandle、address);
while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){}
返回 SPI_Read (spiHandle)&~0xC000;

//! \brief 直接从 AS5048A 返回幅度。
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_getMagnitude (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars){
SPI_AS5048A_Vars->Magnitude =AS5048A_Read (spiHandle、AS5048A_Magnitude、&SPI_AS5048A_Vars->errorFlag)/16384.0;

//! \brief 发送写入到寄存器地址,然后发送数据写入其中
//! \param[in] spi_handle、(uint16_t)地址、(uint16_t)数据
void AS5048A_write (spi_handle spiHandle、const uint16_t address、const uint16_t data){
uint16_t ctrlAddress;
uint16_t ctrlData;
uint16_t n;

//添加奇偶校验
ctrlAddress = address | AS5048A_CalculateOddParity (address);
ctrlData = data | AS5048A_CalculateOddParity (data);

//将 Rx FIFO 指针重置为零
SPI_resetRxFifo (spiHandle);
SPI_enableRxFifo (spiHandle);

SPI_WRITE (spiHandle、ctrlAddress);
//等待寄存器更新
对于(n=0;n<0xdf;n++)
asm (" NOP");
while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){}
//阅读最后一条消息
SPI_READ (spiHandle);


SPI_WRITE (spiHandle、ctrlData);
//等待寄存器更新
对于(n=0;n<0xdf;n++)
asm (" NOP");
while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){}
SPI_READ (spiHandle);

这是 AS5048A.h 代码

#ifndef _AS5048A_H_
#define _AS5048A_H_
秘书长的报告
//包括
#include

//驱动程序

//#include "sw/drivers/spi/src/32b/F28x/F2802x/spI.h"<-请勿使用
//#include "sw/drivers/gpio/src/32b/f28x/f2802x/gpio.h"<-请勿使用
#include "DSP28x_Project.h"//器件头文件和示例 include 文件
//#include "F2802x_common/include/spI.h"
#include "F2802x_common/include/gpio.h"
#include "F2802x_common/include/SPI.h"
#include "F2802x_common/include/clk.h"

#ifdef __cplusplus
extern "C"{
#endif

秘书长的报告
//定义

//! \brief 定义 R/W 掩码
//!
#define AS5048A_RW_MASK (1<<14)
//! \brief 定义“无操作”掩码
//!
#define AS5048A_NOP (0x00)
//! \brief 定义清除错误掩码
//!
#define AS5048A_CLEAR_ERROR_FLAG (0x0001)
//! \brief 定义编程控制掩码
//!
#define AS5048A_programming_control (0x0003)
//! \brief 定义零位置(高)掩码
//!
#define AS5048A_OTP_REGISTER_ZERO POS_HIGH (0x0016)
//! \brief 定义零位置(低)掩码
//!
#define AS5048A_OTP_REGISTER_ZERO _POS_LOW (0x0017)
//! \brief 定义诊断+自动增益控制(AGC)掩码
//!
#define AS5048A_DIAG_AGC (0x3FFD)
//! \brief 定义幅度控制掩码
//!
#define AS5048A_Magnitude (0x3FFE)
//! \brief 定义角度控制掩码
//!
#define AS5048A_ANGLE (0x3FFF)
//! \brief 定义错误寄存器中的组帧错误位
//!
#define AS5048A_ERROR_FRAME (1 << 0)
//! \brief 定义错误寄存器中的无效命令位
//!
#define AS5048A_ERROR_INVALID_COMMAND (1 << 1)
//! \brief 定义错误寄存器中的奇偶校验错误位
//!
#define AS5048A_ERROR_奇 偶校验(1 << 2)
//! \brief 定义编程寄存器中的 MODE 位
//!
#define AS5048A_programming_enable (1 << 0)
//! \brief 定义编程寄存器中保留的1位
//!
#define AS5048A_programming_RESV1 (1 << 1)
//! \brief 定义编程寄存器中保留的12位
//!
#define AS5048A_programming_RESV2 (1 << 2)
//! \brief 定义编程寄存器中的刻录位
//!
#define AS5048A_programming_burn (1 << 3)
//! \brief 定义编程寄存器中保留的3位
//!
#define AS5048A_programming_RESV3 (1 << 4)
//! \brief 定义编程寄存器中保留的4位
//!
#define AS5048A_programming_RESV4 (1 << 5)
//! \brief 定义编程寄存器中的校验位
//!
#define AS5048A_programming_verify (1 << 6)
//! \brief 定义诊断+自动增益控制寄存器中的 OCF 位
//!
#define AS5048A_DIAG_AGC_OCF (1 << 8)
//! \brief 定义诊断+自动增益控制寄存器中的 COF 位
//!
#define AS5048A_DIAG_AGC_COF (1 << 9)
//! \brief 定义诊断+自动增益控制寄存器中的 Comp Low 位
//!
#define AS5048A_DIAG_AGC_COMP_LOW (1 << 10)
//! \brief 定义诊断+自动增益控制寄存器中的 Comp High 位
//!
#define AS5048A_DIAG_AGC_COMP_HIGH (1 << 11)


//! \Error 寄存器的简要枚举。 所有错误均可通过访问清除
//!
typedef 枚举

ERR_framingError = AS5048A_ERROR_FRAME、//!<帧错误
ERR_INVALIDCommand = AS5048A_ERROR_INVALID_COMMAND、//!<命令无效
ERR_parityError = AS5048A_ERROR_奇 偶校验、//!<奇偶校验错误
} AS5048A_errorRegister_e;

//! \brief 编程寄存器的枚举。
//! 必须在烧断保险丝之前启用编程。 是一个
//! 必须进行验证。
//!
typedef 枚举

PRG_Enable = AS5048A_programming_enable、//!<启用编程
PRG_RSV1 = AS5048A_programming_RESV1、//!<保留
PRG_RSV2 = AS5048A_programming_RESV2、//!<保留
PRG_BURN = AS5048A_programming_burn、//!<刻录
PRG_RSV3 = AS5048A_programming_RESV3、//!<保留
PRG_RSV4 = AS5048A_programming_RESV4、//!<保留
PRG_VERIFY = AS5048A_programming_verify、//!<验证
} AS5048A_programmingRegister_e;

//! \볲 略 Diagnostics + AutomaticGain Control 寄存器的枚举。
//!
typedef 枚举

DIAG_AGC_OCV = AS5048A_DIAG_AGC_OCF、//!<偏移补偿完成
DIAG_AGC_COF = AS5048A_DIAG_AGC_COF、//!< CORDIC 溢出
DIAG_AGC_Comp_Low = AS5048A_DIAG_AGC_COMP_LOW、//!<表示高磁场。 建议在监测幅度值的同时进行监测。
DIAG_AGC_Comp_High = AS5048A_DIAG_AGC_COMP_HIGH、//!<表示磁场较弱。 建议监控幅度值。
} AS5048A_DIAG_AGcRegister_e;

//! 用于编程寄存器的\brief 对象
//!
typedef 结构_AS5048A_Error_

bool ERR_framingError;//位0
bool ERR_invalidCommand;//位1
bool ERR_parityError;//位2
}AS5048A_Error_;

//! 用于编程寄存器的\brief 对象
//!
typedef 结构_AS5048A_Programming_

bool PRG_Enable;//位0
bool PRG_RSV1;//位1
bool PRG_RSV2;//位2
bool PRG_BURN;//位3
bool PRG_RSV3;//位4
bool PRG_RSV4;//位5
bool PRG_VERIFY;//位6

}AS5048A_Programming_;
//! \brief 对象,用于诊断+自动增益控制(AGC)寄存器
//!
typedef 结构_AS5048A_Diag AGC_

CHAR DIAG_AGC_automaticGain;//位0-7
bool DIAG_AGC_ocf;//位8
bool DIAG_AGC_cof;//位9
bool DIAG_AGC_Comp_Low;//位10
bool DIAG_AGC_Comp_High;//位11
}AS5048A_Diag AGC_;


//! 针对 OTP 寄存器零位置低寄存器的\brief 对象
//!
typedef 结构_AS5048A_Zero_position_

uint16_t zero_POS_HI;//位7-0
uint16_t zero_POS_LOW;//位5-0
}AS5048A_Zero_Position_;

//! \brief 对象,用于 AS5048A 寄存器和命令
//!
typedef struct _AS5048A_Vars_t_

AS5048A_Error_ ErrorRegister;
AS5048A_Programming_ProgrammingRegister;
AS5048A_Zero_Position_ZeroPosition;
AS5048A_DIAG_AGC_诊断寄存器;
int16_t 计数;
浮点 angleLastCycle;
浮子 angleSingleturn;
浮动弯角多转;
浮点数幅度;
浮点零角;
bool errorFlag;
}AS5048A_Vars_t;
typedef 结构_AS5048A_Obj_

浮点 A;
}AS5048A_Obj;
//! \brief 定义 AS5048A 句柄
//!
typedef struct _AS5048A_Obj_* AS5048A_handle;

秘书长的报告
//函数
//! \brief 设置 SPI 以便与 AS5048A 传感器通信
//! \param[IN] SPI_Handle、CLK_Handle
void AS5048A_SPI_init (SPI_Handle spiHandle、CLK_Handle clkHandle);

//! \brief 设置 SPI FIFO 以与 AS5048A 传感器通信
//! \param[IN] SPI_Handle
void AS5048A_fifo_init (SPI_Handle spiHandle);

//! \brief 设置 SPI GPIO 以与 AS5048A 传感器通信
//! param[IN] GPIO_Handle
void AS5048A_GPIO_init (GPIO_handle gpioHandle);

//! \brief 计算命令的偶校验
//! \param[in] uint16_t 值
uint16_t AS5048A_CalculateEvenParity (const uint16_t value);

//! \brief 计算命令的奇数奇偶校验
//! \param[in] uint16_t 值
uint16_t AS5048A_CalculateOddParity (const uint16_t value);

//! \brief 发送一个寄存器的读取命令,然后发送一个空命令来读取反馈
//! \param[in] spi_handle、(uint16_t)地址
uint16_t AS5048A_read (SPI_Handle spiHandle、const uint16_t address、bool *错误);

//! \brief 读取 AS5048A 上的编程寄存器
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_readProgrammingReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars);

//! \brief 读取错误寄存器并清除 AS5048A 上的错误标志
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_clearErrorReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars);

//! \brief 从 AS5048A 读取诊断寄存器
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_readDiagnosteReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars);

//! \brief 从 AS5048A 读取零位置
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_readZeroPosReg (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars);

//! 将零点偏移位置\brief 写入 AS5048A
//! \param[IN] SPI_Handle、浮点数零角度(度数)
void AS5048A_writeZeroPosReg (SPI_Handle spiHandle、const float zeroAngle);

//! \brief 返回绝对(多转)旋转。 这使用 MCU 的计算
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_getAngle (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars);

//! \brief 发送一个用于读取寄存器的读取命令并读取接收寄存器。(最后一个软件包)
//! \param[in] spi_handle、(uint16_t)地址
uint16_t AS5048A_stream (SPI_Handle spiHandle、uint16_t address);

//! \brief 直接从 AS5048A 返回幅度。
//! \param[IN] SPI_Handle、AS5048A_Vars_t
void AS5048A_getMagnitude (SPI_Handle spiHandle、AS5048A_Vars_t * SPI_AS5048A_Vars);

//! \brief 发送写入到寄存器地址,然后发送数据写入其中
//! \param[in] spi_handle、(uint16_t)地址、(uint16_t)数据
void AS5048A_write (spi_handle spiHandle、const uint16_t address、const uint16_t data);

extern AS5048A_Obj as5048a;

#endif

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    [引用 userid="525985" URL"~μ C/support/microriers/C2000-microriers-group/C2000/f/C2000-microriers-forum/1113944/launchxl-f28027f-ca-t-read-the -as5048-absolute-encoder-using-spI-interface]SPI->SPIFFRx = 8196

    您可以参阅 C2000 MCU 技术参考手册中 SPIFFRx 寄存器的说明。 该值表示 RX FIFO 实际上没有接收到任何字符。 因此、代码一直等待 RX FIFO 不为空是很有意义的。  

    由于 SPI 在主控模式下运行、任何到 SPITXBUF 的写入都应该移入一个新值到 SPIRXBUF。 我看不到 SPI_write()函数的代码。 您是否查看过此函数以确保它写入 SPITXBUF 寄存器?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Gus、

    首先、非常感谢您的建议。

    SPI_WRITE 函数也位于 AS5048A.c 代码中。 (while (SPI_getRXFifoStatus (spiHandle)是连续循环的代码)  

    //! \brief 发送一个寄存器的读取命令,然后发送一个空命令来读取反馈
    //! \param[in] spi_handle、(uint16_t)地址
    uint16_t AS5048A_read (spi_handle spiHandle、const uint16_t address、bool *错误){
    //添加奇偶校验
    uint16_t recivedData;
    uint16_t ctrlAddress;
    ctrlAddress =地址| AS5048A_CalculateEvenParity (地址);
    //添加读取掩码
    ctrlAddress |= AS5048A_rw_mask;
    //将 Rx FIFO 指针重置为零
    SPI_resetRxFifo (spiHandle);
    SPI_enableRxFifo (spiHandle);
    //写入要读取的地址
    SPI_WRITE (spiHandle、ctrlAddress);
    while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){}
    //阅读最后一条消息
    spi_read (spiHandle);
    //写入 NOP 以恢复新值
    SPI_WRITE (spiHandle、AS5048A_NOP);

    while (SPI_getRxFifoStatus (spiHandle)=SPI_FifoStatus_empty){}

    //从寻址的寄存器中读取值
    recivedData=SPI_Read (spiHandle);
    if (recivedData & 0x4000){
    *ERROR=1;

    返回 RecivedData &~0xC000;

     ========================================================================

    在 SPI_WRITE 函数代码中、 SPITXBUF 似乎应该接收相同的数据值。

    但是、这两个值在547行之后是不同的。

    SPI->SPITXBUF = 48954

    数据= 16385

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是我的引脚配置。 我使用 Arduino 读取编码器值、它起作用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您共享附加代码。 您看到的行为很奇怪。 我建议您检查以下几点:

    1. 验证 LaunchPad 的 SPI_CLK 和 SPI_MOSI 引脚上是否存在任何活动。  
    2. 尝试 C2000ware 中的 SPI 示例之一、以验证 SPI 的功能。

    C:\ti\c2000Ware_4_01_00_00\device_support\f2802x\examples\structs

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Gus、

    我找不到任何与 SPI 示例相关的文档来验证您上面提到的 SPI 的功能。

    C:\ti\c2000Ware_4_01_00_00\device_support\f2802x\examples\structs

    请告诉我可以从哪里获取该文档吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    C2000ware 中提供了两个 SPI 示例。

    您是否熟悉从 C2000ware 导入 CCS 工程的过程? 下面是一个快速概览。

    https://dev.ti.com/tirex/explore/content/c2000_academy_2.00.01.41_all/modules/Module_2_Getting_Started/module_2_getting_started_lab.html#import-empty-project-from-c2000ware-

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很清楚、我建议尝试使用 C2000ware 示例、只是为了让您确信器件上的 SPI 工作正常。 编写 C2000ware 示例不是为了与您使用的编码器配合使用。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢!

    我已经检查了 SPI_SLK 和 SPI_MOSI 信号、如果我运行示例代码、它就会起作用。

    但是、如果我将空项目制作成了空项目并运行了相同的代码、则 SPI 信号不会输出。

    我是否可以通过任何方式复制示例项目并调整我一侧的代码? 我似乎无法更改代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在快速概览中、他们使用 了 TMS320F280039C、空驱动程序许可证位于 C2000Ware_4_01_00_00\driverlib\f28003x\examples\empty_projects 中。

    但我认为它不支持2802x 系列。  我是否只需要从新建空 项目开始? 我尝试过很多次,但不起作用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="525985" URL"~/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1113944/launchxl-f28027f-cAN-t-read-the -as5048-absolute-coder-using-spI-interface/4152456#4152456"]如果我已检查 SPI_spi_spi_example_spi_s 并运行 SPI_spi_spi_s 代码和 spi_example_spi_ise_s[。]

    这很好、因此您可以排除 EVM 的一些问题。 您现在还有一个工作代码引用。

    [引用 userid="525985" URL"~μ C/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1113944/launchxl-f28027f-ca-t-read-the -as5048-absolute-encoder-using-spI-interface/4152482#4152482"]但我认为不支持2802x 系列。  我是否只需要从新建空 项目开始? 我尝试过很多次,但不起作用。[/引述]

    您不能在 F2802x 器件上使用 F28003x 项目。 F2802x SPI 示例中没有太多代码。 如果您有一个 F2802x 空项目并将 SPI 代码复制到该项目、我想您基本上会得到原始 SPI 示例。

    我建议您继续调试原始项目、因为这是您想要开始工作的内容。 您是否 使用原始代码验证了 SPI_CLK 和 SPI_MOSI 活动?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回答!

    我调整了示例代码并成功获取编码器值。 (当我清空项目时、我仍然不知道为什么无法进行 SPI 通信)。

    现在、我尝试使用 F28069M MCU 的编码器和电机、但所有头文件都不同。 我的编码器的头文件使用"clk.h"、而 F28069M 没有它。 您能否告诉我我可以使用哪种类型的头文件来代替 clk.h?

    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    抱歉、我不理解您在寻找什么。

    [引用 userid="525985" URL"~/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1113944/launchxl-f28027f-cAN-t-read-the -as5048-absolute-encoder-use-using-spI-interface/4164723#4164723"]现在我正在尝试使用不同的 MCU 头文件、但正在尝试使用不同的 MCU 头文件和 F28069M[。]

    这一点我不清楚。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很抱歉、我的解释不正确。

    我正在尝试使用 BOOSTXL-DRV8301电机驱动器将微控制器从 LAUNCHXL-F28027F 更改为 LAUNCHXL-F28069M。
    (由于我使用的是 SPI 接口绝对编码器、BOOSTXL-DRV8301也需要另一个 SPI 接口、因此我更改为 F28069M 模型。)

    要使用编码器控制电机、我认为我需要使用 InstaSPIN-MOTION 实验12x 和13x。

    问题在于、我用于读取编码器值 的库文件基于 C2000Ware 和 F28027F 微控制器。

    在 F28027F 代码中、我在 接头下面使用了

    #include "F2802x_common/include/adc.h"
    #include "F2802x_common/include/clk.h"
    #include "F2802x_common/include/flash.h"
    #include "F2802x_common/include/gpio.h"
    #include "F2802x_common/include/pie.h"
    #include "F2802x_common/include/PLL.h"
    #include "F2802x_common/include/SPI.h"
    #include "F2802x_common/include/wdog.h"

    我想知道  、如果我使用相同的代码将上述接头更改为 MotorWare F28069M 接头、是否会起作用。
    (我在 MotorWare 中找不到任何有关 SPI 通信的文档、而实验12x 使用增量编码器)

    始终感谢您的反馈和帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    更新:我尝试了上述方法(将标题从 c2000ware F2802x 更改为 motorware F28069M)  
    例如、common/include/clk.h -> C:\ti\motorware\motorware_1_01_00_18\sw\drivers\clk\clk.h

    总之、它不起作用、因为标头不完全相同、我认为这  不是一个好的试验。

    有一些问题和答案将绝对编码器(AS5048a)和电机集成到 F28069M 上、我无法理解它们是如何获得的。

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/921727/ccs-launchxl-f28069m-problem-integrating-an-absolute-encoder-with-instaspin-motion

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/663317/launchxl-f28069m-integrating-an-absolute-rotary-position-magnetic-encoder-with-instaspin-motion

    我尝试理解他们的代码、但很难 获得。 您能给我一些建议吗?

    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的额外解释。 让我在内部跟进并尽快回复您。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    太棒了、感谢您抽出宝贵的时间为您提供帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很抱歉、我的回复很晚、我不得不咨询一些更熟悉摩托车的人。

    [引用 userid="525985" URL"~μ C/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1113944/launchxl-f28027f-ca-t-read-the -as5048-absolute-encoder-using-spI-interface/4166648#4166648"]

    更新:我尝试了上述方法(将标题从 c2000ware F2802x 更改为 motorware F28069M)  
    例如、common/include/clk.h -> C:\ti\motorware\motorware_1_01_00_18\sw\drivers\clk\clk.h

    总之、它不起作用、因为标头不完全相同、我认为这  不是一个好的试验。

    [/报价]

    我相信您需要在 CCS MotorWare 项目中更改一些内容、以使其正常工作。 我建议您查看 C2000ware 中 F2806x 开发用户指南中的"项目创建和调试入门"部分。 您不必实际创建新项目、但可以查看需要添加的文件和路径。

    C:\ti\c2000\C2000Ware_4_01_00_00\device_support\f2806x\docs

    我还想指出的是、motorware 中已经提供了 SPI 驱动程序。 您可以看到下面的路径(安装路径可能与您不同)。  如果您从头开始编写编码器代码、 则可以更轻松地利用这些 motorware 驱动程序来访问编码器。

    C:\ti\c2000\motorware\motorware_1_01_00_18\sw\drivers\spi\src\32b\F28x\f2806x

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Gus、

    非常感谢您的帮助!

    目前 、我已经从 F28027F 中读取了编码器值、我解决了这个问题。

    现在、我发布了一个新问题、即有关具有 AS5048A 编码器的 F28069M 的问题。

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1126154/launchxl-f28069m-read-the-absolute-encoder-values-by-spi-communication-in-c2000ware-as5048a

    谢谢!