2013-07-17 2 views
0

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 
+1

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

+0

"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

+1

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

Répondre

0

Les PNS du LPC17xx ont pour FIFOs émises et reçues. Cela signifie que vous devez faire correspondre vos appels SSP_SendData() et SSP_ReceiveData(), ou vider le FIFO. Vous devrez également envoyer une valeur factice lorsque recevant les données - généralement 0x00 ou 0xFF est utilisé comme dummy.

La bibliothèque fait cela dans SSP_ReadWrite() que vous pouvez utiliser à la place.

Une version plus simple ressemblerait à ceci:

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; 
} 

Cette fonction peut être utilisée pour remplacer les deux SSP_SendData() et SSP_ReceiveData() dans votre code.

Note finale: Vous avez probablement ne voulez pas voulez matériel Chip Select, car cela peut désélectionner l'esclave entre la commande et les mots de réponse. Lisez les fiches techniques correspondantes, dans la plupart des cas, cela n'est pas autorisé.

+0

J'ai essayé d'utiliser SSP_ReadWrite() en plus de maintenir la ligne de sélection de la puce enfoncée tout en transmettant l'instruction "get accuracy" (je la mets à sa fonction GPIO par défaut avant de l'envoyer et la remet en CS matériel. vérifié les fiches techniques et je ne peux pas trouver quoi que ce soit approprié au sujet besoin de tenir la sélection de puce vers le bas de toute façon manuellement. – Tagc

+0

Afficher le code. la nécessité d'octets factices applique également 'SPI_ReadWrite()'. –

+0

Désolé pour la réponse tardive. J'ai . travaille sur quelque chose d'autre un collègue a obtenu le travail SPI en changeant la CPOL et les bits ACSP je ne pouvais trouver aucune référence dans les feuilles de données, il est donc ennuyeux qu'ils étaient le problème il y a encore un problème à gauche.. - le SPI va maintenant se synchroniser avec les bonnes données, mais il va aussi afficher un certain nombre de valeurs aléatoires, et je vais essayer de trouver un moyen d'arrêter cela. g. – Tagc

Questions connexes