Aufgabe 3, UART Labor Mikrocontroller mit NUC130 Prof. Dr.-Ing. F. Kesel Dipl.-Ing. (FH) J. Hampel Dipl.-Ing. (FH) A. Reber 23.11.2016 Gruppe A Mikrocontroller Labor EIT/TI Gruppe A - 1 -
Inhalt 1 Einführung... 3 1.1 Grundlagen zum UART2... 3 1.1.1 Kennzeichen... 3 1.1.2 Übertragungsrate... 3 1.1.3 Auswahl der Baudrate... 3 1.1.4 Initialisierung des UARTs... 4 1.1.5 Daten senden mit M_UART2_DATA_WRITE... 4 1.1.6 Daten empfangen mit M_UART2_DATA_READ... 4 1.1.7 Kommunikation mit Datenpaketen... 4 1.1.8 Senden von Datenpaketen... 5 1.1.9 Empfangen von Datenpaketen... 5 1.1.10 Datensicherheit... 5 1.1.11 Überprüfung des Datenframes... 5 1.2 Einführung zu Automaten... 6 1.2.1 Diagramm für Datenüberprüfung ohne 0xA und 0xD... 6 1.2.2 Struktogramm für Automaten aus 1.2.1... 7 2 Literatur... 7 3 Aufgaben... 8 3.1 Aufgabe 3.1 Byte senden... 8 3.1.1 Aufgabenpunkte für 3.1... 8 3.1.2 Fragen zu 3.1... 8 3.1.3 Abnahmepunkte für 3.1... 8 3.2 Aufgabe 3.2 Byte empfangen... 9 3.2.1 Aufgabenpunkte für 3.2... 9 3.2.2 Abnahmepunkte für 3.2... 9 3.3 Aufgabe 3.3 Voltmeter mit Kommunikation... 9 3.3.1 Aufgabenpunkte für 3.3... 10 3.3.2 Fragen zu 3.3... 10 3.3.3 Abnahmepunkte für 3.3... 10 3.4 Aufgabe 3.4 Schaltbare und sichere Kommunikation... 11 3.4.1 Aufgabenpunkte für 3.4... 11 3.4.2 Fragen zu 3.4... 11 3.4.3 Abnahmepunkte für 3.4... 11 Mikrocontroller Labor EIT/TI Gruppe A - 2 -
1 Einführung Ein Mikrocontroller ohne Verbindung zur Außenwelt wird kaum zu finden sein. Der NUC130 verfügt dazu über vier unterschiedliche Peripherieeinheiten zur seriellen Kommunikation. Neben einem CAN- Interface enthält er noch 3 UARTs. Diese UARTs können für die unterschiedlichsten elektrischen Interface (RS232, RS485, RS422, IrDa und LIN) konfiguriert werden. In der aktuellen Aufgabe soll erst mit dem PC, später dann mit einem Nachbar-M_Dongle eine Kommunikation aufgebaut werden. Die erste Kommunikation mit dem PC ist deshalb besser, da man sich sicher sein kann, dass die eingestellte Baudrate am PC korrekt ist. Wenn der UART selber initialisiert wird, besteht schon die Möglichkeit, dass das Protokoll nicht ganz korrekt ist. Für den Anfang wird nur eine ASCII-Kommunikation verwendet, d.h. Zahlen müssen in darstellbare ASCII-Zeichen umgewandelt werden, bevor sie gesendet werden. Der Vorteil ist, dass Alles, was auf das LCD geschrieben werden kann, sofort sendefähig ist. Beim Empfang von Zeichen können diese ohne Umwandlung direkt auf das LCD geschrieben werden. Diese Klartext-Kommunikation benötigt zwar mehr Zeichen, ist jedoch sehr praktisch, da die Daten mit einem einfachen Terminalprogramm empfang- und darstellbar sind. 1.1 Grundlagen zum UART2 1.1.1 Kennzeichen Der NUC130 verfügt über drei UARTs, die jedoch zum Teil unterschiedliche Features haben. Sie sind in der Lage mit unterschiedlichen Datenbitlängen zu arbeiten. Zur Entlastung der CPU bieten sie die die Möglichkeit, Datenpakete mittels FIFO-Speicher senden bzw. empfangen zu können. Außerdem sind verschiede Erweiterungen für Busprotokolle eingebaut, die die Kommunikation per LIN, RS485 oder IrDA erheblich vereinfachen. UART0 und UART1 verfügen über viele Features, der UART2 in seinen Möglichkeiten etwas eingeschränkt ist. Diese Einschränkungen haben jedoch den Vorteil, dass seine Initialisierung nicht so komplex ist. Für alle UARTs gilt, sie werden mit dem gleichen Takt versorgt. Dieser Takt wird automatisch beim Systemstart durch die Funktion DrvSystem_ClkInit(); eingestellt und beträgt 22,1188 MHz. Der Vorteiler für den Takt wird nicht verwendet, was bei der Nutzung von UART 0 und 1 zu beachten ist. Da der UART2 für die PC-Kommunikation benutzt wird, ist er auf das übliche 8N1-Protokoll eingestellt. 1.1.2 Übertragungsrate Das Hauptproblem aller asynchronen Datenübertragungen ist die Frequenz, mit der die Daten- und Kontrollbits gesendet werden. Das bedeutet, dass jeder Teilnehmer seinen eigenen Sende- und Empfangstakt erzeugen muss, da er im Datenframe nicht enthalten ist. Für UARTs beträgt die Abweichung vom Takt maximal 5 %. 1.1.3 Auswahl der Baudrate Für die Aufgabe 3.3 soll die Baudrate so bestimmt werden, dass es ohne Probleme möglich ist, vier gewandelte Werte pro Sekunde an das andere Board zu schicken. Bei dem normalen 8N1-Protokoll für die Übertragung benötigt ein Zeichen 10 Bit (Startbit, Zeichen & Stoppbit). Bei einer zu niedrigen Baudrate ist schon wieder ein neuer ADC-Wert vorhanden, obwohl der letzte noch nicht gesendet ist. Da Zahlenumwandlung und LCD-Ausgabe auch Zeit benötigen, kann nicht davon ausgegangen werden, dass es ausreicht, alle Zeichen innerhalb von 250 ms zu senden. Mikrocontroller Labor EIT/TI Gruppe A - 3 -
1.1.4 Initialisierung des UARTs Für die Initialisierung des UART2 ist eine Funktion in der Bibliothek vorhanden: void DrvUART2_Init(uint16_t u16baudrate, uint8_t uitriglevelbytes); Diese Funktion initialisiert den UART2 auf die gewünschte Baudrate. Außerdem wird die Anzahl der Bytes festgelegt, ab der der Interrupt des UART2 aktiv wird, falls er benutzt wird. Für die Einstellung der Baudrate ist die Systemfrequenz der UARTs maßgeblich, die je nach eingestellter Taktquelle variieren kann. Die vorgegebene Funktion beachtet alle Parameter und stellt die gewünschte Baudrate ein: DrvUART2_Init(38400,0); // 38k4, 8N1, Meldung ab 1 Byte im Empfänger 1.1.5 Daten senden mit M_UART2_DATA_WRITE Daten senden nur wenn Puffer frei, sonst weiter: if(uart2->fsr.tx_full == FALSE) { M_UART2_DATA_WRITE('T'); } // wenn ein Byte frei // Sendet ein T oder: if(uart2->fsr.tx_empty == TRUE) { M_UART2_DATA_WRITE('T'); } // wenn ein 16 Byte frei // Sendet ein T 1.1.6 Daten empfangen mit M_UART2_DATA_READ Daten empfangen wenn Daten da, sonst weiter: if(uart2->fsr.rx_empty == FALSE) { u8empfang = M_UART2_DATA_READ; } // wenn FALSE, Daten vorhanden //Daten aus Empfangsregister holen Die beiden Makros selbst beschreiben bzw. lesen nur das Register des UARTs, ohne auf die Status- Flags zu achten. Da dies aber zu Fehlern führen kann, sollten die Flags mit einbezogen werden. 1.1.7 Kommunikation mit Datenpaketen Bei der Kommunikation ist es üblich, die Daten als Blöcke (Frames) zu Senden oder zu Empfangen. Dazu müssen Softwareblöcke angelegt werden, die dies ermöglichen. In einem System ohne Interrupts werden diese Softwareblöcke in der Hauptschleife angelegt. Ein Softwareblock ist für das Senden und einer für das Empfangen zuständig. Diese Blöcke funktionieren ähnlich wie die Blöcke zur ADC- Werteverarbeitung bzw. den Blöcken für die Tastenabfrage. Der Grund für dieses Vorgehen ist die Tatsache, dass die Hauptschleife nicht durch unnötiges Warten blockiert werden soll. Für den Anfang können zwei Arrays angelegt werden, die für die Sende- bzw. Empfangsdaten zuständig sind. Diese Array dienen dann als Datenbasis für die anderen Funktionen. Mikrocontroller Labor EIT/TI Gruppe A - 4 -
1.1.8 Senden von Datenpaketen Die ASCII-Daten der ADC-Wandlung werden in das Sendearray kopiert und somit dem Sendeblock zur Verfügung gestellt. Über ein Flag (Variable) wird das Senden der Daten angefordert. In der Hauptschleife wird dieses Flag abgefragt und wenn nötig, in den Sendeblock verzweigt. Innerhalb des Blockes wird nur nachgeschaut, ob der Sendepuffer frei ist und falls ja, ein Byte in diesen übertragen. Anschließend wird der Block wieder verlassen. Erst wenn alle Bytes übertragen sind, löscht der Softwareblock das Sende-Flag und blockiert sich damit selbst. Die Sendeblock blockiert das Senden nicht, da er nur dann etwas in den Sendepuffer schiebt, wenn dieser frei ist. Diese Vorgehensweise funktioniert mit jedem UART. Ein weiterer Weg besteht darin, die Eigenschaften des UARTs zu nutzen, wenn er einen internen Sende-FIFO hat. Dazu muss nur im UART nachgeschaut werden, ob der FIFO leer ist und dann können so viele Bytes in den Puffer geschrieben werden, wie er Platz hat. Der UART schickt dann alle im FIFO vorhandenen Bytes zum Empfänger. Der FIFO von UART2 hat 16 Bytes. 1.1.9 Empfangen von Datenpaketen Die Software für das Empfangen sieht ähnlich aus, sie meldet sich erst per Flag, wenn sie eine definierte Anzahl an Bytes empfangen hat, die dann in unserem Bespiel erst auf Gültigkeit geprüft werden, bevor sie auf dem LCD ausgegeben werden. Die Empfangssoftware schaut immer nur nach, ob ein Zeichen da ist. Wenn ja, wird es im Empfangsarray abgelegt, wenn keines da ist, geht sie weiter. Für die gewählte Baudrate von 38400 ergibt sich für 6 Zeichen eine Übertragungszeit von ca. 1,56 ms. Würde gewartet werden, bis alle 6 Zeichen im Sendepuffer sind, so muss die Main-Schleife ca. 1,3 ms warten, was etwa 15625 Maschinenzyklen bei 12 MHz entspricht. 1.1.10 Datensicherheit Des Weiteren ist es Stand der Technik, diese Frames mit Sicherungsmaßnahmen zu versehen. Diese Sicherungsmaßnahmen sorgen dafür, Übertragungsfehler zu entdecken. Ein einzelnes Byte kann schon ein Sicherungsbit, das Paritätsbit, enthalten. Dies allein reicht jedoch nicht aus, weshalb in der Maschinenkommunikation eine Vielzahl von Verfahren benutzt wird, um eine sichere Übertragung zu ermöglichen. Ein einfaches Verfahren ist die Nutzung von festen Frame-Längen und Kennungen für den Framestart und Frameende. Für die ADC-Übertragung soll der Frame wie folgt aussehen: A,Daten0, Daten1, Daten2, Daten3,E Frameanfang: A Frameende: E Wird nun ein Frame empfangen, werden als erstes die beiden Kennungen geprüft und bei positivem Ausgang kann dann noch der Inhalt der Daten (die 0x30 bis 0x39 enthalten müssen) überprüft werden. Wenn mit Terminalprogrammen gearbeitet wird, ist es hilfreich, an den Frame noch ein 0xA oder 0xD anzufügen. Diese Zeichen bewirken, dass ein Zeilenvorschub im Terminal ausgelöst wird, was die Ansicht der Daten erheblich verbessert. 1.1.11 Überprüfung des Datenframes Wird ein Frame im obigen Format empfangen, so kann die Überprüfung unterschiedlich ablaufen. Es können einfach sechs Bytes empfangen werden, die dann erst auf korrekten Frame-Start und Frame- Ende hin geprüft werden. Nach einem positiven Testergebnis erfolgt der Test der Daten 0 bis 3 auf darstellbare Zahlen. Die Freigabe für die LCD-Ausgabe erfolgt nur, wenn keine Fehler gefunden wurden. Das eigentliche Problem ist die Fehlerbehandlung bzw. die Synchronisation auf den Frame-Start. Eine Möglichkeit ist ein einfacher Automat, der alles erledigt und zudem noch einfach erweitert werden kann. Mikrocontroller Labor EIT/TI Gruppe A - 5 -
1.2 Einführung zu Automaten Ein für diese Aufgabe nutzbare Automat ist ein Moore-Automat. Der Moore-Automat wartet im aktuellen Zustand auf ein bestimmtes Byte, damit er überhaupt erst in den nächsten Zustand wechseln kann. Da bei obigem Datenframe immer bekannt ist, was in welchem Zustand erwartet wird, ist der Moore-Automat die ideale Lösung für das Problem. Kommt das richtige Byte, geht der Automat zum nächsten State, sonst geht er zurück zu Idle. 1.2.1 Diagramm für Datenüberprüfung ohne 0xA und 0xD Solche Automaten werden mit Hilfe einer switch/case Struktur realisiert, wobei in jedem case der nächste Zustand bzw. Idle anhand einer Überprüfung festgelegt wird. Zur besseren Lesbarkeit werden die Zustandsnamen in einem enum (Aufzählung) hinterlegt: enum erxstate {Idle, Data0, }; // enum anlegen Mikrocontroller Labor EIT/TI Gruppe A - 6 -
1.2.2 Struktogramm für Automaten aus 1.2.1 2 Literatur µvision User's Guide http://www.keil.com/ C_Programmierung_mit_dem_M_Dongle.pdf, HS Pforzheim Kapitel aus der Vorlesung Mikrocontroller Labor EIT/TI Gruppe A - 7 -
3 Aufgaben Die heutigen Programmierschritte gehen vom einfachen Senden von Bytes zum Empfangen von Bytes. Danach sollen Datenpakete gesendet und empfangen werden, um Techniken für die blockierfreie Datenkommunikation zu erlernen. Den Schluss bildet die schaltbare Datenkommunikation mit einer Sicherungsschicht, wie sie heutzutage normal ist. Das Ergebnis ist ein Voltmeter, welches die gemessenen Daten bei Bedarf an einen anderen Teilnehmer senden bzw. dessen Daten empfangen und darstellen kann. 3.1 Aufgabe 3.1 Byte senden Erstellen Sie ein Programm, welches nach erfolgter Initialisierung von Board und UART2 in der Mainloop den Taster des Joysticks abfragt. Bei jedem erkannten Taster-Druck soll ein beliebiges, darstellbares ASCII-Zeichen abschickt werden. Zum Testen verbinden Sie das Board per Nullmodem-Kabel mit dem PC und starten ein Terminal, z.b. HTerm. Das bedeutet, wenn der Joy-Taster gedrückt wurde, wird ein Zeichen gesendet. Wird er gedrückt gehalten, sollen keine weiteren Zeichen gesendet werden. Es muss ein Tastendruck erkannt werden, also Taste wird aktiv, danach muss die Taste erst wieder inaktiv werden bevor ein neues Zeichen gesendet werden kann. 3.1.1 Aufgabenpunkte für 3.1 Anleitung und die notwendigen Kapitel aus dem Vorlesungsscript lesen PAP für das Hauptfile erstellen und abgeben (andreas.reber@hs-pforzheim.de) Projekt anlegen und die notwendigen Initialisierungen einfügen Endlosschleife erstellen (Abfrage von Joystick bzw. Sendepuffer-Flag) Ausgabe eines Zeichens wenn beide Bedingungen war sind 3.1.2 Fragen zu 3.1 Welche Baudrate benötigen Sie mindestens, wenn 1750 Zeichen pro Sekunde im 8N1-Format übertragen werden sollen? 3.1.3 Abnahmepunkte für 3.1 Das funktionierende Programm wurde vorgeführt PAP für die Main-Schleife Korrekte Endlosschleife Code korrekt formatiert (Allman Style) Unterschrift: Mikrocontroller Labor EIT/TI Gruppe A - 8 -
3.2 Aufgabe 3.2 Byte empfangen Erweitern Sie ihr Programm um einen Empfangsblock (kein Unterprogramm) und geben Sie das empfange Zeichen auf dem LCD aus. Zum Testen senden lassen Sie sich ein Zeichen vom Nachbarn oder vom PC schicken. Warten Sie dabei nicht, bis ein Zeichen da ist, sondern reagieren Sie nur, wenn ein Zeichen im Empfangspuffer liegt. 3.2.1 Aufgabenpunkte für 3.2 Anleitung und die notwendigen Kapitel aus dem Vorlesungsscript lesen PAP für das Hauptfile erstellen und abgeben (andreas.reber@hs-pforzheim.de) Hauptfile kopieren (nur C-File) und einbinden Endlosschleife erweitern (Abfrage von Empfangspuffer-Flag) Ausgabe des empfangenen Zeichens auf das LCD 3.2.2 Abnahmepunkte für 3.2 Das funktionierende Programm wurde vorgeführt PAP für die Main-Schleife Korrekte Endlosschleife Code korrekt formatiert (Allman Style) Unterschrift: 3.3 Aufgabe 3.3 Voltmeter mit Kommunikation Nehmen Sie die Aufgabe 2.4 als Vorlage und fügen Sie einen Sendeblock (kein Unterprogramm) hinzu. Die in ASCII gewandelten AD-Daten sollen an einen Nachbarn geschickt werden, der diese dann empfängt und darstellt. Im Sendeframe soll kein Komma enthalten sein. Erweitern Sie ihre eigene Software so, dass auch Sie die Daten eines Nachbarn darstellen können. Dazu bekommt das LCD eine weitere Zeile (rot markiert), die den empfangenen Wert darstellt. Stellen Sie sicher, dass nur darstellbare Werte auf dem LCD erscheinen. Für das Senden gilt ebenfalls, dass nur veränderte Werte per UART gesendet werden. In dieser Aufgabe wird keine Datensicherheit verwendet, sondern es soll nur das byteweise Senden bzw. Empfangen ohne Behinderung der Hauptschleife realisiert werden. Der Empfangsblock sammelt erst ein komplettes Datenpaket, bevor es auf das LCD geschrieben wird. Um die Datenorganisation zu vereinfachen, wird je ein Array für das Senden und das Empfangen angelegt. Die vom Umwandlungsprogramm erzeugten ASCII-Daten für die mv sind im Sendearray abgespeichert. Aus diesem Array werden dann die Daten für das Senden und für die LCD-Ausgabe entnommen. Der Empfangsblock schreibt seine Daten in das Empfangsarray. Mikrocontroller Labor EIT/TI Gruppe A - 9 -
Zugehörige LCD-Ansicht nach dem Start: UART-Aufgabe A ADC Status: Off ADC Wert: 0.000 V ADC Wert: 0000 mv ADC RX Wert: 0.000 V 3.3.1 Aufgabenpunkte für 3.3 Anleitung und die notwendigen Kapitel aus dem Vorlesungsscript lesen PAP für das Hauptfile erstellen und abgeben Je ein PAP für den Sende- bzw. den Empfangsblock erstellen und abgeben (andreas.reber@hs-pforzheim.de) C-File Aufgabe2_4 kopieren und in Aufgabe3_3 umbenennen Endlosschleife erweitern (Block für Senden, Empfangen und Ausgabe LCD) Ausgabe der empfangenen Zeichen auf das LCD Datenarrays anlegen 3.3.2 Fragen zu 3.3 Welche Baudrate benötigen Sie mindestens, wenn 4 Datenframes im 8N1-Format pro Sekunde komplett übertragen werden sollen? In den verschiedenen Peripherien müssen bestimmte Flags abgefragt bzw. gesetzt werden. Ergänzen Sie die Verbindungen zwischen ISR, ADC und Hauptprogramm. Schreiben Sie die verwendeten Steuervariablen auf die Pfeile. Der Pfeil geht immer von dem Block aus, der die Aktion startet. ISR Hauptprogramm UART TX ADC UART RX Software 3.3.3 Abnahmepunkte für 3.3 Peripherieblock Das funktionierende Programm wurde vorgeführt Umbenannte Kopie von 2.4 verwendet PAP für das Hauptfile PAP für die Struktur Senden PAP für die Struktur Empfangen Datenarrays angelegt und verwendet Code korrekt formatiert (Allman Style) Unterschrift: Mikrocontroller Labor EIT/TI Gruppe A - 10 -
3.4 Aufgabe 3.4 Schaltbare und sichere Kommunikation Erweitern Sie die Aufgabe 3.3 um eine Abfrage, ob die Daten per UART abgeschickt werden sollen oder nicht. Des Weiteren sollen die Daten, die per UART gesendet werden, mit einer Datensicherung nach Kapitel 1.1.7 und 1.1.8 ausgestattet werden. Dazu müssen in dem Sendeblock die notwendigen Erweiterungen eingefügt werden. Im Automaten für den Empfangsblock werden die Daten auf Gültigkeit hin überprüft, d.h. die beiden Frame-Kennzeichen müssen korrekt und die restlichen Zeichen müssen Zahlen sein. Die beiden Datenarrays aus 3_3 sollen um je 2 Elemente vergrößert werden, damit Frame Start und Ende abgespeichert werden können. Zugehörige LCD-Ansicht nach dem Start: UART-Aufgabe A ADC Status: Off ADC Wert: 0.000 V ADC Wert: 0000 mv ADC TX: Off ADC RX Wert: 0.000 V 3.4.1 Aufgabenpunkte für 3.4 Anleitung und die notwendigen Kapitel aus dem Vorlesungsscript lesen PAP für das Hauptfile erstellen und per Mail abgeben PAP für den Sendeblock erstellen und abgeben (andreas.reber@hs-pforzheim.de) Hauptfile kopieren (nur C-File) und einbinden Sendeblock um die Sicherheit erweitern Empfangsblock als Automat realisieren Abfragen von Joy_Up (Tx Ein) und Joy_Down (Tx Aus) einfügen und Funktion realisieren Datenarrays erweitern 3.4.2 Fragen zu 3.4 Weshalb macht es Sinn, im Empfangsarray Frame Start und Ende abzuspeichern 3.4.3 Abnahmepunkte für 3.4 Das funktionierende Programm wurde vorgeführt PAP für das Hauptfile PAP für die geänderte Struktur Senden PAP für die geänderte Struktur Empfangen Datenarrays erweitert und verwendet Code korrekt formatiert (Allman Style) Testframe ok A1234E Testframe ok A345EA6543E Unterschrift: Abnahmekriterien Software, die bei der Abnahme nicht akzeptiert werden: - Warteschleifen in den Sende- bzw. Empfangsroutinen - Doppelter Code Mikrocontroller Labor EIT/TI Gruppe A - 11 -