2013-07-17 27 views
0

我正在使用LPC1788微控制器,我正尝试使用SPI发送和接收来自UFDC-1(通用频率 - 数字转换器)的数据。我可以通过MOSI传输数据给它(我已经用示波器证实了这一点),但每当我发送像“获取准确性”这样的指令时,我在数据缓冲区中唯一的数据就是数据或指令我刚刚发送。 “回送”未启用。LPC1788:使用SPI与UFDC-1进行通信

这是我的代码:

SSP_CFG_Type sspConfig; 
SSP_DATA_SETUP_Type sspData; 
LPC_SSP_TypeDef *SSPx = NULL; 

UFDC_RESULT_T result_SSP0_FX1, result_SSP0_FX2; 
UFDC_RESULT_T result_SSP1_FX1, result_SSP1_FX2; 
UFDC_RESULT_T *result, *resultFX1, *resultFX2 = NULL; 

uint8_t resultSign; 
uint64_t resultInt, resultFract; 

uint8_t SSP0resultFX1sign, SSP0resultFX2sign; 
uint8_t SSP1resultFX1sign, SSP1resultFX2sign; 

uint64_t SSP0resultFX1int, SSP0resultFX2int; 
uint64_t SSP1resultFX1int, SSP1resultFX2int; 

uint64_t SSP0resultFX1fract, SSP0resultFX2fract; 
uint64_t SSP1resultFX1fract, SSP1resultFX2fract; 

uint16_t getAccInstr = 0x01FF; 
uint16_t setAccInstr = 0x020A; 
uint16_t checkStatusInstr = 0x03FF; 
uint16_t setMeasureModeInstr1 = 0x0600; 
uint16_t setMeasureModeInstr2 = 0x060E; 
uint16_t getBCDResultInstr = 0x07FF; 
uint8_t startMeasureInstr = 0x09; 

uint32_t measureInstr; 

uint8_t txData[2]; 
uint8_t rxData[2]; 

uint16_t data; 

sspConfig.CPHA = SSP_CPHA_FIRST; 
sspConfig.CPOL = SSP_CPOL_HI; 
sspConfig.ClockRate = 100000; 
sspConfig.Databit = SSP_DATABIT_16; 
sspConfig.Mode = SSP_MASTER_MODE; 
sspConfig.FrameFormat = SSP_FRAME_SPI; 

sspData.tx_data = txData; 
sspData.rx_data = rxData; 
sspData.length = 2; 

printf("Initialising SSP0 and SSP1...\n\n"); 

PINSEL_ConfigPin(0, 15, 2); // SSP0_SCK 
PINSEL_ConfigPin(0, 16, 2); // SSP0_SSEL 
PINSEL_ConfigPin(0, 17, 2); // SSP0_MISO 
PINSEL_ConfigPin(0, 18, 2); // SSP0_MOSI 
PINSEL_ConfigPin(0, 6, 2); // SSP1_SCK 
PINSEL_ConfigPin(0, 7, 2); // SSP1_SSEL 
PINSEL_ConfigPin(0, 8, 2); // SSP1_MISO 
PINSEL_ConfigPin(0, 9, 2); // SSP1_MOSI 

PINSEL_SetFilter(0, 7, DISABLE); 
PINSEL_SetFilter(0, 8, DISABLE); 
PINSEL_SetFilter(0, 9, DISABLE); 

SSP_Init(LPC_SSP0, &sspConfig); 
SSP_Init(LPC_SSP1, &sspConfig); 
SSP_Cmd(LPC_SSP0, ENABLE); 
SSP_Cmd(LPC_SSP1, ENABLE); 

printf("Reading UDFC frequency values...\n\n"); 
for(int i=0; i < 2; i++) 
{ 
    if(i == 0) 
    { 
    SSPx = LPC_SSP0; 
    resultFX1 = &result_SSP0_FX1; 
    resultFX2 = &result_SSP0_FX2; 
    } 
    else 
    { 
    SSPx = LPC_SSP1; 
    resultFX1 = &result_SSP1_FX1; 
    resultFX2 = &result_SSP1_FX2; 
    } 

    // Set UFDC accuracy to 1%. 
    SSP_SendData(SSPx, setAccInstr); 
    while(SSPx->SR & SSP_SR_BSY); 

    // Check accuracy. 
    while(1) 
    { 
    printf("Sending data...\n"); 
    SSP_SendData(SSPx, getAccInstr); 

    while(SSPx->SR & SSP_SR_BSY); 

    // Wait to receive back data. 
    while(SSPx->SR & SSP_SR_RNE) 
    { 
     printf("Received data here: 0x%x\n", SSP_ReceiveData(SSPx)); 
    } 

    //data = SSP_ReceiveData(SSPx); 
    //printf("Accuracy check 1: %i\n", data >> 8); 
    //printf("Accuracy check 2: %i\n", data & 0xFF); 
    } 

编辑:Here是发送“设定精度”指令(0x020A)毕竟我SPI线的捕获。 MISO的数据在这里预计没有意义。如果有必要,我可以为其他指令生成捕获。

从上到下:

  • MISO
  • MOSI
  • SS
  • SCLK

编辑2:具体来说,我想要做的是设置精度UFDC-1的指令0x020A。该(“0A”)的最后部分是准确数字。在那之后,我有一段时间循环,我尝试读取准确度。 “获得准确性”指令是0x01FF,其中“FF”是为了回读准确性数字而发送的虚拟字节。因此,当我发送“0x01FF”时,我希望在从UFDC-1发回的数据中的某处读回“0A”。

编辑3:Here是第一次向UFDC-1发送“获取精度”指令时SPI线的捕捉。蓝线(从顶部开始第二个)是MOSI,它肯定会给出正确的命令(0x01FF)。如果这项工作正常进行,UFDC-1应在MOSO传输“FF”的同时以“0A”(0b00001010)(这是准确性编号)在MISO上进行回复。相反,当时我发回了“1A”,我不相信“A”实际上来自UFDC-1,而是来自我之前发送的“设置准确性”指令(0x020A)。这是因为我在while循环中执行了“get accuracy”指令,而我读回的稳态值是“0x7F00” - 与UFDC-1的准确数字无关。

这是我的输出如下:

Initialising SSP0 and SSP1... 

Reading UDFC frequency values... 

Sending data... 
Received data here: 0xff00 
Received data here: 0xa1a 
Sending data... 
Received data here: 0xff00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 
Received data here: 0x7f00 
Sending data... 

编辑:原来,问题是与CPOL和CPHA位。它们都从0变为1.这似乎让SPI控制器与UFDC正确交互。

剩下的一个问题是SPI时钟在MISO上的随机数据上。例如,我有一个while循环,我希望只返回“0xedff”。我得到的却是:

Data : 0xedff 
Data : 0xffff 
Data : 0xff01 
Data : 0xffff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
Data : 0xedff 
+1

我不太明白你的问题。但我猜你正在等待缓冲区中收到的数据,但没有得到它。你看过UFDC-1数据表上的SPI信号吗?我不知道你的功能如何处理芯片选择线。大多数SPI外设集成电路确实需要主器件选择芯片以响应命令。 “ – Thanushan

+0

”但我猜你正在等待缓冲区中收到的数据,但没有得到它。“是的。我会通过澄清更新这个问题。 “大多数SPI外设集成电路确实需要主控芯片选择芯片来响应命令。”我的微控制器似乎正在自动处理这个问题,这取决于我从示波器获取的数据。从机选择似乎被按下直到整个命令被发送。 – Tagc

+1

您是否从UFDC-1收到任何回复,并查看范围?我认为芯片选择线由SSP_SendData()和SSP_ReceiveData处理。但UFDC-1可能希望保持低电平直到响应被发送,即在写入指令后不拉高,然后将其拉低以接收数据(只是猜测)。 – Thanushan

回答

0

在LPC17xx的SSP的有两个发送FIFO和接收。这意味着您必须匹配您的SSP_SendData()SSP_ReceiveData()调用,或清空FIFO。当收到数据时,您还必须发送虚拟值 - 通常使用0x000xFF作为虚拟。

该库在SSP_ReadWrite()中执行此操作,您可以改用它。

一个简单的版本是这样的:

uint16_t spi_write_read(LPC_SSP_TypeDef* SSPx, uint16_t outgoing) 
{ 
    uint16_t incoming; 

    while(!(SSPx->SR & (1 << SSP_SR_TNF))) { ; } 
    SSPx->DR = outgoing; 
    while(!(SSPSR & (1 << SSP_SR_RNE))) { ; } 
    incoming = SSPx->DR; 

    return incoming; 
} 

此功能可以作为对你的代码都SSP_SendData()SSP_ReceiveData()的替代品。

最后说明:您可能不要想要硬件片选,因为这可以取消选择命令和响应字之间的从站。阅读相应的数据表,在很多情况下这是不允许的。

+0

我试过使用SSP_ReadWrite()以及在发送“get accuracy”指令时手动按住芯片选择线(在发送之前将其设置为其默认的GPIO功能,然后将其设置为硬件CS。检查了相应的数据表,我找不到任何关于需要手动保持芯片选择的信息 – Tagc

+0

显示代码虚拟字节的需求也适用于'SPI_ReadWrite()' –

+0

对不起,延迟响应。一个同事通过改变CPOL和CPHA位使SPI工作,在数据表中我找不到任何对它们的引用,所以这很令人讨厌,他们是这个问题 还有一个问题 - SPI现在会输入正确的数据,但它也会以一系列随机值的形式输入,我会试着找到一种方法来阻止它发生G。 – Tagc