11
1 Labor Industrielle Netzwerke Versuch 2: Relais Steuerung durch SPI Datum: 23.01.2018

Labor Industrielle Netzwerke Versuch 2: Relais Steuerung ... · TX Shift Register des MSP430 noch nicht bereit für die nächste Übertragung sind. Wie in Versuch 1 schon erwähnt,

  • Upload
    lykhanh

  • View
    221

  • Download
    0

Embed Size (px)

Citation preview

1

Labor Industrielle Netzwerke

Versuch 2: Relais Steuerung durch SPI

Datum: 23.01.2018

2

Serial Peripheral Interface (SPI)

Beim SPI (Serial Peripheral Interface) Protokoll handelt es sich um einen seriellen BUS, der für synchrone und serielle Datenübertragung (USRT) zwischen einem Master und einem oder mehreren Slaves mit hoher Geschwindigkeit entwickelt wurde. Die Übertragung findet im Vollduplex statt, d.h. die Daten werden gleichzeitig in beide Richtungen zwischen Master und Slave übertragen. Der SPI-Bus besteht aus zwei Signal- und zwei Datenleitungen:

• Serial data out (SDO) / Master out Slave in (MOSI)

• Serial data in (SDI)/ Master in Slave out (MISO)

• Serial clock (CLK) /UCLK

• Chip select Oder Slave Transmit Enable (CS)/STE

Der Master wählt sein Slave durch die Chip Select Leitung aus. Außerdem wird dem Slave über dieses Leitung signalisiert, dass eine Übertragung stattfindet.

SPI Protokoll in CAN-Controller

Der MCP2515 verwendet das SPI Protokoll, um mit dem MSP430 zu kommunizieren. Laut des SPI Protokolls gibt es vier verschiedene Arten von Kommunikation zwischen zwei SPI Geräten. Diese werden als Mode0, Mode1, Mode2 und Mode3 definiert. Der MCP verwendet entweder Mode0 oder Mode3. In Mode0 werden die Daten mit steigender Flanke des Taktes gesendet und mit fallender Flanke empfangen. In Mode3 werden die Daten mit fallender Flanke des Taktes empfangen und mit steigender Flanke gesendet. In diesem Labor werden die Daten und Befehle mit steigender Flanke des Taktes über den MOSI Pin zum MCP2515 übertragen. Mit fallender Flanke des Taktes antwortet der MCP2515 dem MSP430 über den MISO Pin.

Der MSP430x169 stellt 2 asynchron/synchrone Übertragungs-Ports zur Verfügung:

• USART0

3

• USART1 Das Modul USART0 kann entweder als UART (asynchron) oder SPI (synchron) verwendet werden. Beim USART1 kommt zusätzlich die Schnittstelle I²C (synchron) hinzu.

Funktionsweise des SPI Moduls im MSP430

Das SPI Protokol initialisiert die Übertragung, wenn die Daten in das TXBUF Register geschrieben werden. Die Daten werden dann in das Shift Register gelegt und über den MOSI Pin vom Master zum Slave übertragen. Das Bit UTXIFGx signalisiert die korrekte Übertragung der Daten.

SPI Register

Anhand der folgenden 11 Register1 können alle USART Moduleinstellungen definiert werden: USART control register (U0CTL) Transmit control register U0TCTL) Receive control register (U0RCTL) Modulation control register (U0MCTL) Baud rate control register0 (U0BR0) Baud rate control register1 (U0BR1) Receive buffer register (U0RXBUF) Transmit buffer register (U0TXBUF) SFR module enable register (1ME1) SFR interrupt enable register (1IE1) SFR interrupt flag register (IFG1)

SPI Initialisierung

Master: P3SEL |= 0x0F; // P3.0, P3.1, P3.2, P3.3 in USART Mode (Peripherie)

ME1 |= USPIE0; // Enable USART0 SPI Modus UCTL0 = SWRST; // SW-Reset UCTL0 |= CHAR+SYNC+MM; // CHAR: 8-Bit, SYNC: SPI-Modus , MM: SPI-Master UTCTL0 = STC + SSEL1 + SSEL0 + CKPL; // STC: 3-Pin SPI-Modus, SSEL1: UCLK = SMCLK, SSEL0: UCLK = ACLK, CKPL: Clock Polatität low UBR00 = 0x08; // UCLK/8 -> 1MHz @ 8MHz UBR10 = 0x00; UMCTL0 = 0x00; // keine Modulation IE1 |= URXIE0; UCTL0 &=~ SWRST; // Starte USART

Das folgende Bild stellt die Verbindung zwischen dem MSP430 und dem MCP2515 dar.

1 Siehe Userguide MSP430x169 Usart Peripheral Interface (Seite 13-21 bis 13-29)

4

Befehlssatz

Damit der MCP2515 mit dem MSP430 kommunizieren kann, sind neun Befehle definiert: Reset, Read, Read Rx Buffer, Write, Load Tx Buffer, Request To Sent, Read Status, Rx Status und Bit Modify Instruktionen.

RESET Instruktion

Dieser Befehl entspricht dem Wert 0xC0 in Hexadezimal und ist dafür verantwortlich, dass alle internen Register des MCP2515 auf den Initialzustand gesetzt werden.

Void reset_MCP() { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0xC0; // reset Kommando while (!(UTCTL0 & TXEPT)); // warte bis übermittelt P3OUT |= 0x80; // cs-high->disable }

Es ist wichtig, dass CS im Laufe der Transaktion auf Null gezogen wird (P3OUT &= ~0x80;). Außerdem verlangt der MCP, dass die erste Anweisung nach dem CS der Befehl ist. Nach jeder Anweisung muss der CS wieder auf Eins gezogen werden (P3OUT |= 0x80;), um das Ende der Datenübertragung zu signalisieren. Die Anweisung “while (! (UTCTL0 & TXEPT));” wird verwendet, um eine Warteschleife zu generieren, bis die Übertragung korrekt durchgeführt worden ist. Diese sorgt dafür, dass keine Datenverluste durch Überschreiben der Daten im Transmit Buffer (TxBUF) entstehen. UTCTLx, USART Transmit Control Register 7 6 5 4 3 2 1 0

CKPH CKPL SSELx Unused Unused STC TXEPT

TXEPT (Transmitter empty flag): Falls UxTXBUF und TX Shift Register des MSP430 Controllers bereit für die Übertragung sind, hat dieser Flag den Wert 1 und die nächsten Daten können gesendet

5

werden. Falls dieser Flag den Wert 0 aufweist, dann ist das ein Indiz dafür, dass die UxTXBUF und TX Shift Register des MSP430 noch nicht bereit für die nächste Übertragung sind. Wie in Versuch 1 schon erwähnt, existiert eine sogenannte header.h Datei mit dem Eintrag „# define TXEPT 0x01“. Somit bleibt der Ausdruck „! (UTCTL0 & TXEPT)“ solange auf 1 bis Bit TXEPT 0 ist. Die nächste Anweisung kann somit nicht durchgeführt werden, weil eine Warteschleife aktiv ist. Auf diese Art und Weise wird garantiert, dass die Daten korrekt übertragen werden.

Read Instruktion

Dieser Befehl entspricht dem Wert 0x03 in Hexadezimal und wird für das Auslesen der Daten von einem bestimmten Register vom MCP benötigt. Diese Anweisung verwendet 3 Teilbereiche: den Read Code (0x03), ein Adressbyte und ein Idle Byte. Der Read Code (0x03) wird durch den SI Pin vom MSP430 zum MCP2515 gesendet. Direkt danach erwartet der MCP ein Adressbyte, welches genau bestimmt, welches Register gelesen werden soll. Danach sendet der MSP430 ein Dummy Byte, damit ein Taktsignal generiert wird und der MCP, die gefragten Daten durch den SO Pin zum MSP430 überträgt. Empfangene Daten werden im RXBUF Register des MSP430 Controllers gespeichert.

byte read_mcp(byte addr) { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0x03; // Lesebefehl senden while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = addr; // Adresse senden while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = 0xaa; // Dummy Byte senden while (!(UTCTL0 & TXEPT)); // warte bis übermittelt data = RXBUF0; //Daten aus dem SPIBuffer holen und in Variable data schreiben P3OUT |= 0x80; // cs-high->disable }

Read RX Buffer Instruction

Die Anweisung 10010xx0 in Binär bietet eine schnelle Übertragung zum Lesen von Nutzdaten aus dem Receive Buffer Register. x x → 0 0 Adresse 0x61h (in dieser Adresse befindet sich RXB0SIDH2) x x → 0 1 Adresse 0x66h (in dieser Adresse befindet sich RXB0D03) x x → 1 0 Adresse 0x71h (in dieser Adresse befindet sich RXB1SIDH) x x → 1 1 Adresse 0x76h (in dieser Adresse befindet sich RXB1D0) Void readbuffer-mcp() { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0x96; // Lesebefehl mit dem Anfangregister RXB1D0 while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = 0xaa; // Dummy Byte senden

2 Steht für Receive Buffer0 Standard ID High Register (siehe Datenblatt vom MCP2515) 3 Steht für Receive Buffer Register0 Data 0 (siehe Datenblatt vom MCP2515)

6

while (!(UTCTL0 & TXEPT)); // warte bis übermittelt data = RXBUF0; //erste Daten aus dem UARTBuffer holen und in Variable data schreiben P3OUT |= 0x80; // cs-high->disable }

Wie zu erkennen ist, wird das Adressbyte durch diese Anweisung im Vergleich mit der Read Anweisung nicht benötigt.

Write Instruktion

Dieser BEfehl entspricht 0x02 in Hexadezimal und wird fürs Schreiben der Daten in einem bestimmten Register verwendet. Diese Anweisung besteht aus 3 Teilbereiche: den Write Code (0x02), Adresse Byte und Daten Byte. Der Write Code wird durch den SI Pin vom MSP430 zum MCP2515 gesendet. Direkt danach erwartet der MCP ein Adresse Byte, das angibt, wohin die späteren Nutzdaten geschrieben werden. void write_mcp(byte addr, byte value) { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0x02; // Schreibbefehl while (!(UTCTL0 & TXEPT)); // warte bist übermittelt TXBUF0 = addr; // Adresse while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = value; // Nutzdaten while (!(UTCTL0 & TXEPT)); // warte bis übermittelt P3OUT |= 0x80; // cs-high->disable }

Load TX Buffer Instruction

Die Anweisung 10010xxx im Binär bietet eine schnelle Übertragung zum Schreiben von Nutzdaten in den folgenden Registern. x x x → 0 0 0 Adresse 0x31 (in dieser Adresse befindet sich TXB0SIDH4) x x x → 0 0 1 Adresse 0x36 (in dieser Adresse befindet sich TXB0D05) x x x → 1 0 0 Adresse 0x41 (in dieser Adresse befindet sich TXB1SIDH) x x x → 0 1 1 Adresse 0x46 (in dieser Adresse befindet sich TXB1D0) x x x → 1 0 0 Adresse 0x51 (in dieser Adresse befindet sich TXB2SIDH) x x x → 1 0 1 Adresse 0x56 (in dieser Adresse befindet sich TXB2D0) Void loadbuffer_mcp() { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0x91; // Schreibbefehl in das Register TXB0D0 while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = value; // erste Daten in den UARTBuffer schreiben while (!(UTCTL0 & TXEPT)); // warte bis übermittelt P3OUT |= 0x80; // cs-high->disable }

4 Steht für Transmit Buffer 0 Standard ID Register (siehe Datenblatt vom MCP2515). 5 Steht für Transmit Buffer Data 0 Register (siehe Datenblatt vom MCP2515).

7

Request To Send

Drei Transmit Register TXB0, TXB1 und TXB2 sind im MCP2515 fürs Datensenden über die CAN Schnittstelle verantwortlich. Jeder Transmit Buffer kann die Daten senden, solange das Bit TXREQ, das sich im Transmit Buffer Control Register (TXB0CTRL) befindet, 1 ist. Mit Hilfe der Request To Send Anweisung wird bestimmt, welcher TXB mit Senden anfangen kann. Die Request To Send Anweisung entspricht 10000xxx in Binär und sieht wie folgt aus: x x x → 0 0 0 Transmit ignored x x x → 0 0 1 TXB0 x x x → 0 1 0 TXB1 x x x → 1 0 1 TXB2 Void request_mcp() { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0x81; // Zulassung für TXB0D0 while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = TXB0CTRL; // muss in Transmit Buffer Control Register geschrieben werden while (!(UTCTL0 & TXEPT)); // warte bist übermittelt TXBUF0 = 0x0b; // dadurch wird das 4. Bit des TXB0CTRL Registers auf 1 gesetzt d.h. TXREQ gleich 1 P3OUT |= 0x80; // cs-high->disable }

Read Status Instruktion

Dieser Befehl entspricht 0xA0 in Hexadezimal und wird fürs Auslesen von wichtigen Flags verwendet. Read Status Instruktion wird durch den SI Pin vom MSP430 zum MCP2515 gesendet. Der MCP antwortet dem MSP430 wie folgt durch den SO Pin. B7 B0

CANINTF. TX2IF

TXB2CTRL. TXREQ

CANINTF. TX1IF

TXB1CTRL. TXREQ

CANINTF.TX0IF

TXB0CTRL. TXREQ

CANINTF.RX1IF

CANINTF. RX0IF

Die Bedeutung der Bits sind im Datenblatt des MCP2515 Controllers beschrieben.

void read_mcp() { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0xA0; // auslesen des Status Bits while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = 0xaa; // Dummy Byte senden while (!(UTCTL0 & TXEPT)); // warte bis übermittelt status = RXBUF0; while (!(UTCTL0 & TXEPT)); // warte bis übermittelt P3OUT |= 0x80; // cs-high->disable }

RX Status Instruktion

Dieser Befehl entspricht 0xB0 in Hexadezimal und zeigt welcher Filter die Nachricht erhält und um welche Nachricht es sich handelt, da verschiedene Nachrichtentypen wie Standard Frame, Extended

8

Frame oder Remote existieren. Der Read Status Befehl wird durch den SI Pin vom MSP430 zum MCP2515 gesendet. Direkt danach sendet der MCP ein Byte wie folgt durch den SO Pin zurück.

B7 B6 Recieved Massage 0 0 0 1 1 0 1 1

Keine Nachricht Nachricht in RXB0 Nachricht in RXB1 Nachricht in beide Buffern

B4 B3 Nachricht Typ 0 0 0 1 1 0 1 1

Standard Data Frame Standard Remote Frame Extended Data Frame Extended Remote Frame

B2 B1 B0 Entsprechender Filter 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1

RXF0 RXF1 RXF2 RXF3 RXF4 RXF5 RXF0(rollover to RXB1) RXF1(rollover to RXB1)

Bit Modify Instruktion

Dieser Befehl entspricht 0x05 in Hexadezimal und maskiert den Wert in einem Zielregister. Diese Anweisung besitzt 4 Teilbereiche: den Modify Code (0x05), Adressbyte, Mask Byte und Data Byte. Der Modify Code wird durch den SI Pin vom MSP430 zum MCP2515 gesendet. Direkt danach erwartet der MCP ein Adressbyte. Dann sendet der MSP430 ein Mask Byte, wobei jede 0 im Mask Byte das entsprechende Bit im Ziel Register unverändert lässt (im unteren Beispiel mit Rot angezeigt). Erst durch eine 1 kann das entsprechende Bit verändert werden (im unteren Beispiel mit Blau angezeigt). Beispiel: Mask Byte: 0 0 1 0 1 0 1 1 Data Byte: 0 0 0 1 1 1 1 0 Alte Daten im Adress Register: 1 1 1 1 1 0 1 1

Void status_mcp() { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0xB0; // auslesen des Status Bits while (!(UTCTL0 & TXEPT)); // warte bis übermittelt status = RXBUF0; while (!(UTCTL0 & TXEPT)); // warte bis übermittelt P3OUT |= 0x80; // cs-high->disable }

9

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Neue Daten im Adress Register: 1 1 0 1 1 0 1 0

Void modify_mcp() { P3OUT &= ~0x80; // cs-low->enable TXBUF0 = 0x05; // Bit Modify while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = addr; // wo die Änderungen durchgeführt werden müssen while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = mask; // Mask Byte z.b. : 00101011 while (!(UTCTL0 & TXEPT)); // warte bis übermittelt TXBUF0 = data; // Data Byte z.b.: 00011110 while (!(UTCTL0 & TXEPT)); // warte bis übermittelt P3OUT |= 0x80; // cs-high->disable }

10

Aufgaben:

Aufgabe 1

Lesen Sie im MCP2515datasheet-Datenblatt über die SPI-Schnittstelle. Welche Register müssen Sie beachten? Schreiben Sie verschiedene Werte in diese Register. In welchem MSP-Register muss man einen SPI-Befehl schreiben?

Aufgabe 2

Nutzen Sie das IAR-Debugger-Tool, um die Werte von Aufgabe 1 zu lesen und schreiben.

11

Funktionssammlung:

Initialisierung: msp_init(); initialisiert den MSP430 port_init(); initialisiert die zu benutzenden Ports als Ein- und Ausgänge init_spi(); initialisiert die SPI-Schnittstelle MCP2515: reset_mcp(); führt Reset des MCP2515 durch

read_mcp(REGISTER); liest REGISTER des MCP2515 und gibt den Wert zurück

write_mcp(REGISTER,WERT); schreibt WERT in REGISTER des MCP2515 Logik: P5OUT = 0xFF; Setzt alle Bits von Port 5 auf 1 P1OUT = P1OUT | 0x20; Setzt Bit 5 von Port 5 auf 1 P1OUT = P1OUT | 0xFE; Setzt alle Bits außer Bit0 von Port 5 auf 1 P1OUT = P1OUT & 0x20; Setzt alle Bits außer Bit5 von Port 5 auf 0

P1OUT = P1OUT & 0xFE; Setzt Bit 1 von Port 5 auf 0

(P3IN & 010) == 0x10 Ist P3.4 (Taster 1) auf 1? (P3IN & 020) == 0x20 Ist P3.5 (Taster 2) auf 1? Zaehlertaste1++; Erhöht die Variable Zaehlertaste1 um 1 Zaehlertaste1 = 0x00; Setzt den Wert von Zaehlertaste1 auf 0 zurück Zaehlertaste1 < 20 Prüft, ob Zaehlertaste1 noch kleiner ist als 20 data = data << n verschiebt die Bits von data um n nach links data = data >> n verschiebt die Bits von data um n nach rechts

sonstige: DELAY(); Wartefunktion wait()ZEIT; wartet ZEIT ms

if(BEDINGUNG){AKTION} führt AKTION aus, falls BEDINGUNG erfüllt ist

for(BEDINGUNG){AKTION} führt AKTION so oft aus, wie BEDINGUNG erfüllt ist

z.B. BEDIGUNG: int i = 0; i++; i<5 -> 4 mal BEDIGUNG: ; ; -> immer

while(BEDINGUNG){AKTION} führt AKTION aus, solange BEDINGUNG erfüllt ist