Mikrocomputer INF 5T Wintersemester 2004/2005

Inhaltsverzeichnis

1 Einführung	4

1.1 Architektur eines Mikrocomputers	4

1.2 Möglichkeiten der Algorithmusimplementierung	5

1.2.1 Algorithmusentwicklung	5

1.2.2 Algorithmusimplementierung	5

1.3 ?	6

1.4 ?	6

1.5 Logikfamilien	6

1.6 Logikbausteine	6

1.6.1 Bezeichnungssystematik	6

1.6.2 Beispiele der 74er Serie	6

2 CPU	7

2.1 Grundlagen Befehlsabarbeitung und Maschinensprache	7

2.1.1 Befehlsanordnung im Speicher	7

2.1.2 Maschinenprogramm	7

2.1.3 Prinzip Maschinenprogramm	7

2.1.4 Befehlszyklus	8

2.2 Blockdiagramm CPU	8

2.3 Betriebsarten der CPU	8

2.3.1 Normaler Betriebsmodus	8

2.3.2 Interrupt-Modus	9

2.3.2.1 Begriffe	9

2.3.2.2 Abarbeitung von Interrupts	9

2.3.2.3 Interrupt Control Register	9

2.3.2.4 Prinzipielle Programmstruktur mit Interrupt-Servicefunktion	9

2.3.3 Power Down-Modus	10

2.3.4 DMA-Modus	10

3 Peripheriemodule	11

3.1 Digitale Ports	11

3.2 Timer und Zähler	11

3.2.1 Vorlesungsübung 2	12

3.3 Peripheriemodule für serielle Datenübertragung	14

3.3.1 Allgemeines	14

3.3.1.1 Unterscheidung parallel – seriell	14

3.3.1.2 Kommunikationsmodi	14

3.3.1.3 Übertragungsmodi synchron – asynchron	14

3.3.2 Asynchrone Übertragung mit UART	15

3.3.3 Synchrone Datenübertragung	16

3.3.3.1 Separate Übertragung von Takt und Rahmen-Anfang/Ende	16

3.3.4 Physical Layer	16

3.3.4.1 RS 232-Standard	16

3.3.4.2 RS485/488	17

3.3.5 CAN	17

4 Programmiermodelle und Assemblerprogrammierung	19

4.1 Arithmetik in B-Komplement-Darstellung	19

4.1.1 Ganzzahlen	19

4.1.1.1 Addition	19

4.1.1.2 Subtraktion	20

4.1.1.3 Multiplikation	21

4.1.2 Festkomma-Zahlen	21

4.1.2.1 Addition	23

4.1.2.2 Subtraktion	24

4.1.2.3 Multiplikation	24

4.2 Programmiermodelle	25

4.2.1 Registerstrukturen	25

4.2.2 Operanden-Adressierung	25

4.2.3 Adressierung Code	26

4.2.3.1 Ein Instruction Pointer	26

4.2.3.2 Banking	26

4.2.3.3 Segmentierung	27

4.3 Maschinenbefehle - Assemblersprache	28

4.3.1 Transportbefehle	28

4.3.2 Datenbearbeitungsbefehle	28

4.3.3 Rotier- und Schiebebefehle	29

4.3.4 Bitmanipulation	29

4.3.5 Programm-Steuer-Befehle	30

4.3.6 CPU-Steuerbefehle	31

4.3.7 Unterschied Controller – DSP – Prozessor	32

5 Bussysteme	33

5.1 Grundlagen Busarchitektur	33

5.1.1 Überblick Busse	33

5.1.2 Einteilung Busarchitekturen	33

5.1.3 Prinzipieller Bus-Aufbau	34

5.2 Buszyklus	35

5.2.1 Asynchroner Buszyklus	35

5.2.2 Synchroner Buszyklus	36

5.2.3 Multiplex von Adressen und Daten	37

5.3 Adressraum-Dekodierung	38

5.3.1 Minimale Adress-Dekodierung	38

5.3.2 Maximale Adress-Dekodierung	38

Einführung

Prüfung und Literatur

Architektur eines Mikrocomputers

Derivat: Halbleiter-Hersteller bieten Controller-Fam. an, welche auf einer CPU basieren (= ein Maschinenbefehlsatz), jedoch mit unterschiedlichen Peripherieaussattung (on-chip).

Ausgewählte Herstellerliste:

Hersteller	Produkt
Infineon	8051-Fam. 8-Bit C167-Fam. 16-Bit (Einsatz im Praktikum) TriCore 32-Bit
Motorola	68 ... 05 / 08 / 12 PowerPC 32-Bit
Philips	8051 XA
MicrochipTech	PIC
Atmel	8051 AVR ARM 32-Bit (sehr beliebt bei Handys)
Intel	ARM (-> XSCALE) 8051
Penesas	H8S, M16 bis 32-Bit
Zilog	Z80

Algorithmus

Algorithmusentwicklung

Nicht Thema dieser Vorlesung

Möglichkeiten der Algorithmusimplementierung

PROZESSOR mit Programmspeicher	Fest verdrahtete Logik	Programmierbare Logik
Programm schreiben in C, C++, Java, Delphi, ...		VHDL (Sprache)
Kompilieren / Übersetzen		Synthese
Maschinenprogramm, relative object-files	Schaltplan / Schematic	
Linken / Binden benötigt Speicheradressen des mC-Systems	Platzieren und Verdrahteten	
Maschinenprogramm mit physikalischen Adressbereichen	Layout, Lageplan	
Laden (serielle Schnittstelle)	Film, Platinenhersteller, Bestücken (z.B. löten)	
Baugruppe mit programmierten Programmspeicher	Fertige Baugruppe	
Standard-Baustein billig flexibel programmierbar	statische lösung zeit- & kostenintensiv	sehr kostenintensiv komplex nicht jedes VHDL- Programm ist realisierbar

Informationsabbildung und -darstellung

Abbildung

Darstellung
analoge:	zeitkontinuierlich
wertkontinuierlich
digitale:	zeitdiskret
wertdiskret, wertbegrenzt

Vorteile:

einfache Darstellung durch binäre Zustände

einfach speicherbar
z.B.	Kondensator geladen / ungeladen
Flipflop

störsicher
Gruppierung von Bits:
4 Bit	Nibble
8 Bit	Byte
16 Bit	Word	int
32 Bit	long word

Binäre Zustände in der Digitaltechnik

Low-High Potential
Leitung für Bit x GND ux Bezugspotential “Ground” “Masse” Log. 0 ≙ 0 < ux < uLOW Log. 1 uHigh < ux < uB Betriebsspannung

Zeitverzögerung

Leistung
Leistungsverbrauch logischer Gatter
y x pStart

Logikfamilien

Unterscheidungsmerkmale

Halbleitertechnologie (CMOS, Bipclon, BICMOS, ...)

Betriebsspannung

Low-High Pegel

Leistungsaufnahme

Geschwindigkeit

Treiberleistung

single-ended differential	t CLK CLK

Terminierung

Logikbausteine

Bezeichnungssystematik

Beispiele der 74er Serie

CPU

Grundlagen Befehlsabarbeitung und Maschinensprache

Prinzip Maschinenprogramm

Aufbau eines Maschinenbefehls	N-1	0 OP-CODE OPERANDEN Operations- code

Befehlsanordnung im Speicher

Jede Speicherzelle hat eine Adresse: z.B. von 0x0000 bis 0xFFFF; jede Stelle stellt dabei 4 Bit zu, also ist in dem Beispiel der Gesamtadressraum 16 Bit

Mit den Adressen werden BYTE adressiert, nicht WORDs. D.h. bei 16bit und 32bit Prozessoren werden immer Bytes adressiert, auch wenn 2 bzw. 4 Byte auf einmal ausgelesen werden (können).
=> Adressen werden (meist) byteweise gezählt

Bem.	Adresse	Inhalt	Assembler
CPU holt ersten Befehl nach Reset	0x0000	Befehl 1	NOP
	0x0001	Befehl 2	JUMP
Zieladresse des Sprunges (low Byte)	0x0002	ALB	
Zieladresse des Sprunges (hight Byte)	0x0003	AHB	
	...		
Zieladresse	0x00..	Befehl 3	

Maschinenprogramm

C-Beispielprogramm:

unsinged int a, b[5], c, i; // 16-bit

a = 0;

c = 2;

for( i = 5; i > 0; i-- ) {

a = a + b[i];

a = a * c;

}

Prinzip Maschinenprogramm

Folgerungen:

Maschinenbefehle sind aufgebaut aus:

Operations-Code „OpCode“

Operanden

interne Register ermöglichen es dem Compiler, das Maschinenprogramm effizienter zu gestalten:

effiziente Adressieren (da Adressen wesentlich kürzer)
=> kürzerer Code, schnellere Ausführung

schnellerer Zugriff als auf (externen) Speicher

wird ein Befehl falsch interpretiert (durch Störung), kann der nachfolgende Operand als Befehl interpretiert werden oder umgekehrt
=> die CPU schmiert ab

Befehlsabarbeitung besteht aus mehreren Phasen

Befehlszyklus

effiziente Abarbeitung durch „Pipelining“

Unit \ Cycle	i	i+1	i+2	i+3	i+4	i+5
Fetch	N	N+1	N+2	N+3	N+4	N+5
Decode		N	N+1	N+2	N+3	N+4
Operand Fetch			N	N+1	N+2	N+3
Execute				N	N+1	N+2
Write Back					N	N+1

Programmiermodelle

Blockdiagramm CPU

Registerstrukturen

Daten- und Adressenregister

Kontrollregister

Steuerbits für ALV

Interupt-Control-Register SER

Steuerregister

PSW
Statusbits der ALV
aktuelle Priorität
Registersatz

Warum Register für Adressierung und Operanden?

effiziente Adressierung
mehrere Registeradressen (Registerindex)
können in einem Maschinenbefehl codiert werden

schneller Zugriff auf interne Register

Optimierungsmöglichkeit für Compiler

Adressierung Operanden

Prüfungsfrage: Nennen Sie drei Adressierungsarten und erläutern Sie diese kurz.

Beschreibungen siehe Folien

Immediate

Memory direct

Register direct

Register indirect

Base Offset

Zirkuläre Adressierung

Adressierung Code

Unterschieden wird

absolute Adressierung

relative Adressierung

direkte Adressierung

indirekte Adressierung

Die (physikalische) Adressierung kann erfolgen über

einen Instruction Pointer

mehrere Instruction Pointer	 Segmentierung
 Banking

Grundstrukturen C-Assembler

Betriebsarten der CPU

Normaler Programmablauf

int main( void ) { Initialisieren(); while( 1 ) { /* Polling-Schleife */ EingängeLesen(); /* !! no busy waiting !! */ AusgangszuständeBerechnen(); AusgängeSchreiben(); } }	Adresse der Routine “Initialisieren” CALL Init L1: CALL Input CALL Comp CALL Output JUMP L1

Main-Loop
Polling-Schleife oder Hauptschleife

Enthält keine „busy-waitings“ (aktives Warten auf Eingaben).

Typischerweise werden in der Pollingschleife Benutzereingaben und Displayausgaben bearbeitet oder Ereignisse bearbeitet, welche Bearbeitungszeiten bis ≈ 50ms tolerieren.

Im Allgemeinen läßt sich eine maximale Durchlaufzeit der Pollingschleife ermitteln  falls der Controller nur die Pollingschleife bearbeitet, wäre diese „echtzeitfähig“ bis zu dieser Durchlaufzeit.

Echtzeitfähig = maximale Rechenzeit wird garantiert.

Ereignisse, welche eine schnellere Bearbeitung erfordern als die Pollingschleife Laufzeit hat, werden in Interruptfunktionen behandelt.

Interrupt-Modus

Begriffe

Unterscheidung „Exceptions“.

Asynchron zum Programmlauf (externe Ereignisse)

Synchron zum Programmlauf (Stackover- / -underflow, ...)

maskierbar (d.h. kann die Exception deaktiviert werden)

Priorität

Einteilung nach Filk/Liebig:

Traps: synchron zum Programmlauf

Interrupts: asynchron

Einteilung Infineon C166-Serie:

Traps: nicht maskierbar

Hardware-Traps (Reset, NMI (Non Maskable Interrupt), Bufferoverflow, ...)

Software-Traps

Interrupts: maskierbar, Priorität einstellbar (im wesentlichen die asynchronen HW-Ereignisse)

Abarbeitung von Interrupts

Prioritäten

Aufruf der Interrupt-Servicefunktion

Interrupt-Latenzzeit

Prüfungsfrage: Was passiert bei einem Interrupt? (siehe Folie „Aufruf der Interrupt-Service...“

Interrupt Control Register

<Folie „Aufbau Interrupt Control Register“ und „Programm Status Word ...“>

z.B.	T3IC =	88;	//dezimal
0x48;	//hexadezimal

⇒ enable flag und Priorität 6 wurden gesetzt

IEN = 1	// IEN bitadressierbar
// im Headerfile hinterlegt

T3IE = 0;	//  T3-Interrupt disabled

Prinzipielle Programmstruktur mit Interrupt-Servicefunktion

#include <reg161.h>

int main( void )

{

T3IC=0x48;

IEN=1;

...	//restliche Initialisierungen
while( 1 ) {

EingängeLesen();
Zustände();
Ausgänge();
}
}

/* Interrupt-Servicefunktion

void Timer3( void ) interrupt 0x23 { /* 0x23 ist die Interrupt-Nr. */

...

}

Power-Down Modi

Stromspar-Modi können durch verschiedene Maßnahmen eingeleitet werden.

Abschalten von Peripheriemodulen, welche (momentan) nicht benötigt werden

Verringerung der Taktfrequenz (durch Konfigurationsbits)

CPU abschalten (Aufwecken z.B. durch Interrupt)

spezielle Befehle, z.B. SLEEP, IDLE, PWRDOWN

DMA-Modus

„Direct Memory Access“
CPU übergibt die Kontrolle über den Speicher an ein Peripheriegerät.

Peripheriemodule

Digitale Ports

Ports sind Anschlüsse des Controller-Chips für Steueraufgaben. Es gibt zwei Typen:

Digitale Eingangsports
Eingangsspannung am Port-Pin wird in eine logische 0 oder 1 verwandelt ( Electrical Characteristics);

Digitaler Ausgangsport
Logische 0 oder 1 wird in ein Low- oder High-Potential von einem Pin umgesetzt.

Typischerweise werden die Portpins Portregistern zugeordnet.

P2	16-Bit	0xFFC0	physikalische Adresse

...

VAR = *((unsigned int volatile *) 0xFFC0);

Im (Keil)-C erfolgt der Zugriff über sogenanntes SFR (eng. Special Funktion Register). Diese Funktionen und andere Werte sind in der spezifischen Header-Datei zum jeweiligen Controller hinterlegt (z.B. #include <reg161.h>)

Beispiel:

SFR	P2	0xFFC0

Umschaltung zwischen digitalem Eingangsport und Ausgangsport erfolgt typischerweise über Konfigurationsregister
z.B. beim Port P2 mittels Registers DP2

Beispiel:

z.B.	...	4	3	2	1	0	
		0	1	1	0	0	DP2
	...	...	...	Output	Input	Input	P2

in C. Hinweis: DP2 heißt Direction Port 2

DP2 = 0x0000; /* alles Eingänge */

Variable = P2;

DP2 = 0xFFFF; /* alles Ausgänge */

P2 = Variable;

Timer und Counter

Grundaufbau

Wichtigste Verwendungszwecke:

Zeitbasis erzeugen (unabhängig von der CPU-Clock, denn wir wollen vielleicht nur Milli-Sekunden oder Sekunden für die Messtechnik verwenden)

Ereignisse zählen

Beschreibung zu Folie <mc_kap_3-2_timer>, Seite 1:

Wir haben eine CPU. Diese CPU ist MHz-getaktet, typischerweise mit 16 und 20 MHz. Wir könnten also die CPU zählen lassen. Das Problem ist nur, dass der Prozessor 16 Bit breit ist und somit max. bis 216 = 65535 zählen kann.

Ersatz: ein Vorteiler (engl. Prescaler) teilt die Frequenzen in 2er Pozenzen (also 20, 21, ..., 215). Den Wert des Teilers (also 0 – 15) liest der Vorteiler aus dem Vorteiler-Register (engl. Prescale-Register). Dieses Register kann über den Bus beschrieben werden.

Der n-Bit-Zähler (engl. n-Bit-Counter) zählt die Impulse, die der Vorteiler abgegeben hat. Aber nur wenn der Counter überläuft, wird ein Interrupt-Request-Flag gesetzt. Wenn wir also früher einen Interrupt auslösen wollen, dann müssen wir den Counter bei einem Wert != 0 starten lassen, und schon läuft er eher über!

Zeitbasiserzeugung nur mit Zählerregister. Laden in Interrupt-Servicefunktion
void Timer interrupt 0x...
{
TIM = Startwert; // -10000
...
}
nicht exakt, da Aufruf Zeit benötigt
genauer:
TIM = TIM + Startwert; // bei uns: TIM – 10000

separates Reload-Regster; kein Code in der Service-Routine nötig. Das Reload-Register speichert also den Initialwert des Counters, für die nächste Zählung, nachdem ein Interrupt ausgelöst wurde

Wenn ein Interrupt angefordert wird, ist TFLag = 1, ansonsten 0.

Der rechte Schalter dient dient zum An- und Ausschalten der Zeitzählung

Der linke Schalter bestimmt den Modus, also ob der Zähler raufzählen soll (i++) oder runter zählen soll (i--).

Gate-Modus: zählen, nur wenn high ist

Prescaler 1/16  Eingangstakt Timer = 1MHz
gewünscht: 10ms Überlaufperiode 10000 * zählen

Capture (Beschreibung zu Folie <mc_kap_3-2_timer>, Seite 2):

Bei einem Ereignis wird der Counter-Wert in das Capture-Register kopiert (damit man also feststellen kann, wie viel Zeit bis zu diesem Ereignis vergangen ist).
Beispiel: Ereignis E1 erzeugt Cap1, Ereignis E2 erzeugt Cap2. Wie groß ist die Zeitdifferenz?
Lösung:

Wann wird reagiert? Z.B. nur bei positiven Flanken

Pulsweitenmodulation (PWM) (Beschreibung zu Folie <mc_kap_3-2_timer>, Seite 3):

Wir führen jetzt einen Compare-Wert ein

Unterhalb des Compare-Wertes ist COUT high (1), oberhalb low (0).

COUT ist also ein Pulsweitensignal, das angibt, wann ein Ereignis eingetreten ist (wo also der Compare-Wert lag).

Vorlesungsübung 2

Zeitbasis = 10 ms
-> soll 4 Micro-Sek. Periode haben => 250 kHz

T3CON

T2CON

T3-Takt 4 Mic-Sec / 250 kHz

Überlauf-Periode: 10.000 Mic-Sec

=> Reload-Wert = 2500 (weil Timer 3 hochzählt)

Der C-Code könnte irgendwie so aufgebaut sein:

#define TC_TxM(y) ( (y << 3) & 0x0038) // y: {0;...;7}

T3CON = 0x0043;

//besser:

T3CON = TC_TxM( 0 ) | TC_TxI( 3 );

T3UD = 0; //bewusst initialisieren, so dass er aufwärts zählt

T3UDE = 0;

...

T2CON = 0x0027;

//besser:

T2CON = TC_TxM( 4 ) | TC_TxI( 7 );

T2R = 0;

T2 = -2500; //Reload-Register Laden

T3 = -2500;

T3IC = IC_ILVL( 3 ) //Interrupt-Register konfigurieren

//hier sieht man auch die Priorität

T3IE = 1; // Interupt aktivieren (enablen)

IEN = 1; // globale Enable/Disalbe-Flag

T3R = 1; // so, jetzt geht's los!

void main( void )

{

unsigned int wtimer1000ms = 100;

unsigned int f1000ms = 0; //flag, ob eine sec. vergangen ist

//wird in der Polling-Schleife geprüft

...

while( 1 ) {

... // read inputs

if( f1000ms ) { // dann schrei!

if( ENGINEON_1 ) ..++;

}

}

//interrupt-service-Routine

void TIMER3( void ) interrupt 0x23

{

wtimer1000ms--;

if( wtimer1000ms == 0 ) {

wtimer1000ms = 100;

f1000ms = 1;

}

}

Serielle Datenübertragung

Allgemeines

Unterscheidung parallel – seriell

parallel

zu einem Zeitpunkt werden mehrere Bits auf mehreren Leitungen übertragen

seriell

ein Bit je Zeit auf einer Leitung

Vorteil:

definierte geometrische Struktur möglich

keine Laufzeitdifferenzen

preisgünstigeres Kabel

Kommunikationsmodus

Simplex: Übertragung nur in eine Richtung (z.B. Master  Slave)

Halb-Duplex: eine Übertragungsstrecke; beide Richtungen sind möglich, aber immer nur nacheinander (Master  Slave, Master  Slave)

Duplex: zwei Übertragungsstrecken, beide Richtungen gleichzeitig möglich (Master ↔ Slave)

Übertragungsmodi synchron – asynchron

Empfänger erhält „nur“ eine Folge von 0/1. Problematik:

Anfang und Ende eines Bits

Anfang und Ende eines Zeichens

Anfang und Ende einer Nachricht

Synchrone Übertragung

USRT (engl. universal synchronious receive transmit device); einfache Implementierung in Microcontrollern

Takt des Senders ist beim Empfänger verfügbar

durch separate Taktleitung (typ. auf Baugruppen)

durch Taktregeneratoren aus dem Bitstrom

Asynchrone Übertragung

UART (engl. universal ansynchronious receive transmit device); einfache Implementierung in Microcontrollern

Takt des Senders und des Empfängers sind unabhängig. Synchronisation erfolgt typ. bei jedem Zeichen neu, bzw. die Anzahl der übertragbaren Bits ist begrenzt

Die Kombination aus USRT und UART nennt man USART.

Asynchrone serielle Datenübertragung (UART)

Byte-orientiertes Übertragungsverfahren

Synchronisation erfolgt bei jedem neuen Zeichen

Dauer eines Bits ist Bekannt (ca.)

Typischer Ablauf Sendevorgang:

Flanke dient zur Synchronisation, Abtastung in der Bit-Mitte (typischerweise bis zu drei Abtastungen).

Synchrone Datenübertragung

Separate Übertragung des Taktes – Serial Microwire (SPI)

Eingesetzt zur Kommunikation auf der Baugruppe

Prinzipieller Kommunikationsablauf

um eine Taktregeneration zu ermöglichen, müssen die Bits (0, 1) kodiert werden, z.B. Manchester-Codierung

Übung: Serial Microwire

Init:

DP1H = 0x70;

Deklaration:

sbit LD = P1H^4;
sbit CLK = P1H^6
sbit DIN = P1H^5

load_da (int da_a, int da_b) {

int mask;
CLK = 0;
LD = 0;
mask = 0x0800;	// Bit 11

while () {

if ((da_a & mask) != 0) {
DIN = 1;
} else {
DIN = 0;
}
CLK = 1;	// Flanke
mask = mask >> 1;
CLU = 0;
}
LD = 1;
}

Physical Layer

RS 232-Standard

<siehe Folie „mc_kap3_3_rs232_rs485.pdf“>

RS485/488

Merkmale von RS485:

differentielle Datenübertragung

verdrillte Datenleitungen, um störunempfinglich zu sein

zumeist nur drei Leitungen: zwei ineinander verdrillte Leitungen für differentielle Datenübertragung plus eine Masse-Leitung
=> Betrieb nur in eine Richtung möglich
=> Halb-Duplex-Betrieb

es ist auch möglich, eine Bus-Struktur aufzubauen

Der RS485-Standard wird auch vom SIEMENS-Profibus verwendet

Merkmale von RS488: genauso wie bei RS485, nur dass es zwei verdrillte Adern gibt, so dass Full-Duplex-Betrieb möglich ist.

<siehe Folie „mc_kap3_3_rs232_rs485.pdf“>

LIN-Bus

<siehe Folie „mc_kap3_3_lin.pdf“>

CAN-Bus

<siehe Folie „mc_kap3_3_can.pdf“>

CPU – 2. Teil

Ganzzahlarithmetik Grundlagen

Bearbeitungsreihenfolge

z.B.

2-er Komplement

Idee: ALU hat nur Addierwerk für ganze Zahlen. Trotzdem sollen Substraktionen möglich sein!

einfach HW zur Ermittlung des 2-er Komplements

Wertebereich 2-er komplementäre Zahlen (N Bits)

Multiplikation

Ergebnis 2⋅N Bits nötig

2-er Komplement als Festkommazahl

Idee: Bei einer Multiplikation soll der darstellbare Zahlenbereich nicht verlassen werden

⇒ Zahlenbereich	[-1 ... 0 ... 1[

z.B. N=8

Skalierung

Fixed Point Multiplikation Beispiel:

N = 4
+2	0 • 0 1 0
*-6	1 • 0 1 0
___	________	________
-12	1•110100
für richtiges Ergebnis um 1 nach links schieben
Ergebnis der Ganzzahlmultipliziereinhei

ein nach links geschoben
1 • 1 1 0 1 0 0 0
Reduktion
auf 4 Bits

Grundprinzip der Signalverarbeitung

Programmiermodelle

(Registerstrukturen)

Einteilung der Register in

Kontrollregister

Interrupt-Kontrollregister

Register zur Konfiguration der Peripheriemodule (SFR)

Steuerbits für die ALU u.v.m

Statusregister; sie spiegeln den momentanen „Zustand“ der CPU wieder und ändern sich durch Operationen

Priorität des momentan bearbeiteten Codes

Status Flags der ALU (Zero-Flag, Negativ, ...)

Registersatz

Adressen- und Operanden-Register

(Operanden-Adressierung)

Arten der Adressierung:

Immediate: hier handelt es sich um Konstanten, die fest in den Befehl codiert sind
z.B. ADD R3, # data3; damit reicht ein Wort als Gesamtbefehl aus
z.B. ADD R3, # data16; damit stehen 16 Bit für die Konstante zur Verfügung; es werden zwei Wörter verwendet

Memory Direct: der Adress-Operand ist bei 16-Bit-Prozessoren mit 16-Bit-Adressraum 24 Bit lang; somit benötigt ein Befehl zwei Wörter

Register Direct: direkte Register-Adressierung

single Index
z.B. ADD A, @Rx

double Index
z.B. ADD A, Rx, Ry

Offset

Base Offset: verwendet für Adressierung eines Stucture-Elements innerhalb eines Arrays

Implicit Base Offset: fusionieren der Bits; Vorsicht: nicht Addieren!
z.B. A = A + @SMEM

Register Indexed Base Offset

Circular Base-Offset

(Adressierung Code)

Adressierung (im einfachsten Fall) durch einen „Instruction Pointer“ bzw. „Program Counter“ wird bei der Abarbeitung des Programms automatisch inkrementiert.

Ausnahmen:

Sprünge

absolute Sprünge: IP wird mit neuem Wert geladen

relative Sprünge. zum IP wird eine Distanzadresse addiert

Unterprogramm/Funktionsaufruf

direkt: Adresse der Funktion ist im Code hinterlegt

indirekt: Adresse der Funktion ist im Register hinterlegt (dieses Verhalten entspricht in C den Funktionszeigern)

(Ein Instruction Pointer)

Gegeben: 8-Bit-Architektur, 16-Bit-Adressraum
⇒ JMPA (absoluter Sprung): 3-Byte-Befehl.

Zieladresse:

Gegeben: 16-Bit-Architektur
⇒ JMPA (relativer Sprung): 2-Byte-Befehl.

Zieladresse: ; Hinweise zu „JMPA“:

mit Bedingungen reichen u.U. 2 words nicht

indirekte Aufrufe/Sprünge; nur 16-Bit-Register (R0 ... R15)

(Banking)

Hinweise zum PDF „...“

Banking verwendet mehrere Speicherblätter, die über spezielle Maschinenbefehle ausgewählt werden

(Segmentierung)

Hinweise zum PDF ....

Wenn der Linker intelligent genug war, die Funktion nicht an die Grenze zu legen sondern in ein Segment, dann ist alles chillig.

Zerteilen der physikalischen Adresse auf zwei Register.

Maschinenbefehle - Assemblersprache

Einteilung:

Transportbefehle

Datenbearbeitungsbefehle

Programmsteuerbefehle

CPU-Steuerbefehle

Hinweise zu Folie „K-4.3_AssemblerBefehle.pdf“

(Transportbefehle)

A = ACCU = Akkumulator

DPTR = Data-Pointer

MOV A, @R2	R2: 8-Bit-Register

MOVX A, @DPTR	DPTR: 16-Bit-Register

MOVC A, @DPTR

8051: Harvard-Architektur:

internes RAM (8-Bit-Adresse MOV)

externes RAM (16-Bit-Adresse MOVX (external))

Code-Speicher (Konstanten + Code; 16-Bit-Adresse MOVC)

PUSH R3

Datenbearbeitungsbefehle

ADC

Beispiel: 8-Bit-CPU

Es sollen zwei 16-Bit-Zahlen addiert werden: c = a + b

CMPD1 ; for( i = 100, i >= 0; i++ ) {...}

Compare op1 ⇔ op2 ⇒ Flags werden gesetzt, z.B:: ZERO_Flag falls op1 == op2

INZ

(Rotier- und Schiebebefehle)

ROR R0, #1 (Rotiere Register R0 um eine Stelle nach rechts)

SHR R0, #2 (Rechts-Shift um zwei Stellen; es werden 0en aufgefüllt)

Beispiel: Rechtsshift

singed int R0;

R1 = R0 / 2

In dem Beispiel ist R0 eine positive Zahl. Probleme treten auf, wenn negative Zahlen behandelt werden. Dann muss das Vorzeichen-Bit wieder auf die erste Stelle kopiert werden.

ASHR R0, #1

Bitmanipulation

z.B. IC:

IC = 0x0044 | ( IC & 0x0080

Intern:

MOV R4, IC <- nun setzt Peripherie IR

AND R4, 0x0080

OR R4, 0x0044

MOV IC, R4 <- IR wird gelöscht !!!

Es hilft alles nichts: die CPU muss immer das gesamte Register lesen, das einzelne Bit setzten und dann das komplette Register zurückschreiben. Wenn in der Zeit von der Hardware ein Flag gesetzt wird, wird es von der CPU wieder gelöscht.

Hinweis zur Folie „Maschinenbefehle – Assemblersprache“, Seite 4

Der untere Absatz ist falsch und kann ignoriert werden.

Lösung: Protected Bits

Register msg-ctl (bei CAN-Versuch). Zwei Bits werden gebraucht.
Es gibt folgende Kombinationsmöglichkeiten:

01: Reset durch CPU

11: Setzen

11: unverändert lassen

Beispiel: LEDs zum Leuchten bringen

// niederwertige 8 Bit von a auf Port P2 ausgeben

IEN = 0

P2 = ( P2 & 0xFF00 ) | ( a & 0x00FF );

IEN = 1

jetzt komme einer auf die Idee, in einer Interrupt-Funktion die anderen 8 Bits zu beschreiben. Das ist schlecht.

// höherwertige 8 Bits von b auf P2 ausgeben

P2 = ( P2 & 0x00FF ) | ( a & 0x00FF );

Das Problem das hier auftritt: wenn jemand den Port schreibt und genau in dieser Phase der Interrupt ausgelöst und behandelt wird, dann wird das Ergebnis des Interrupts wieder überschrieben, da das reguläre Schreiben von a auf Port P2 mit einer Kopie von Port 2 arbeitet und diese Kopie dann zurückschreibt. Die Lösung wurde blau dargestellt.

(Programm-Steuer-Befehle)

Es existieren folgende Arten von Programm-Steuer-Befehlen:

Sprünge

Unterprogrammaufrufe

Sprünge

JMPA cc, op2 (Sprung)

für OP2 gilt: Zieladresse im gleichen Segment „Intra-Seg“

Möglichkeiten: für cc:

cc_uc (Condition-Code, unconditional; er springt immer) [if-else-Konstrukte]

cc_z (Condition-Code, Zero-Flag) [bei SUB Zero-Flag gesetzt ist]

cc_N (Condition Code, Null)

cc_NN (Condition Code, Not Null)

...

„einfache“ haben oft nur wenige Bedingungen

DJNZ op1, Zieladresse (Decrement Jump Not Zero)
 Einsatz in Schleifen, wo die Laufvariable nach unten gezählt wird.

Unterprogrammaufrufe

Intrasegment:

CALLA cc, ZielRET

( SP )  (SP ) - 2

(( SP ))  ( IP )

( IP )  Ziel

RET

( IP )  (( SP ))

( SP )  ( SP ) + 2

Intersegment

CALLS

( SP )  ( SP ) - 2

(( SP ))  ( CSP )

( SP )  ( SP ) - 2

(( SP ))  ( IP )

( CSP )

( ISP )

RETS

( IP )  (( SP ))

( SP ) + 2

( CSP )  (( SP ))

( SP ) + 2

RETI (Return für Interrupt-Aufruf)

( IP )  (( SP ))

( SP ) + 2

( CSP )  ( SP )

( PSW )  (( SP ))

auslösender Befehl für Interrupt-Service-Routine:

TRAP

(( SP ))  ( PSW )

(( SP ))  ( CSP )

(( SP ))  ( IP )

wird i.a. vom Interrupt-Controller bei Request in die Pipeline eingeschleust

(CPU-Steuerbefehle)

Wechseln von Registersätzen

Context-Pointer (CP) bestimmt den „angewählten“ Registersatz

In C (Keil-IDE) sieht das so aus:

void NAME ( void ) interrupt NR using REGNAME {

...

}

Parameterübergabe

Wenn man von einem C-Programm aus ein Assembler-Programm oder eine Assembler-Funktion aufrufen will, muss man beachten, wie der Controller die Parameter verarbeitet.

Beispiel: C-Aufruf

long function( int b, int c, long d, int e, int f ) { ... }

b  R8
c  R9
d  R10, R11
e  R12
f  Stack (weil der Controller nur 12 Register hat und alles weitere auf den Stack schieben muss)

Hinweis: die Rückgabe des Datentyps long erfolgt auf Register R4 und R7.

(Unterschied Controller – DSP – Prozessor)

Controller:

integrierte Peripheriemodule und effiziente Verbindung zur CPU

„mächtige“ Interruptverarbeitung

Bitmanipulation

DSP:

MAC (Multiplikations-Additions-Einheit) in einem Takt

Zero Overhead Loops: Schleifenzähler ist in Hardware realisiert, der parallel zur MAC-Einheit integriert ist

zirkuläre Adressierung

bit reversed Adressierung für Spektral-Analyse via FFT: die interne Berechnung und Darstellung erfolgt von links nach rechts von LSB zu MSB; die Ausgabe erfolgt genau anders herum und somit richtig lesbar für normale Programme

Festkomma-Arithmetik

Saturation (Sättigung); was passiert bei Überlauf? Bei Überlauf wird der Maximal-Wert gehalten und nicht im Zahlenring wieder von vorne angefangen ⇒ entspricht bei einem Audio-Verstärker der maximalen Leistungs-Begrenzung

Prozessor:

hohe Taktfrequenzen

riesiger Adressraum

Memory Management Unit mit Memory Protection

Grundregeln für effizientes C

Speicherwerte

Speichertypen:

NVM	Flash-ROM	Code, Konstanten	schreiben langsam + unflexibel, lesen mit fCPU

VM	RAM	Variablen	schreiben + lesen flexibel mit fCPU

NVM	EEPROM	Parameter	schreiben langsam aber flexibel

NVM: non volatile memory
VM: volatile memory

Alle 3 Typen können

on-chip	sehr effizienter Zugriff durch mehrere Busse, kurzer Zyklus

off-chip	typischerweise ein Bus für Flash + RAM, zum Teil Daten- und
Adressbus gemultiplext (  langsam)

realisiert werden.

⇒ Zeitkritischer Code in's interne Flash
häufig benötigte Variablen in's interne RAM (on-chip RAM)

Operandenverwendung

Konstanten

b = a + 3;

z.B.	8051 (8-Bit-Architektur)	8-Bit-Konstante	2-Byte-Befehl
16-Bit-Konstante	3-Byte-Befehl

C166 (16-Bit-Architektur)	3-Bit-Konstante	2-Byte-Befehl
16-Bit-Konstante	4-Byte-Befehl

ARM-7 (32-Bit-Architektur)	8-Bit-Konstante	4-Byte-Befehl

Variablen

B = C;

B, C im Registerformat

Register:

8051:	MOV A, RC
MOR RB, A	/2 Byte, 2 Befehlszyklen

C166:	MOV RB, RC	/2 Byte, 1 Befehlszyklus

internes RAM:

8051:	MOV A, MEMC
MOV MEMB, A	/4 Byte, 2 Befehlszyklen

C166:	MOV Ri, MEMC
MOV MEMB, Ri	/8 Byte, 2 Befehlszyklen

externes RAM:

8051:	MOV DPTR, MEMC
MOV A, @DPTR	/8 Byte, 8 Befehlszyklen

C166:	Code intern	RAM extern	10 CPU-Takte (5 Befehlszyklen)
Code extern	RAM extern	18 CPU-Takte (9 Befehlszyklen)
Bus gemultiplext

Arithmetik

Multiplikation C166 V1

Code intern, Variablen in Registern

char	8 Bit	10 Takte

int	16 Bit	10 Takte

long	32 Bit	46 Takte

float	32 Bit	170 Takte

double	64 Bit	372 Takte

Sinus C166 V1

32 Bit	2500 ... 3100 Takte

Multiplikation ARM7 (ohne FPU)

char	8 Bit	2 Takte

int	16 Bit	2 Takte

long	32 Bit	4 Takte (?)

float	414 Takte	GNU-C 

double	721 Takte	GNU-C 

Multiplikation MPC 555 mit FPU

float	4 Takte

double	5 Takte

Bussysteme

Grundlagen Busarchitektur

Überblick Busse

Ebenen im Überblick:

Chipebene: parallele Verbindungen, CPU-ALU-Register

Baugruppenebene:

parallele Verbindungen
Prozessor/Controller – Programm- und Variablenspeicher

serielle Verbindungen zur Peripheriebausteinen

Geräteebene:

ISA-Bus

PCI-Bus auf Motherboard (parallel und seriell)

VME (parallel und seriell)

Anlagenebene

Feldbusse (Profibus, ASI, Interbus, CAN, Ethernet, ...)

Einteilung Busarchitekturen

Überblick:

von-Neumann-Architektur

Havard-Architektur

von-Neumann-Architektur

Die Architektur zeichnet sich durch einen linearen Adressraum für Code und Daten aus.

Vorteil:

effektive Speicheraufteilung möglich

„platzsparend“, nur ein Adressbus und ein Datenbus

Beispiele: von-Neumann-Architektur

C167, Motorola 68HC12, Intel 80x86, ...

Havard-Architektur

Hier sind Adressräume für Code und Daten getrennt. Bussysteme sind mehrfach ausgeführt. Auf Baugruppen-Ebene verbraucht die Architektur viele Leitungen, aber auf Chip-Ebene ist das unkritisch.

Vorteil:

gleichzeitiger Zugriff auf Code- und Datenspeicher möglich (DSPs - „extended“ modified Havard Architecture mit Mehrfachauslegung der Bussysteme)

unterschiedliche (Bus-)Breiten für Code und Daten möglich ⇒ der Chip wird billiger, weil Chipfläche kostet Geld. (PIC-Serie der Firma MICROCHIP).

Nachteil:

falls die Busse aus dem Controller herausgeführt werden sollen: viele Pins nötig ⇒ weniger Pins für Steuerfunktionen
 Busse werden zusammen gelegt

Beispiel: Havard-Architektur

Intel 8051, AVR, PIC, DSP, ...

(Prinzipieller Bus-Aufbau)

8-Bit-Datenbus mit 8-Bit-Speicher:

16-Bit-Datenbus mit 16-Bit-Speicher:

Dabei muss folgendes Beachtet werden:

Der Controller adressiert den Speicher Byte-weise, aber der RAM interpretiert den Adressbus und damit die Adress-Pins als Word-Adresse!

WRL (Write Lower Byte): Anweisung, nur das Lower-Byte zu schreiben

WRH (Write Higher Byte): Anweisung, nur das Higher Byte zu schreiben

Buszyklus

Datenbus (8 Bit, 16, 32, 64, ...)

Adressbus (16, 24, 32, ...)

Steuersignale (Lesen, Schreiben)

Unterscheiung:

synchroner Buszyklus (+ Takt)

anynchroner Buszyklus

Synchroner Buszyklus

Hinweise zu Folie „K-5.2_Buszyklen.pdf“, Seite 1

Das Timing ist genauer realisiert.

Lese-Zyklus:

Startsignal ist low, Flanke kommt, ich muss die Adresse intern speichern.

Man benötigt immer zwei Takt-Zyklen: einen für die Adress-Übermittlung, einen für Lesen/Schreiben

Hinweise zu Folie „K-6_Speicherbausteine.pdf“, Seite 3

GW (Global Write): 32-bit-Zugriff

6 Leitungen, die sich mit Schreiben beschäftigen

OE-Leitung: Lese-Leitung

ZZ: hochohmiger Zustand in Stand-By-Betrieb versetzen

CLC (Clock): Synchroner Speicher

CSx (Chip Select): Auswahl der Baugruppe

Hinweise zu Folie „K-6_Speicherbausteine.pdf“, Seite 4

nicht verstanden ... !

Ein Burse-Zyklus hat nur 4 32-Bit-Wörter. Das ist so festgelegt.

Asynchroner Buszyklus

Hinweise zur Folie „K-5.2_Buszyklen.pdf“, Seite 1

Komponenten:

Adress-Bus: A0, ..., A23

Master: CPU, Micro-Controller

Vorgehen beim Lese-Zyklus:

Die CPU will Speicher Ax lesen

beim Read wird ein Aktiv low gelegt

der Slave ist hier bei uns der Speicher; er lässt sich ein bisschen Zeit, darauf zu antworten. zwischen aktiv low und Antwort des Speichers.

Vorgehen beim Schreib-Zyklus:

Die CPU will Daten schreiben

mit der steigenden Flanke von aktive Low auf high ist es das Übernahmesignal für den Speicher, die Daten vom Bus zu nehmen.

Hinweise zu Folie „K-6_Speicherbausteine.pdf“, Seite 1

SRAM: Statisches RAM: es behält den Inhalt bei, wenn die Spannung anliegt. Das ist beim dynamischen RAM nicht so.

Komponenten:

128 kB Speicher ⇒ 17 Adressleitungen notwendig: A0 – A16

Pin N.C. (not connected): nicht gebrauchter Pin als Reserve für die Zukunft, falls eine Adressleitung Nr. 18 für 256K gebraucht wird.

I/O-Ports: die Japaner fangen bei 1 das Zählen an.

CSx (Chip-Select): falls mehrere Bausteine zu einem großen Speicher zusammen gekoppelt wird, übernimmt jeder einen Teil-Adressraum. Mit dem Chip-Select wird dem Bauteil mitgeteilt, in welchem Adressraum er zu liegen hat.

Hinweise zu Folie „K-6_Speicherbausteine.pdf“, Seite 2

Lese-Zyklus:

Read-Cycle = Reaktionszeit; hier 70 ns.

wenn das Lesesignal weggenommen wird, kann es 25 ns dauern, bis der Baustein seine Treiber abgeschalten hat. Es kommt dann eh viel später der Schreib-Zugriff vom Master

Schreib-Zyklus:

wie beim Lese-Zylus.

Multiplex von Adress- und Datenbus

Beispiel: 8051-Derivat 80C32

Hinweis zu Folie „K-5.2_Buszyklen.pdf“, Seite 3

Havard-Architektur:

Auf Port 0: AD0 – AD7

Auf Port 2: A8 – A15

Das blaue liefert der Code-Speicher

ALE fallende Flanke: Latch

Hinweis zu Folie „K-5.2_Buszyklen.pdf“, Seite 4

Write-Zyklus:

Der Prozessor geht ins RAM rein

Er liefert selber das Signal

PSEN (Program Store Enable): Entweder auf Busspeicher oder auf Code-Speicher zugreifen

Hinweis zu Folie „K-5.2_Buszyklen.pdf“, Seite 2

Elemente:

BUS (P0): A0 – A15

Segment (P4): A16 - ...

RD: Q0 – Q15

ALE ist verlängerbar um einen Takt (für langsame Speicher)

BUS (P0) kann er verlängern

Vergleich:

nicht-gemultiplext: 2 Takte

gemultiplext: 3 Takte

Wort- und Bytezugriffe

Adressraum-Dekodierung

Minimale Dekodierung

<Folie „K-5.3_AdressDekodierung.pdf“, Seite 1>

Maximale Dekodierung

<Folie „K-5.3_AdressDekodierung.pdf“, Seite 2>

ODER-Gatter: Nur wenn alle Eingänge auf 0 wird CS aktiviert

Di wird auf Qi durchgeschaltet
letzter Zustand der Qi bleibt gespeichert
Qi im Tri-State-Zustand
interne Qi werden auf die Pins Qi getrieben

Man könnte in C den digitalen Ausgang U6 so ansprechen:

*(( unsigned char volatile xhuge * ) 0x8'0000 )) = 0xaF;

Erklärung:

volatile: teilt dem Compiler mit, dass er nichts optimieren oder wegschmeißen soll.

xhuge: C167-spezifisches Konstrukt zum Ansprechen des Zeugs

*((...) 0x8'0000): der Inhalt soll geschrieben werden.

Adressraum:

Übung 4

Flash ab 0x00'0000 - 0x0F'FFFF
2 * 512 kByte = 1 MByte

RAM ab 0x08'0000
2 * 128 kByte = 256 kByte

Wort- und Bytezugriffe möglich

Speichertechnologien

Mitschrift	Mikrocomputer

21.12.2004	Seite 43 von 44

Mikrocomputer

FH Ingolstadt; Mitschrift

FH Ingolstadt 2003 2004

2003-10-08T22:34:59

Ignaz Forster