Forum: Mikrocontroller und Digitale Elektronik LPC1114/LPC111x SPI Config


von Alex (Gast)


Lesenswert?

Hallo Leute,
ich versuche die SPI Schnittstelle auf dem lpc1114/302(NXP LPCEperesso 
Board) zum Laufen zu bringen.  Leider hab ich ein Fehler den ich nicht 
finde.
Die Code Beispiele und das UM helfen mir irgendwie nicht weiter.

Ich müsste doch mit diesen Einstellungen ein CLK auf PIO0_6 messen 
können.
Leider ist er auf GND.

Was mache ich falsch oder was übersehe ich?

1
void SPI_IOConfig(){
2
3
  LPC_SYSCON->PRESETCTRL |= (1<<0);     //Table 9
4
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);  //Table 21 Enable SPI0
5
  LPC_SYSCON->SSP0CLKDIV = (1<<1);    //Tab 22
6
  //Pin Cfg
7
  LPC_IOCON->PIO0_8  &= ~0x07;    //SSP Reset Value I/O config
8
  LPC_IOCON->PIO0_8  |=  0x01;    //SSP MISO
9
  LPC_IOCON->PIO0_9  &= ~0x07;    //SSP Reset Value I/O config
10
  LPC_IOCON->PIO0_9  |=  0x01;    //SSP MOSI
11
12
  LPC_IOCON->SCK_LOC  =  0x02;    //Tab 147 CLK an PIO0_6 umleiten
13
  LPC_IOCON->PIO0_6  =  0x02;    //SCK0
14
15
  // SSP SSEL is a GPIO pin
16
  LPC_IOCON->PIO0_2  &= ~0x07;    //Reset
17
  LPC_GPIO0->DIR    |=(1<<2);
18
  LPC_GPIO0->MASKED_ACCESS[(1<<2)] = (1<<2);  //SSEL0
19
}
20
void SPI_Init(){
21
  uint8_t i, Dummy=Dummy;
22
23
  LPC_SSP0->CR0   = 0x0000;    //Reset
24
  LPC_SSP0->CR0   = 0x0107;    //Tab 208 Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 0
25
  /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
26
  LPC_SSP0->CPSR  = 0x2;      //Tab 212
27
28
  for ( i = 0; i < 8; i++ ){
29
      Dummy = LPC_SSP0->DR;    //Tab 210 clear the RxFIFO
30
    }
31
  // Enable the SSP Interrupt
32
  //NVIC_EnableIRQ(SSP0_IRQn);    //Tab 442 
33
  //Master Mode
34
  //LPC_SSP1->CR1   = (1<<1);   //Tab 209 SSE
35
  /* Set SSPINMS registers to enable interrupts */
36
  /* enable all error related interrupts */
37
  //LPC_SSP1->IMSC   = (1<<0)|(1<<1); //Tab 213 
38
}

von Stefan (Gast)


Lesenswert?

Hallo,

die Konfiguration habe ich mir nur oberflächlich angesehen. Könnte 
passen. Aber die (Test-)Schleife danach kann nicht funktionieren.
Ein SPI Master liest während er schreibt. Deswegen sind es zwei 
Datenleitungen (MISO + MOSI). Wenn tatsächlich nur gelesen werden soll, 
muss du erst ein Dummybyte rausschreiben und danach das Register lesen.
Und natürlich der SPI Einheit Zeit geben das Byte auszugeben indem du 
entweder etwas wartest oder das Statusregister in einer Schleife 
ausliest.
Interruptbetrieb oder gar DMA geht natürlich auch, ist aber oft 
Overkill.

Also ungefähr so:
1
LPC_SSP0->DR = 0x43; // etwas senden
2
// warten bis fertig
3
dummy = LPC_SSP0->DR; // Daten auslesen

von Alex (Gast)


Lesenswert?

Hi,
danke für die Hilfe, aber die diese schleife nicht passen soll glaube 
ich nicht ganz. Sie ist praktisch aus den Code Beispielen herauskopiert.
Und beim Debugen komm ich da ohne Probleme durch.

Ich hab diese Send Prozedur auch aus den Beispielen genommen in etwas 
angepasst.

Leider bleibt der LPC bei der zweiten Schleife(S2) hängen bzw. verlässt 
diese nicht. Ich verstehe den Grund nicht. Irgendwann muss es es doch 
freigeben.
1
void SPI_Send(){
2
   uint32_t i,length=8;
3
   uint8_t Dummy=Dummy, buf=170;
4
5
    for ( i = 0; i < length; i++ ){
6
    /* Move on only if NOT busy and TX FIFO not full. */
7
    while ( (LPC_SSP0->SR & ((1<<1)|(1<<4))) != (1<<1)); //S1
8
    LPC_SSP0->DR = buf;
9
    while ( (LPC_SSP0->SR & 1<<4)); //S2 Bleibt in dieser Schleife gefangen
10
    Dummy = LPC_SSP0->DR;
11
    }
12
}

von temp (Gast)


Lesenswert?

Alex schrieb:
> while ( (LPC_SSP0->SR & 1<<4)); //S2 Bleibt in dieser Schleife gefangen

Versuch mal um das 1<<4 eine Klammer zu machen.
while ( (LPC_SSP0->SR & (1<<4)));

hier machst du es ja auch:
> while ( (LPC_SSP0->SR & ((1<<1)|(1<<4))) != (1<<1)); //S1

von Erwin R. (er-tronik)


Lesenswert?

Warum hast Du denn diese Zeile ausgeklammert?
1
//LPC_SSP1->CR1   = (1<<1);   //Tab 209 SSE

Hierdurch wird der SPI-Port aktiviert und ist unbedingt erforderlich.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
danke für die Antworten.

@ temp hab ich auch schon versucht. Keine Änderung.

@ Erwin
Ich hab das UM falsch verstanden habs jetzt geändert.

Aber dieser Befehl
1
LPC_SSP1->CR1   = (1<<1);   //Tab 209 SSE
 hat seltsamerweise in meinem Code keine Auswirkung. o_0 Das Bit wird 
nicht gesetzt.
Habe das Beispiel von NXP, bis zu der Zeile Schritt für Schritt im 
Debugger angeschaut. Mit meinem verglichen. Sie setzen die gleichen SPI0 
Register. Aber bei ihnen wird das Bit geändert/gesetzt.
1
#define SSPCR1_SSE      (0x1<<1) ...
2
/* Master mode */
3
  LPC_SSP1->CR1 = SSPCR1_SSE;

Ich versteh nicht wieso...
Bin zwar am Problem dran, wäre aber trotzdem für Hilfe dankbar.

von Martin M. (capiman)


Lesenswert?

Ich glaub, Du hast da einen Dreher mit SSP0 / SSP1 drin...

LPC_SSP0->CPSR  = 0x2;      //Tab 212
       ^
...

LPC_SSP1->CR1 = (0x1<<1);   //Tab 209 SSE
       ^

von Alex (Gast)


Lesenswert?

OMG -.- so ein Mist du hast recht  Martin!
Danke!
Ich habs Total übersehen -.- jetzt sendet es.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.