Je travaille avec un microcontrôleur LPC1788 et j'essaie d'envoyer et de recevoir des données à partir d'un UFDC-1 (convertisseur universel fréquence-numérique) en utilisant SPI. Je suis capable de transmettre les données à travers le MOSI (je l'ai confirmé avec un oscilloscope), mais chaque fois que j'envoie une instruction comme "obtenir la précision", les seules données que j'ai dans mon tampon de données sont les données ou instructions Je viens juste d'envoyer. "Loop back" n'est pas activé.LPC1788: Communiquer avec UFDC-1 en utilisant SPI
C'est le code que j'ai:
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);
}
Edit: Here est une capture de toutes mes lignes SPI après l'envoi d'une instruction "set précision" (0x020A). Les données à travers le MISO devraient être sans signification ici. Je peux produire des captures pour d'autres instructions si nécessaire.
De haut en bas:
- MISO
- MOSI
- SS
- SCLK
Edit 2: Plus précisément, ce que je suis en train de faire est de définir la précision de l'UFDC-1 avec l'instruction 0x020A. La dernière partie de cela ("0A") est le numéro de précision. Après cela, j'ai une boucle while où j'essaye de lire cette précision en arrière. L'instruction "get accuracy" est 0x01FF, où "FF" est un octet fictif envoyé pour lire le numéro de précision. Par conséquent quand j'envoie "0x01FF", je m'attends à lire "0A" quelque part dans les données que je reçois de l'UFDC-1.
Édition 3: Here est une capture des lignes SPI lorsque j'envoie l'instruction "get accuracy" à l'UFDC-1 pour la première fois. La ligne bleue (deuxième à partir du haut) est le MOSI, et il donne définitivement la bonne commande (0x01FF). Si cela fonctionnait correctement, l'UFDC-1 devrait répondre à travers le MISO avec "0A" (0b00001010), qui est le numéro de précision, pendant que le MOSI transmet "FF". Au lieu de cela je reçois "1A" retransmis à ce moment, et je ne crois pas que "A" vient en fait de l'UFDC-1, mais seulement de l'instruction "set accuracy" (0x020A) que j'ai envoyé plus tôt. C'est parce que j'ai l'instruction "obtenir la précision" dans une boucle while, et la valeur d'état stable que je suis en train de lire est "0x7F00" - rien à faire du tout avec le numéro de précision de l'UFDC-1.
C'est ce que ma sortie ressemble:
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...
Edit: Il s'avère que le problème était avec le CPOL et les bits ACSP. Ils ont tous deux été changés de 0 à 1. Cela semble laisser le contrôleur SPI interagir correctement avec l'UFDC. Un problème restant est que les horloges SPI dans les données aléatoires sur le MISO
Par exemple, j'ai une boucle while où je pense ne récupérer rien d'autre que "0xedff". Ce que je reçois à la place:
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
Je ne comprends pas très bien votre question. Mais je suppose que vous attendez les données reçues dans le tampon, mais ne pas l'obtenir. Avez-vous regardé le signal SPI sur la fiche technique UFDC-1? Je ne sais pas comment la ligne de sélection de puce est gérée par votre fonction. La plupart des CI périphériques SPI exigent que le maître conserve la puce sélectionnée pour répondre à une commande. – Thanushan
"Mais je suppose que vous attendez les données reçues dans le tampon, mais ne pas l'obtenir." Oui. Je vais mettre à jour la question avec des précisions. "La plupart des CI périphériques SPI exigent que le maître garde la puce sélectionnée pour répondre à une commande" Mon microcontrôleur semble gérer ceci automatiquement, basé sur les captures que j'ai reçues de l'oscilloscope. La sélection de l'esclave semble être maintenue jusqu'à ce que toute la commande soit envoyée. – Tagc
Recevez-vous une réponse de UFDC-1, en regardant avec la portée? Je pense que la ligne de sélection de puce est gérée par SSP_SendData() et SSP_ReceiveData. Mais l'UFDC-1 voudra peut-être garder la ligne basse jusqu'à ce que la réponse soit envoyée, c'est-à-dire ne pas la tirer trop haut après avoir écrit l'instruction et la tirer ensuite bas pour recevoir des données (seulement une supposition). – Thanushan