[英]LPC1788: Communicating with UFDC-1 using SPI
我正在使用LPC1788微控制器,正在尝试使用SPI从UFDC-1(通用频率数字转换器)发送和接收数据。 我可以在MOSI上传输数据达到最佳状态(我已经用示波器确认了这一点),但是每当我发送“获取准确性”之类的指令时,我在数据缓冲区中唯一的数据就是数据或指令我刚寄出去 未启用“回送”。
这是我的代码:
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);
}
编辑: 这是发送“设置精度”指令(0x020A)后捕获的所有我的SPI线的图像。 预计MISO上的数据在这里将毫无意义。 如果需要,我可以提供其他说明的捕获。
从上到下:
编辑2:具体来说,我要执行的操作是使用指令0x020A设置UFDC-1的精度。 该数字的最后一部分(“ 0A”)是精度数字。 在那之后,我有一个while循环,我尝试在其中读回该精度。 “获取精度”指令为0x01FF,其中“ FF”是为读取精度数字而发送的虚拟字节。 因此,当我发送“ 0x01FF”时,我希望在从UFDC-1发送回的数据中的某处读回“ 0A”。
编辑3: 这是SPI线的捕获, 这是我第一次向UFDC-1发送“获取精度”指令时。 蓝线(自上而下第二条)是MOSI,它肯定是给出了正确的命令(0x01FF)。 如果这正常工作,则UFDC-1应该在MOSI传输“ FF”的同时,在MISO上以“ 0A”(0b00001010)(即准确度数字)进行答复。 相反,我当时回传了“ 1A”,我不认为“ A”实际上来自UFDC-1,而只是来自我之前发送的“设置精度”指令(0x020A)。 这是因为我在while循环中使用了“获取精度”指令,而我正在读回的稳态值为“ 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
LPC17xx中的SSP具有用于发送和接收的FIFO。 这意味着您必须匹配SSP_SendData()
和SSP_ReceiveData()
调用,或者清空FIFO。 接收数据时,您还必须发送一个虚拟值-通常将0x00
或0xFF
用作虚拟值。
该库在SSP_ReadWrite()
执行此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()
。
最后说明:您可能不需要硬件芯片选择,因为这可以取消选择命令和响应字之间的从设备。 阅读相应的数据表,在许多情况下,这是不允许的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.