主题中讨论的其他器件:ADS1298R、 C2000WARE
您好!
我正在尝试了解如何使用 SPI 与向我发送9个24位字的从 SPI 外设进行通信。 我开始使用提供的使用驱动程序库的示例之一、并在阅读数据表时发现 SPI 缓冲器和 FIFO 为16位宽度。 我想我可以将 DE SPI 设置为8位字、然后将字节读取为字节、但 API 显示、正如我看到的、缓冲器只读取最后一个有效字节、而"损耗"其他字节、对吗? 如何继续?
此致、
Matheus Alexandre
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.
您好!
我正在尝试了解如何使用 SPI 与向我发送9个24位字的从 SPI 外设进行通信。 我开始使用提供的使用驱动程序库的示例之一、并在阅读数据表时发现 SPI 缓冲器和 FIFO 为16位宽度。 我想我可以将 DE SPI 设置为8位字、然后将字节读取为字节、但 API 显示、正如我看到的、缓冲器只读取最后一个有效字节、而"损耗"其他字节、对吗? 如何继续?
此致、
Matheus Alexandre
大家好、Praveen
谢谢、但我已经这么做了。 我现在唯一需要测试的方法是使用 SPI 作为 slaver、但我认为它不应改变预期的行为。 我从另一个 SPI 主设备(10MHz、POL 0 PHA 0)发送、两个字的24位 宽度、0x78ABCD 和0x123456。 我在 sData++上使用断点、第一次暂停时、我在 RDATA 上看到0x00000178、第二次暂停时看到 0x0000345E、然后我从主器件重新发送相同的数据、并在第三次暂停0x00005E78和第四次暂停0x00003456上看到。
#include "driverlib.h"
#include "device.h"
//
循环运行的次数(如果需要增加次数)
//
uint16_t loop_count = 100;
//
函数原型
//
void initSPI (void);
void initSPI_gpio (void);
//
Main
//
void main (void)
{
uint16_t sData = 2; //发送数据
uint32_t RDATA = 0; //接收数据
uint32_t i = 0;
//
//初始化设备时钟和外设
//
device_init();
//
//禁用引脚锁定并启用内部上拉。
//
DEVICE_initGPIO();
//
//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
interrupt_initVectorTable();
//
//设置 SPI,将其初始化为 FIFO 模式
//
initspi();
initspi_gpio();
//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;
//
//永久循环。 暂停或放置断点以观察缓冲区。
//
while (1)
{
RDATA = SPI_READDataBlockingNonFIFO (SPIB_BASE);
sData++;
Example_PassCount++;
对于(i=0;i<2000000;i++)
{
}
}
void initSPI()
{
SPI_disableModule (SPIB_BASE);
SPI_setConfig (SPIB_BASE、DEVICE_LSPCLK_FREQ、SPI_PROT_POL0PHA0、
SPI_MODE_SLAVE、10000000、8);
SPI_setEmulationMode (SPIB_BASE、SPI_emulation_free_run);
spi_enableModule (SPIB_BASE);
}
void initspi_gpio()
{
EALLOW;
//SPI B 配置
GPIO_setPadConfig (63、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (64、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (65、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (66、GPIO_PIN_TYPE_PULLUP);
GPIO_setDirectionMode (63、GPIO_DIR_MODE_IN);
GPIO_setDirectionMode (64、GPIO_DIR_MODE_OUT);
GPIO_setDirectionMode (65、GPIO_DIR_MODE_IN);
GPIO_setDirectionMode (66、GPIO_DIR_MODE_IN);
GPIO_setQualificationMode (63、GPIO_QUAL_异 步);
GPIO_setQualificationMode (64、GPIO_QUAL_异 步);
GPIO_setQualificationMode (65、GPIO_QUAL_异 步);
GPIO_setQualificationMode (66、GPIO_QUAL_异 步);
GPIO_setPinConfig (GPIO_63_SPISIMOB);
GPIO_setPinConfig (GPIO_64_SPISOMIB);
GPIO_setPinConfig (GPIO_65_SPICLKB);
GPIO_setPinConfig (GPIO_66_SPISTEB);
EDIS;
}
您可能需要考虑使用 McBSP。 以下是指向教程的链接... http://www.add.ece.ufl.edu/4511/references/McBSP%20Tutorial.pdf
您好、Matheus、
您将使用什么作为主器件?配置的时钟速度是多少? 请注意 、C2000器件不一定与为其他器件定义的其他"模式"保持一致。 相位和极性位意味着不同的东西。 请参阅用户指南以确定您的发送和接收边沿是什么、并将它们与主芯片进行比较。 不要只匹配相位= 0和极性= 0、并假设模式相同。 请参阅 TRM 中的 SPI 时钟方案部分。
此致、
Praveen
Praveen、我使用了 Analog DISCOVERY 2中的协议分析 器、f28379d 中配置的时钟频率为 DEVICE_SYSCLK_FREQ = 200MHz、DEVICE_LSPCLK_FREQ = 50MHz 和 SPI 频率10MHz。 我确信模拟发现的频率、POL 和 PHA 配置良好、因为我之前已经使用过它。 我将尝试按照 Todd 的建议使用 McBSP 模块、不要太过分。
很抱歉、如果是双帖子、我忘记回复 Praveen。
大家好、Praveen
很抱歉耽误你的时间、我正在处理2个不同的项目。
我想我已经明白了、我正在不间断地使用 SPI 的 FIFO 使能。 我还无法测试 MISO。
我对 SPI 仍有一些疑问:
1) 1)使用 SPI 的 FIFO 时是否需要使用中断?
2) 2)启用 FIFO 时、8位字 SPI 是否正常工作? 因为正如我在程序上看到的、它仅在缓冲区获得16位时开始传输、即使我更改为8位字 SPI 配置也是如此。
3) 3)我不习惯与 FIFO 一起工作。 据我所知、没有填充 FIFO 的指令和其他用于启动 SPI 传输的指令、有吗?
除了驱动器库示例中的库文件之外、还有3个文件、第一个文件包含 main、SPI_ADS.c 包含与 SPI 相关的所有内容、而 spi_ads.h 包含宏。
我的最终目标是与 ADS1298R ECFE 通信。
include "driverlib.h"
#include "device.h"
#include "spi_ads.h"
// main
void main (void)
{
//
//初始化设备时钟和外设
//
device_init();
//
//禁用引脚锁定并启用内部上拉。
//
DEVICE_initGPIO();
//
//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
interrupt_initVectorTable();
//
//设置 SPI,将其初始化为 FIFO 模式
//
init_spi_ads ();
ads_reset ();
//中断_ENABLE (INT_SPIB_TX);
//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;
//
//永久循环。 暂停或放置断点以观察缓冲区。
//
while (1)
{
}
}
#include "spi_ads.h"
void init_spi_ads ()
{
EALLOW;
//SPI B 配置
GPIO_setPadConfig (SPI_MOSI、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (SPI_MISO、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (SPI_CLK、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (SPI_CS_1、GPIO_PIN_TYPE_PULLUP);
GPIO_setDirectionMode (SPI_MOSI、GPIO_DIR_MODE_OUT);
GPIO_setDirectionMode (SPI_MISO、GPIO_DIR_MODE_IN);
GPIO_setDirectionMode (SPI_CLK、GPIO_DIR_MODE_OUT);
GPIO_setDirectionMode (SPI_CS_1、GPIO_DIR_MODE_OUT);
GPIO_setQualificationMode (SPI_MOSI、GPIO_QUAL_异 步);
GPIO_setQualificationMode (SPI_MISO、GPIO_QUAL_异 步);
GPIO_setQualificationMode (SPI_CLK、GPIO_QUAL_异 步);
GPIO_setQualificationMode (SPI_CS_1、GPIO_QUAL_异 步);
GPIO_setPinConfig (GPIO_63_SPISIMOB);
GPIO_setPinConfig (GPIO_64_SPISOMIB);
GPIO_setPinConfig (GPIO_65_SPICLKB);
EDIS;
//
//必须在配置 SPI 之前将其复位
//
SPI_disableModule (SPIB_BASE);
//
// SPI 配置。 使用1MHz SPICLK 和16位字大小。
//
SPI_setConfig (SPIB_BASE、DEVICE_LSPCLK_FREQ、SPI_PROT_POL0PHA1、
SPI_MODE_MASTER、BAUD_RATE、16);
SPI_disableLoopback (SPIB_BASE);
SPI_setEmulationMode (SPIB_BASE、SPI_emulation_stop_after_transmit);
//FIFO
SPI_enableFIFO (SPIB_BASE);
SPI_enableModule (SPIB_BASE);
}
void ads_sys_command (uint16_t 命令)
{
GPIO_writePin (SPI_CS_1、0);
SPI_CYCLE (18 *波特率/DEVICE_SYSCLK_FREQ);
命令=命令<<8;
SPI_writeDataNonBlocking (SPIB_BASE、COMMAND);
SPI_CYCLE (18 *波特率/DEVICE_SYSCLK_FREQ);
GPIO_writePin (SPI_CS_1、1);
}
void ads_write_reg (uint16_t address、uint16_t reg_data)
{
GPIO_writePin (SPI_CS_1、0);
SPI_CYCLE (18 *波特率/DEVICE_SYSCLK_FREQ);
地址=(0x40|地址)<<8;
REG_DATA = REG_DATA <<8;
SPI_writeDataNonBlocking (SPIB_BASE、地址);
SPI_writeDataNonBlocking (SPIB_BASE、REG_DATA);
SPI_CYCLE (18 *波特率/DEVICE_SYSCLK_FREQ);
GPIO_writePin (SPI_CS_1、1);
}
uint16_t ads_read_reg (uint16_t 地址)
{
uint16_t dummy_data = 0x00;
uint16_t RDATA[3];
字符 I = 0;
GPIO_writePin (SPI_CS_1、0);
SPI_CYCLE (18 *波特率/DEVICE_SYSCLK_FREQ);
地址=(0x20|地址)<<8;
SPI_writeDataNonBlocking (SPIB_BASE、地址);
SPI_writeDataNonBlocking (SPIB_BASE、dummy_data);
SPI_CYCLE (18 *波特率/DEVICE_SYSCLK_FREQ);
GPIO_writePin (SPI_CS_1、1);
对于(i=0;i<4;i++)
{
RDATA[i]= SPI_readDataNonBlocking (SPIB_BASE);
}
返回(RDATA[2]);
}
void ads_reset ()
{
ADS_SYS_COMMAND (ADS_RESET);
ADS_SYS_COMMAND (ADS_SDATAC);
if (ads_read_reg (ID)!= ID_value)
{
while (1)
{
}
}
#ifndef SPI_ADS_H_
#define SPI_ADS_H_
#include "driverlib.h"
#include "device.h"
typedef char uint8_t;
#define SPI_cycle_NOP0 (n)_asm (" RPT #("#n ")|| NOP")
#define SPI_cycle_NOP_0_NOP_RATE (n)#define SPI_RATE (n_NOP_0_NOP
)#define P波特 率(n_NOP (n_NOP) 1000000
#define SPI_MOSI 63
#define SPI_MISO 64
#define SPI_CLK 65
#define SPI_CS_1 66
#define ID_VALUE 0x62
#define ID 0x00
#define CONFIG1 0x01
#define CONFIG2 0x02
#define CONFIG3 0x03
#define LOFF 0x04
#define CH1SET 0x05
#define CH2SET 0x06
#define CH3SET 0x07
#define CH4SET 0x08
#define CH5SET 0x09
#define CH6SET 0x0A
#define CH7SET 0x0B
#define CH8SET 0x0C
#define RLD_SENSP 0x0D
#define RLD_SENSN 0x0E
#define LOFF_SENSP 0x0F
#define LOFF_SENSN 0x10
#define LOFF_FLIP 0x11
#define LOFF_STATP 0x12
#define LOFF_STATN 0x13
#define GPIO 0x14
#define PACE 0x15
#define RESP 0x16
#define CONFIG4 0x17
#define WCT1 0x18
#define WCT2 0x19
#define ADS_WAKEUP 0x02
#define ADS_STANDBY 0x04
#define ADS_RESET 0x06
#define ADS_START 0x08
#define ADS_STOP 0x0A
#define ADS_RDATAC 0x10
#define ADS_SDATAC 0x11
#define ADS_RDATA 0x12
void init_spi_ads (void);
void ads_sys_command (uint16_t 命令);
void ads_write_reg (uint16_t address、uint16_t reg_data);
uint16_t ads_read_reg (uint16_t address);
void ads_reset (空);
#endif /* SPI_ADS_H_*
您好、Matheus、
请在下面找到我的答案:
1) 1)使用 SPI 的 FIFO 时是否需要使用中断?
[Praveen]:是的,如果 CPU 带宽受限,可以选择使用中断。 对于 FIFO 配置、您可以参阅 c2000ware 中的 SPI_ex2_loopback_fifo_interrupts 示例。
2) 2)启用 FIFO 时、8位字 SPI 是否正常工作? 因为正如我在程序上看到的、它仅在缓冲区获得16位时开始传输、即使我更改为8位字 SPI 配置也是如此。
[Praveen]:是的、FIFO 适用于 SPICHAR 寄存器的所有有效配置。 请参阅 TRM 中 SPI 章节下的"数据格式"部分。
必须根据 TX/RXBUF 对数据进行正确对齐
3) 3)我不习惯与 FIFO 一起工作。 据我所知、没有填充 FIFO 的指令和其他用于启动 SPI 传输的指令、有吗?
[Praveen]:没有、如果移位寄存器空闲、任何写入 FIFO 的操作都会触发一个传输。
此致、
Praveen