Forum: Mikrocontroller und Digitale Elektronik MSP430: Hardware-SPI - Clock bei Receive?


von david (Gast)


Lesenswert?

Hallihallo,

ich habe den MSP430F1611 und möchte das Hardware-SPI vom UART0 benutzen 
um Daten zu empfangen. Der IC ADC121S625 sendet, sobald er eine Clock 
hat und per CS selektiert wird. Der MSP ist der Master. Nun mein 
Problem, der MSP gibt einfach keine Clock aus, wenn ich etwas empfangen 
will.
Hat jemand eine Idee, wo das Problem sein könnte?

Hier mein Source:

Die Initialisierung vom SPI:
1
void spi_init()
2
{
3
    int i;
4
    WDTCTL = WDTPW + WDTHOLD; 
5
    do
6
    {
7
        IFG1 &=~OFIFG; 
8
        for (i = 0xff; i>0; i--);
9
    } 
10
    while ((IFG1 & OFIFG) != 0);
11
    BCSCTL1 &= ~XT2OFF; 
12
    BCSCTL2 |= (SELM1 + SELS); 
13
  
14
    UCTL0 &=~ SWRST; //starting USART1_init 
15
    UCTL0 |= CHAR+SYNC+MM; 
16
    UTCTL0 = STC + SSEL1 + SSEL0 + CKPL;// + CKPH; //3???,?SMCLK??
17
    UBR00 = 0x08; //1MHz @ 8MHz
18
    UBR10 = 0x00;
19
    UMCTL0 = 0x00;
20
    ME1 |= USPIE0; 
21
    P3SEL |= 0x0F; //active P3.0 & P3.3 for SPI
22
    P3DIR |= 0x0A; //P3.1(SIMO)& P3.3(UCLK)
23
    IE1 &=~ URXIE0; 
24
    UCTL0 &=~ SWRST;
25
}

Meine Empfangsroutine:
1
void spi_receive_byte()
2
{
3
    P2OUT &= ~0x01;             //cs-low->enable
4
    received_byte = RXBUF0;     //daten aus dem uartbuffer holen und in var. data schreiben  
5
    P2OUT |= 0x01;              //cs-high->disable
6
}

Bin über jeden Tipp dankbar!
Gruß David

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du musst auch senden, um empfangen zu können.

Nur so kann die SPI-Logik wissen, wieviele Taktimpulse sie erzeugen 
soll.

von Flo (Gast)


Lesenswert?

Erstmal was anderes:

Rein vom logischen Programmieren her, sollte in SPI_INIT nur die 
Initialisierung der SPI Schnittstelle drin stehen! Lieber eine 2. und 3. 
Funktion anlegen mit z.B. PORT_INIT() und CLK_INIT(). Oder gleich alles 
direkt in die MAIN-Funktion reinzimmern. Nur soviel:
1
void spi_init()
2
{
3
    UCTL0 &=~ SWRST; //starting USART1_init 
4
    UCTL0 |= CHAR+SYNC+MM; 
5
    UTCTL0 = STC + SSEL1 + SSEL0 + CKPL;// + CKPH; //3???,?SMCLK??
6
    UBR00 = 0x08; //1MHz @ 8MHz
7
    UBR10 = 0x00;
8
    UMCTL0 = 0x00;
9
    ME1 |= USPIE0;
10
    IE1 &=~ URXIE0; 
11
    UCTL0 &=~ SWRST;
12
}

Und so klappts mit dem Nachbarn:
1
unsigned char SPI_RW_8BIT(unsigned char data)
2
{  
3
  while((IFG2 & UTXIFG1) == 0);    //TX Buffer leer?
4
  TXBUF1 = data;        //Sende Daten
5
  
6
  while((IFG2 & URXIFG1) == 0);    //Byte im RX Buffer?
7
  return RXBUF1;        //Buffer auslesen
8
}

Um Daten von SPI auszulesen muss man immer davor senden. Hier ein 
Beispiel:
1
unsigned char ADC_READ(void)
2
{
3
    unsigned char value;
4
 
5
    //CS setzen
6
7
    SPI_RW_8BIT(BEFEHL);               //Befehl für ADC senden, um Messergebnis zu bekommen und Rückgabewert verwerfen
8
    value = SPI_RW_8BIT(0x00);         //0x00 senden um Clk zu erzeugen und Messwert auslesen
9
10
    //CS setzen
11
    return value;                     
12
}

Schau dir mal genau das SPI-Timing im Datenblatt von deinen AD-Wandler 
an.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Anmerkung am Rande:

Du solltest damit aufhören, Funktionsnamen in VERSALIEN zu schreiben. 
Per Konvention sind das nur und ausschließlich Präprozessor-Macros 
(#defines).

von Flo (Gast)


Lesenswert?

Per Genfer Konvention?

Blablablabla. Ich schreib des so wie ich will :)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es gibt so Dinge wie C-Standards.
Und Jörg Wunsch, der Dir sicherlich eins auf die Finger gibt.

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.