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.

[参考译文] CCS/EK-TM4C123GXL:我无法通过 SPI 读取 ADXL345数据

Guru**** 2611705 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/771919/ccs-ek-tm4c123gxl-i-am-having-trouble-reading-adxl345-data-through-spi

器件型号:EK-TM4C123GXL

工具/软件:Code Composer Studio

我没有从外设获得任何读取(ADXL345)

我尝试读取器件 ID (应为0xe5)、但返回0。 我得到的所有数据值都是0。

以下是我的代码:

#include 
#include 
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/uartstdio.h"
#define

0x8000

/
define IDes/#define 0x8000 0x00
#define THRESH_TAPE 0x1D
#define OFSX 0x1E
#define OFSY 0x1f
#define OFSZ 0x20
#define Dur.(定义持续时间 0x21
#define 延迟 0x22
#define 窗口 0x23
#define THRESH_ACT 0x24
#define THRESH_INACT 0x25
#define TIME_INACT 0x26
#define ACT_INACT_CTL 0x27
#define THRESH_FF 0x28
#define TIME_FF 0x29
#define TAP_Axes 0x2A
#define ACT_TAP_STATUS 0x2B
#define BW_RATE 0x2C
#define POWER_CTL 0x2D
#define INT_ENABLE 0x2E
#define INT_MAP 0x2F
#define INT_SOURCE 0x30
#define DATA_FORMAT 0x31
#define DATAX0 0x32
#define DATAX1 0x33
#define DATAY0 0x34
#define DATAY1 0x35
#define DATAZ0 0x36
#define DATAZ1 0x37
#define FIFO_CTL 0x38
#define FIFO_STATUS 0x39
//功率控制寄存器位
#define WU_0 (1<0)//唤醒模式-位0
#define WU_1 (1<<1)//唤醒模式-位1
#define 睡眠 (1<<2)//睡眠模式
#define measure (1<<3)//测量模式
#define AUTO_SLP (1<<4)//自动睡眠模式位
#define link (1<<5)//链接位

//中断使能/中断映射/中断源寄存器
位#define 溢出 (1<0)
#define 水印(1<1)
#define FREE_FALL (1<2)
#define INACTIVITY (1<3)
#define ACTIVITY (1<4)
#define DULE_TAP (1<5)
#define SINGLE_TAP (1<6)
#define DATA_READY (1<7)

//数据格式#define Bits
#RANGE 0 (1<<0)
#define RANGE_1 (1<<1)
#define Balit (1<<2)
#define FULL_RES (1<<3)

#define INT_INVERT (1<<5)
#define SPI (1<<6)
#define self_test (1<<7)

#define PIN_LOW 0x00
#define PIN_HIGH 0xFF
int I=0;
void InitConsole (void){
//启用用于 UART0引脚的 GPIO 端口 A。
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

//为端口 A0和 A1上的 UART0功能配置引脚复用。
//如果您的器件不支持引脚复用、则无需执行此步骤。
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);

//启用 UART0以便我们可以配置时钟。
SysCtlPeripheralEnable (SYSCTL_Periph_UART0);

//使用内部16MHz 振荡器作为 UART 时钟源。
UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);

//为这些引脚选择替代(UART)功能。
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

//初始化控制台 I/O 的 UART
UARTStdioConfig (0、115200、16000000);
}

void InitSPI (void){
//必须启用 SSI2外设才能使用。
SysCtlPeripheralEnable (SYSCTL_Periph_SSI2);

//启用端口 B
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);

//设置 SPI CS 引脚(到输出)
GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_5);

//将 SPI CS 设置为高电平(低电平有效)
GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_6、0xFF);

//为端口 B4、B5、B6和 B7上的 SSI2功能配置引脚复用。
GPIOPinConfigure (GPIO_PB4_SSI2CLK);
GPIOPinConfigure (GPIO_PB5_SSI2FSS);
GPIOPinConfigure (GPIO_PB6_SSI2RX);
GPIOPinConfigure (GPIO_PB7_SSI2TX);

//配置 SSI 引脚的 GPIO 设置。
GPIOPinTypeSSI (GPIO_PORTB_BASE、GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);

//为 SPI 主控模式配置和启用 SSI 端口。 使用 SSI2、
//系统时钟电源,空闲时钟低电平和低电平有效时钟输入
//飞思卡尔 SPI 模式、主控模式、1MHz SSI 频率和8位数据。
//对于 SPI 模式,可以设置 SSI 时钟的极性
//单元空闲。 您还可以配置所需的时钟边沿
//在上捕获数据。 有关的更多信息、请参阅数据表
//不同的 SPI 模式。
SSIConfigSetExpClk (SSI2_base、SysCtlClockGet ()、SSI_FRF_MOTO_MOTO_MODE_3、SSI_MODE_MASTER、1000000、 8);

//启用 SSI2模块。
SSIEnable (SSI2_base);

//从 SSI 端口读取任何残留数据。 这将确保接收
// FIFO 为空,因此我们不会读取任何不需要的垃圾。 这在这里完成
//因为 SPI SSI 模式为全双工模式,允许您发送和
//同时接收。 SSIDataGetNonBlocking 函数返回
//返回数据时为"true",未返回数据时为"false"。
//“非阻塞”函数检查接收中是否有数据
// FIFO、如果没有、则不会"挂起"。
uint32_t 报废;
while (SSIDataGetNonBlocking (SSI2_base、&aborty));
}


int main (void){

//将时钟设置为直接从外部晶振/振荡器运行。
SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);

//设置 UART 串行输出
InitConsole();

//为 SPI 通信设置 SSI2
InitSPI();

UARTprintf(".................................. \n");

GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、0x00);
SSIDataPut (SSI2_base、0x31);//数据格式
while (SSIBusy (SSI2_base));
SSIDataPut (SSI2_base、0x01);//+/- 4g
GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、0xFF);

GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、0x00);
SSIDataPut (SSI2_base、0x2D);// power_CTL
while (SSIBusy (SSI2_base));
SSIDataPut (SSI2_base、0x08);
GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、0xFF);

GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、0x00);
SSIDataPut (SSI2_base、power_CTL|测量);//将加速计置于测量模式
while (SSIBusy (SSI2_base)){}
SSIDataPut (SSI2_base、0x08);
GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、0xFF);

uint32_t device_id;
SSIDataPut (SSI2_base、read|DevID);
SSIDataGet (SSI2_base、&device_id);
while (SSIBusy (SSI2_base)){}
UARTprintf ("%i\n"、device_id);

while (1){

uint32_t 值[6];
int16_t x、y、z;




SSIDataPut (SSI2_base、read|DATAX0);
SSIDataGet (SSI2_base、&values[0]);
while (SSIBusy (SSI2_base)){}
SSIDataPut (SSI2_base、read|DATAX1);
SSIDataGet (SSI2_base、&values[1]);
while (SSIBusy (SSI2_base)){}
x =值[1]|(值[0]>8);


SSIDataPut (SSI2_base、read|DATAY0);
SSIDataGet (SSI2_base、&values[2]);
while (SSIBusy (SSI2_base)){}
SSIDataPut (SSI2_base、read|DATAY1);
SSIDataGet (SSI2_base、&values[3]);
while (SSIBusy (SSI2_base)){}
y =值[3]|(值[2]>8);


SSIDataPut (SSI2_base、read|DATAZ0);
SSIDataGet (SSI2_base、&values[4]);
while (SSIBusy (SSI2_base)){}
SSIDataPut (SSI2_base、read|DATAZ1);
SSIDataGet (SSI2_base、&values[5]);
while (SSIBusy (SSI2_base)){}
z =值[5]|(值[4]>8);

UARTprintf ("%i\t\t%i\t%i\n"、x、y、z);

SysCtlDelay (50 *(SysCtlClockGet ()/1000 /3));

}

return (0);//永远不会返回
}

这是我在 Putty 中获得的输出:

三、会议的报告

0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

0         0         0

以下是我收到的警告:

我缺少什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我无法调试您的整个代码、但我看到了一些内容。 首先、如果您在 SSI 引脚上放置逻辑分析仪、然后您可以看到 TM4C 发送的内容以及 ADXL345的响应内容、这将对您有所帮助。 接下来、再次查看 ADXL345数据表。 在 SPI 模式下、传输在 CS 低电平和 CS 高电平之间为16位。 您已将 TM4C 配置为传输8位并将 PB5配置为 SSI2FSS。 这意味着它将在开始时变为低电平、在每个8位传输结束时变为高电平。 由于将引脚配置为 SSI2FSS,因此 GPIOPinWrite()调用将被忽略。

    您有两个选项、

    1:使用16位传输和 SSI2FSS。 这是最简单的、但不允许在单个事务中读取或写入多个字节。

    2:您可以将 PB5配置为 GPIO,并使用 GPIOPinWrite()将其切换为低电平,然后再切换为高电平。 简单灵活、但效率不是很高。 将 PB5设为低电平,然后执行两个8位 SSIDataPut (),后跟两个 SSIDataGet ()。 从第二个 SSIDataGet()返回的数据将包含 ADXL345的响应。 等到第二个 SSIDataGet ()返回后再提升 PB5。 (注:传输只发生在调用 SSIDataPut ()、SSIDataGet ()时,只会从 FIFO 返回在前一个 SSIDataPut ()期间捕获的数据。)