29.01.2013 Aufrufe

Peter Gober Beuth Hochschule Für Technik Berlin

Peter Gober Beuth Hochschule Für Technik Berlin

Peter Gober Beuth Hochschule Für Technik Berlin

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Mikrocomputertechnik<br />

<strong>Peter</strong> <strong>Gober</strong><br />

<strong>Beuth</strong> <strong>Hochschule</strong> für <strong>Technik</strong> <strong>Berlin</strong><br />

Wintersemester 2011/2012<br />

1


Literatur<br />

• Günter Schmitt: Mikrocomputertechnik mit Controllern der Atmel<br />

AVR-RISC-Familie, 5. Auflage, Oldenbourg 2010.<br />

(10 Exemplare in der Bibliothek, Signatur ISBG )<br />

Achtung: Passt in Details nicht 100 % zu dem von uns<br />

verwendeten Prozessor.<br />

• Linksammlung auf meiner Homepage<br />

2


Überblick<br />

Digitaltechnik 6<br />

Zahlensysteme und Codes 15<br />

Aufbau eines Rechnersystems 30<br />

Programmentwicklung 40<br />

Speicher und Assembler-Befehle für den Datentransfer 45<br />

IO-Ports 50<br />

Arithmetische, logische und Bit-Befehle 59<br />

Assembler-Befehle für Sprünge 68<br />

Stack und Unterprogramme 75<br />

Interrupts 80<br />

Programmieren in C 90<br />

Energiesparen 94<br />

Timer/Counter 97<br />

Aspekte des Software Engineerings 110<br />

Serielle Schnittstelle RS-232 124<br />

A/D-Wandler 140<br />

Sensoren 155<br />

Serielle Bussysteme 163<br />

JTAG 179<br />

3


Inhalt / Mechatronik<br />

4


Mikrocomputer-basierte Steuerungen<br />

• Anwendungen:<br />

• Vorteile gegenüber fest aufgebauten Steuerungen<br />

(elektronisch/mechanisch):<br />

5


Zahlensysteme und Codes<br />

15


Binärsystem<br />

• Zahlen können mit „1“ und „0“ im Binärsystem (auch: Dualsystem,<br />

Zweiersystem) (zur Basis 2) dargestellt werden.<br />

• vorzeichenlos (= unsigned)<br />

• Beispiel für die Umrechnung dual � dezimal:<br />

1011 2 = 1·2³ + 0·2² + 1·2 1 + 1·2 0 = 11<br />

• Beispiel für die Umrechnung dezimal � dual:<br />

11 : 2 = 5 Rest 1<br />

5 : 2 = 2 Rest 1<br />

2 : 2 = 1 Rest 0<br />

1 : 2 = 0 Rest 1 Ergebnis: 1011 2<br />

• n Bits erlauben so die Darstellung der Zahlen 0…2 n -1.<br />

16


Addition von vorzeichenlosen Binärzahlen<br />

• Üblich: Feste Bitbreite der Addierschaltung. Hier: n = 4.<br />

• Beispiel 1:<br />

• Beispiel 2:<br />

dez.<br />

0 0 1 1 3<br />

+ 1 0 1 0 + 10<br />

1<br />

0 1 1 0 1 13<br />

dez.<br />

1 0 1 1 11<br />

+ 0 1 1 1 + 7<br />

1 1 1 1<br />

1 0 0 1 0 2<br />

Carry-Bit (C)<br />

(Übertrag)<br />

17


• Beispiel 1:<br />

• Beispiel 2:<br />

Subtraktion von vorzeichenlosen<br />

Binärzahlen<br />

dez.<br />

1 1 0 1 13<br />

- 0 0 1 1 - 3<br />

1<br />

0 1 0 1 0 10<br />

dez.<br />

0 0 1 0 2<br />

- 0 1 1 1 - 7<br />

1 1 1 1<br />

1 1 0 1 1 11<br />

Carry-Bit (C)<br />

(hier als „Borger“)<br />

18


Addition und Subtraktion von<br />

vorzeichenlosen Binärzahlen: Zahlenkreis<br />

19


Vorzeichenbehaftete Binärzahlen:<br />

Zweierkomplement (I)<br />

• vorzeichenbehaftet (= signed):<br />

– höchstwertiges Bit = 0 → positive Zahl<br />

– höchstwertiges Bit = 1 � negative Zahl in Zweierkomplement-<br />

Darstellung<br />

• „Clou“ der Zweierkomplement-Darstellung: Man kann mit einer<br />

Addier-Schaltung subtrahieren, indem man das Zweierkomplement<br />

addiert . (Keine Fallunterscheidung notwendig.)<br />

• Zu einem gegebenen Bitmuster muss man zusätzlich wissen, ob es<br />

eine vorzeichenlose oder eine vorzeichenbehaftete Binärzahl<br />

darstellt.<br />

– Beispiel: 11111111 kann 255 oder -1 heißen.<br />

20


Vorzeichenbehaftete Binärzahlen:<br />

Zweierkomplement (II)<br />

• Rezept Dezimalzahl � vorzeichenbehaftete Binärzahl<br />

– Positive Zahlen: wie gehabt<br />

– Negative Zahlen:<br />

• Von Vorzeichen befreit wie eine vorzeichenlose Zahl in Dualzahl umrechnen.<br />

• Alle Bits invertieren.<br />

• 1 addieren.<br />

• Rezept vorzeichenbehaftete Dualzahl � Dezimalzahl<br />

– Positive Zahlen (oberstes Bit = 0): wie gehabt<br />

– Negative Zahlen (oberstes Bit = 1):<br />

• Alle Bits invertieren.<br />

• 1 addieren.<br />

• Dualzahl wie eine vorzeichenlose Zahl in Dezimalzahl umrechnen und dann<br />

mit einem Minuszeichen versehen.<br />

• n Bits erlauben so die Darstellung der Zahlen: -2 n-1 ...(2 n-1 -1)<br />

21


• Beispiel 1:<br />

• Beispiel 2:<br />

Rechnen mit vorzeichenbehafteten<br />

Binärzahlen<br />

dez.<br />

0 0 1 1 3<br />

+ 1 0 1 1 + (-5)<br />

1 1<br />

0 1 1 1 0 -2<br />

dez.<br />

0 1 0 0 4<br />

+ 0 1 1 1 + 7<br />

1<br />

0 1 0 1 1 -5<br />

• Rechenwerke zeigen eine Bereichsüberschreitung bei<br />

vorzeichenbehafteten Zahlen durch das Overflow-Bit (V) an.<br />

22


Addition und Subtraktion von<br />

vorzeichenbehafteten Binärzahlen: Zahlenkreis<br />

23


Die Zahlen 0 – 15 in verschiedenen Zahlensystemen<br />

Dezimal<br />

(Basis 10)<br />

Binär<br />

(Basis 2)<br />

0 0000 0<br />

1 0001 1<br />

2 0010 2<br />

3 0011 3<br />

4 0100 4<br />

5 0101 5<br />

6 0110 6<br />

7 0111 7<br />

8 1000 8<br />

9 1001 9<br />

10 1010 A<br />

11 1011 B<br />

12 1100 C<br />

13 1101 D<br />

14 1110 E<br />

15 1111 F<br />

Hexadezimal<br />

(Basis 16)<br />

24


Gruppierung von Bits<br />

• 4 Bits = 1 Hexadezimal-Ziffer = 1 Nibble = 1 Half-Byte<br />

• 8 Bits = 2 Hexadezimal-Ziffern = 1 Byte<br />

• 2 n Bytes: Word<br />

Bit 7<br />

= MSB<br />

Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0<br />

= LSB<br />

• LSB = least significant bit<br />

• MSB = most significant bit<br />

25


Gleitkommadarstellung<br />

• auch: Fließkommadarstellung, engl. floating point<br />

• Beispiel Zehnersystem:<br />

0,002 = 0,2 ∙ 10 -2<br />

Mantisse<br />

Exponent<br />

• Übliche binäre Darstellung nach IEEE 754:<br />

Typ Größe Exponent Mantisse entspricht<br />

Dezimalstellen<br />

single<br />

(float)<br />

betragsmäßig<br />

größte Zahl<br />

32 bits 8 bits 23 bits 7-8 3,403·10 38<br />

double 64 bits 11 bits 52 bits 15-16 1,798·10 308<br />

26


Linke Hexadezimal-Ziffer<br />

ASCII-Code<br />

• Mit Hilfe des ASCII-Codes lässt sich mit einem Byte ein Buchstabe,<br />

eine Dezimalziffer, ein Sonderzeichen oder ein Steuercode (z. B.<br />

„Carriage Return“) darstellen:<br />

Rechte Hexadezimal-Ziffer<br />

…0 …1 …2 …3 …4 …5 …6 …7 …8 …9 …A …B …C …D …E …F<br />

0… NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI<br />

1… DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US<br />

2… SP ! " # $ % & ' ( ) * + , - . /<br />

3… 0 1 2 3 4 5 6 7 8 9 : ; < = > ?<br />

4… @ A B C D E F G H I J K L M N O<br />

5… P Q R S T U V W X Y Z [ \ ] ^ _<br />

6… ` a b c d e f g h i j k l m n o<br />

7… p q r s t u v w x y z { | } ~ DEL<br />

Quelle: Wikipedia<br />

27


Übungsaufgaben (I)<br />

1. Rechne folgende Dezimalzahlen in vorzeichenbehaftete<br />

Dualzahlen (8 Bits) und Hexadezimalzahlen (2 Stellen) um:<br />

a) 12 b) -17 c) 65 d) 77 e) 130 (geht das?)<br />

2. Rechne folgende Dual- bzw. Hexadezimalzahlen in Dezimalzahlen<br />

um. Nimm einmal an, dass es sich um vorzeichenlose Zahlen<br />

handelt und einmal, dass es sich um vorzeichenbehaftete Zahlen<br />

(8 Bits) handelt:<br />

a) 01010100 2 b) 4D 16 c) 11111110 2 d) F0 16<br />

3. Führe folgende Rechnungen unter Annahme eines Rechenwerkes<br />

mit n = 8 Bits durch. Gib das Ergebnis hexadezimal und den Inhalt<br />

des C- und des V-Bits nach der Rechnung an.<br />

a) A3 16 + 2B 16 b) 08 16 + FE 16 c) AE 16 – 52 16 d) 65 16 – C1 16<br />

28


Übungsaufgaben (II)<br />

4. Gib den mit 16 Bits üblicherweise darstellbaren Zahlenbereich (a)<br />

für vorzeichenbehaftete Zahlen (Zweierkomplement) und (b) für<br />

vorzeichenlose Zahlen an.<br />

5. Stelle für vorzeichenbehaftete Zahlen mit 16 Bits hexadezimal dar:<br />

a) die vom Betrag größte negative Zahl<br />

b) -1<br />

c) +1<br />

d) die größte positive Zahl<br />

6. Stelle die Zeichenkette „129“ im ASCII-Code dar und gib das<br />

Ergebnis als Folge von Hexadezimalzahlen an.<br />

29


Aufbau eines Rechnersystems<br />

30


Prinzipieller Aufbau eines Rechnersystems<br />

Mikrocontroller<br />

CPU<br />

(Mikroprozessor)<br />

Uhr<br />

Speicher<br />

…<br />

Digitale Ein-<br />

/Ausgänge<br />

A/D-<br />

Wandler<br />

Serielle<br />

Schnittstelle<br />

…<br />

Speicher<br />

31


Speicher (I)<br />

• Beispiel: Speicher der Organisation 64 ki x 8<br />

Adresse Inhalt<br />

0000 37<br />

0001 2A<br />

0002 5B<br />

0003 00<br />

0004 91<br />

0005 30<br />

0006 7F<br />

0007 00<br />

0008 01<br />

0009 3B<br />

000A 59<br />

…<br />

FFFF 3A<br />

…<br />

A15<br />

A2<br />

A1<br />

Speicher<br />

64 ki x 8<br />

D7<br />

D2<br />

D1<br />

D0<br />

…<br />

32


Speicher<br />

Speicher (II)<br />

RAM<br />

• Schreiben und Lesen<br />

• flüchtig (bei Abschalten<br />

Versorgungsspannung)<br />

ROM<br />

• Schreiben<br />

eingeschränkt<br />

• nicht flüchtig<br />

Statisches RAM<br />

(SRAM)<br />

Dynamisches RAM<br />

(DRAM)<br />

(Masken-<br />

programmiertes)<br />

ROM<br />

EEPROM<br />

Flash-EEPROM<br />

33


Quelle: Schmitt: Mikrocomputertechnik<br />

Prinzipieller Aufbau einer CPU<br />

34


Transistors per Chip<br />

10 9<br />

10 8<br />

10 7<br />

10 6<br />

10 5<br />

10 4<br />

10 3<br />

Geschichte der Mikroprozessoren:<br />

Beispiel „Allzweckprozessoren“ von Intel<br />

4004<br />

8080<br />

8086<br />

80486<br />

80286 80386<br />

Pentium<br />

1972 1976 1980 1984 1988 1992 1996 2000<br />

Date<br />

Pentium Pro<br />

Core i7<br />

2004 2008<br />

35


Klassifikation von Mikroprozessoren und<br />

„Verwandten“<br />

• Breite des Datenbusses/der Register/der ALU-Operationen<br />

– Z. B. 4, 8, 16, 32, 64 Bits<br />

• Rechnerarchitektur<br />

– Von-Neumann<br />

– Harvard<br />

• Anwendung<br />

– Allzweckprozessor (für PCs)<br />

– Mikrocontroller<br />

– Signalprozessor<br />

• Befehlssatz<br />

– RISC<br />

– CISC<br />

• Zahlenformate<br />

– Ganzzahlen<br />

– Gleitkomma, Fixkomma<br />

• …<br />

36


Atmel ATxmega128A1: Features (Auszug)<br />

• High-performance, Low-power 8/16-bit Atmel ® AVR ® XMEGA TM Microcontroller<br />

• Enhanced RISC, Harvard<br />

• Non-Volatile Program and Data Memories<br />

– 128K Bytes of In-System Self-Programmable Flash<br />

– 2 KB EEPROM<br />

– 8 KB Internal SRAM<br />

• External Bus Interface for up to 128M bit SDRAM<br />

• Peripheral Features<br />

– Eight 16-bit Timer/Counters<br />

– Eight USARTs<br />

– Two Eight-channel, 12-bit, 2 Msps Analog to Digital Converters<br />

– Two Two-channel, 12-bit, 1 Msps Digital to Analog Converters<br />

– …<br />

• Special Microcontroller Features<br />

– Advances Programming, Test and Debugging Interfaces<br />

• JTAG<br />

– …<br />

• Operating Voltage<br />

– 1.6 – 3.6V 37


Übungsaufgaben<br />

1. Ein Speicherbaustein wird mit den Adressen 0x0000 bis 0x1FFF<br />

angesprochen.<br />

a) Wie viele Adressleitungen besitzt der Baustein?<br />

b) Wie viele Speicherstellen besitzt der Baustein?<br />

39


Programmentwicklung<br />

40


ADD - Add without Carry<br />

Description:<br />

Beispiele für einen Befehl<br />

Adds two registers without the C flag and places the result in the destination register Rd.<br />

Operation:<br />

Rd ← Rd + Rr<br />

Syntax: Operands: Program Counter:<br />

ADD Rd,Rr 0 ≤ d ≤ 31, 0 ≤ r ≤ 31 PC ← PC + 1<br />

16-bit Opcode:<br />

Examples:<br />

add r1,r2 ; Add r2 to r1 (r1=r1+r2)<br />

add r28, r28 ; Add r28 to itself (r28=r28+r28)<br />

Words: 1 (2 bytes)<br />

Cycles: 1<br />

0000 11rd dddd rrrr<br />

41


Assembler (Mnemonics)<br />

Assembler<br />

Maschinencode-Modul<br />

(z. B. .o)<br />

Programmentwicklung<br />

Linker<br />

Maschinencode<br />

(z. B. .elf/.hex)<br />

Hochsprache (z. B. C)<br />

Compiler<br />

Maschinencode-Modul<br />

(z. B. .o)<br />

z. B. über JTAG in<br />

Flash<br />

Simulator Zielsystem<br />

Bibliotheken<br />

(Libraries)<br />

42


Atmel AVR XMEGA-A1 Xplained<br />

43


Beispiel für ein Assembler-Programm:<br />

Blinklicht<br />

ldi r16,0b11111111<br />

sts PORTE_DIR,r16 ;Port E (LEDs) als Ausgang<br />

eor r0,r0 ;r0 = 0<br />

again: com r0 ;r0 invertieren<br />

sts PORTE_OUT,r0 ;r0 an Port E ausgeben<br />

ldi r21,250 ;Verzögerung<br />

m2: ldi r20,250<br />

m1: dec r20<br />

brbc CPU_Z_bp,m1<br />

dec r21<br />

brbc CPU_Z_bp,m2<br />

rjmp again ;Unendlich wiederholen<br />

44


Speicher und Assembler-Befehle für den<br />

Datentransfer<br />

45


7 0<br />

R0<br />

R1<br />

R2<br />

…<br />

R13<br />

R14<br />

R15<br />

R16<br />

R17<br />

R18<br />

…<br />

Register<br />

R26 = XL<br />

R27 = XH<br />

R28 = YL<br />

R29 = YH<br />

R30 = ZL<br />

R31 = ZH<br />

X-Register<br />

Y-Register<br />

Z-Register<br />

46


Datenspeicher<br />

Byte Address 7 0<br />

0<br />

…<br />

FFF<br />

1000<br />

…<br />

17FF<br />

2000<br />

…<br />

3FFF<br />

4000<br />

…<br />

FFFFFF<br />

IO Registers<br />

(4 KB)<br />

EEPROM<br />

(2 KB)<br />

(reserved)<br />

Internal SRAM<br />

(8 KB)<br />

External Memory<br />

(0 to 16 MB)<br />

47


Befehle zum Datentransfer (Auswahl)<br />

Mnemonics Operands Description Operation Flags #Clocks Remarks<br />

MOV Rd, Rr Copy Register Rd ← Rr None 1<br />

LDI Rd, k8 Load Immediate Rd ← k8 None 1 only R16-R31<br />

MOVW Rd, Rr Copy Register Pair Rd+1:Rd ← Rr+1:Rr None 1<br />

LDS Rd, k16 Load Direct from<br />

data space<br />

Rd ← (k16) None 2 (1)(2)<br />

LD Rd, X Load Indirect Rd ← (X) None 1 (1)(2) also Y, Z<br />

STS k16, Rr Store Direct to Data<br />

Space<br />

(k16) ← Rd None 2 (1)<br />

ST X, Rr Store Indirect (X) ← Rr None 1 (1) also Y, Z<br />

PUSH Rr Push Register on (SP) ← Rr,<br />

None 1<br />

Stack<br />

SP ←SP-1<br />

(1)<br />

POP Rd Pop Register from SP ←SP+1, None 2<br />

Stack<br />

Rd ← (SP)<br />

(1)<br />

48


Übungsaufgaben<br />

1. Schreibe die Zahl 123 nach R18.<br />

2. Schreibe die Zahl 0x21 nach R7.<br />

3. Kopiere den Inhalt der SRAM-Adresse 0x2345 nach R0.<br />

4. Schreibe die Zahl 34521 nach Y.<br />

5. In Z stehe eine SRAM-Adresse. Lade den Inhalt dieser Adresse<br />

nach R18.<br />

6. Schreibe die Zahl 0 in die SRAM-Adresse 0x3AB4.<br />

49


IO-Ports<br />

50


Base<br />

Address<br />

Register zum Ansprechen der Ports im „Datenspeicher“<br />

Name Description<br />

0x0000 GPIO General Purpose IO<br />

Registers<br />

0x0010 VPORT 0 Virtual Port 0<br />

…<br />

0x0600 PORTA Port A<br />

0x0620 PORTB Port B<br />

0x0640 PORTC Port C<br />

0x0660 PORTD Port D<br />

0x0680 PORTE Port E<br />

0x06A0 PORTF Port F<br />

0x06E0 PORTH Port H<br />

0x0700 PORTJ Port J<br />

0x0720 PORTK Port K<br />

0x07C0 PORTQ Port Q<br />

0x07E0 PORTR Port R<br />

…<br />

Module<br />

Register im Modul<br />

52


Register der Ports (Auswahl) I<br />

53


Register der Ports (Auswahl) II<br />

+0x11…0x17<br />

54


Register der Ports (Auswahl) III<br />

• Bit 2:0 - ISC[2:0]: Input/Sense Configuration<br />

These bits set the input and sense configuration on pin n according to Table 13-5. The sense configuration<br />

decides how the pin can trigger port interrupts and events. When the input buffer is not disabled, the schmitt<br />

triggered input is sampled (synchronized) and can be read in the IN register.<br />

55


Schalter bzw. LEDs<br />

auf dem XMEGA-A1 Xplained<br />

• Mechanical button switches<br />

Eight mechanical button switches are connected to XMEGA<br />

PORTD(PD0:PD5) and PORTR(PR0:PR1). Internal pull-ups should<br />

be enabled to detect when the buttons are pushed, as they short the<br />

respective line to GND.<br />

– NOTE Buttons share the pins with the J3 header: Pushing the buttons<br />

potentially affects communication or other functionality on these pins.<br />

Pin<br />

330 �<br />

• LEDs<br />

Eight LEDs are connected to XMEGA PORTE. The LEDs are active<br />

low, and thus light up when the respective lines are output low by<br />

the XMEGA.<br />

56


Beispiel<br />

• Schalte LED0 aus, LED1 ein, LED2 aus usw.<br />

.equ PORTE_DIR = 0x0680<br />

.equ PORTE_OUT = 0x0684<br />

ldi r16,0b11111111<br />

sts PORTE_DIR,r16<br />

ldi r16,0b01010101<br />

sts PORTE_OUT,r16<br />

57


…<br />

Automatisch einbezogene Datei<br />

atxmega128a1def.inc<br />

.equ PORTA_DIR = 1536 // I/O Port Data Direction<br />

…<br />

.equ PORTA_OUT = 1540 // I/O Port Output<br />

…<br />

.equ PORTA_IN = 1544 // I/O Port Input<br />

.equ PORTA_INTCTRL = 1545 // Interrupt Control Register<br />

.equ PORTA_INT0MASK = 1546 // Port Interrupt 0 Mask<br />

.equ PORTA_INT1MASK = 1547 // Port Interrupt 1 Mask<br />

.equ PORTA_INTFLAGS = 1548 // Interrupt Flag Register<br />

.equ PORTA_PIN0CTRL = 1552 // Pin 0 Control Register<br />

.equ PORTA_PIN1CTRL = 1553 // Pin 1 Control Register<br />

.equ PORTA_PIN2CTRL = 1554 // Pin 2 Control Register<br />

.equ PORTA_PIN3CTRL = 1555 // Pin 3 Control Register<br />

.equ PORTA_PIN4CTRL = 1556 // Pin 4 Control Register<br />

.equ PORTA_PIN5CTRL = 1557 // Pin 5 Control Register<br />

.equ PORTA_PIN6CTRL = 1558 // Pin 6 Control Register<br />

.equ PORTA_PIN7CTRL = 1559 // Pin 7 Control Register<br />

.equ PORTB_DIR = 1568 // I/O Port Data Direction<br />

…<br />

58


Arithmetische, logische und Bit-Befehle<br />

59


Mnemo-<br />

nics<br />

Arithmetische und logische Befehle (Auswahl)<br />

Operands Description Operation Flags #<br />

Clocks<br />

Remarks<br />

ADD Rd, Rr Add without Carry Rd ← Rd + Rr Z,C,N,V,S,H 1<br />

ADC Rd, Rr Add with Carry Rd ← Rd + Rr + C Z,C,N,V,S,H 1<br />

SUB Rd, Rr Subtract without Carry Rd ← Rd - Rr Z,C,N,V,S,H 1<br />

SUBI Rd, K Subtract Immediate Rd ← Rd - K Z,C,N,V,S,H 1 only R16-R31<br />

AND Rd, Rr Logical AND Rd ← Rd AND Rr Z,N,V,S 1<br />

ANDI Rd, K Logical AND with<br />

Immediate<br />

Rd ← Rd AND K Z,N,V,S 1 only R16-R31<br />

OR Rd, Rr Logical OR Rd ← Rd OR Rr Z,N,V,S 1<br />

ORI Rd, K Logical OR with<br />

Immediate<br />

Rd ← Rd OR K Z,N,V,S 1 only R16-R31<br />

EOR RD, Rr Exclusive OR Rd ← Rd XOR Rr Z,N,V,S<br />

COM Rd One’s Complement Rd ← $FF - Rd Z,C,N,V,S 1<br />

NEG Rd Two’s Complement Rd ← $00 - Rd Z,C,N,V,S,H 1<br />

INC Rd Increment Rd ← Rd + 1 Z,N,V,S 1<br />

DEC Rd Decrement Rd ← Rd - 1 Z,N,V,S 1<br />

60


Mnemo-<br />

nics<br />

Bit- und Bit-Test-Befehle (Auswahl)<br />

Operands Description Operation Flags #<br />

Clocks<br />

LSL Rd Logical Shift Left Rd(n+1) ← Rd(n),<br />

Rd(0) ← 0,<br />

C ← Rd(7)<br />

LSR Rd Logical Shift<br />

Right<br />

ROL Rd Rotate Left<br />

Through Carry<br />

ROR Rd Rotate Right<br />

Through Carry<br />

Rd(n) ← Rd(n+1),<br />

Rd(7) ← 0,<br />

C ← Rd(0)<br />

Rd(0) ← C,<br />

Rd(n+1) ← Rd(n),<br />

C ← Rd(7)<br />

Rd(7) ← C,<br />

Rd(n) ←Rd(n+1),<br />

C ←Rd(0)<br />

Z,C,N,V,H 1<br />

Z,C,N,V 1<br />

Z,C,N,V,H 1<br />

Z,C,N,V 1<br />

BSET s Flag Set SREG(s) ← 1 SREG(s) 1<br />

BCLR S Flag Clear SREG(s) ← 0 SREG(s) 1<br />

BST Rr, b Bit Store from<br />

Register to T<br />

T ← Rr(b) T 1<br />

BLD Rd, b Bit load from T<br />

to Register<br />

Rd(b) ← T None 1<br />

Remarks<br />

61


Status-Register SREG im Modul CPU<br />

The Status Register (SREG) contains information about the result of the most recently<br />

executed arithmetic or logic instruction.<br />

• Bit 7 – I: Global Interrupt Enable<br />

• Bit 6 – T: Bit Copy Storage<br />

A bit from a register in the Register File can be copied into T by the BST instruction,<br />

and a bit in T can be copied into a bit in a register in the Register File by the BLD<br />

instruction.<br />

• Bit 3 – V: Two’s Complement Overflow Flag<br />

• Bit 2 – N: Negative Flag<br />

The Negative Flag (N) indicates a negative result in an arithmetic or logic operation.<br />

• Bit 1 – Z: Zero Flag<br />

The Zero Flag (Z) indicates a zero result in an arithmetic or logic operation.<br />

• Bit 0 – C: Carry Flag 62


Manipulation von einzelnen Bits mit Masken<br />

• Mit einer ODER-Verknüpfung lassen sich gezielt Bits setzen.<br />

Beispiel: ori r0,0b00000101 setzt Bits 0 und 2.<br />

• Mit einer UND-Verknüpfung lassen sich gezielt Bits löschen.<br />

Beispiel: andi r0,0b01111111 löscht Bit 7.<br />

63


Manipulation von einzelnen Bits mit Masken:<br />

Beispiel<br />

• Konfiguriere einen Pull-up-Widerstand für SW0 (Bit 0 von Port D,<br />

kurz PD0). (Die sonstige Konfiguration soll erhalten bleiben.)<br />

lds r16,PORTD_PIN0CTRL<br />

ori r16,0b00011000 ;OPC = 011 (pull up)<br />

andi r16,0b11011111<br />

sts PORTD_PIN0CTRL,r16 ;PD0: pull up<br />

64


Arithmetik mit 16-Bit-Zahlen<br />

• Wie speichert man die Zahl 14975 = 3A7F H ab Adresse 0x2345?<br />

• Speichern in 2-Byte-Zellen:<br />

– Big Endian: höherwertiges Byte wird an niedrigerer Adresse/„zuerst“<br />

gespeichert („Motorola-Format“, z. B. PowerPC, Java)<br />

– Little Endian: niederwertiges Byte wird an niedrigerer Adresse/„zuerst“<br />

gespeichert („Intel-Format“, z. B. x86, Atmel)<br />

• Beispiel: 3A7F H gespeichert im „LittleEndian“-Format:<br />

2344 …<br />

2345 7F H<br />

2346 3A H<br />

2347 …<br />

65


Arithmetik mit 16-Bit-Zahlen: Beispiel<br />

• Addiere zu der 16-Bit-Zahlen (little endian) bei 0x35BA/0x35BB die<br />

Zahl 0xCAFE.<br />

lds r16,0x35BA<br />

ldi r17,0xFE<br />

add r16,r17<br />

sts 0x35BA,r16<br />

lds r16,0x35BB<br />

ldi r17,0xCA<br />

adc r16,r17<br />

sts 0x35BB,r16<br />

66


1. Subtrahiere 17 von R9.<br />

2. Setze das Bit 6 in R12.<br />

3. Lösche Bits 0 und 7 in R2.<br />

4. Addiere 25 zu R0.<br />

5. Lösche R19.<br />

6. Setze alle Bits in R31.<br />

Übungsaufgaben<br />

7. Subtrahiere die Zahl 76 vom Inhalt der SRAM-Speicherstelle<br />

0x2937.<br />

8. In den Speicherstellen 0x3654/0x3655 stehen zwei Bytes einer 16-<br />

Bit-Zahl (little endian). Addiere 23 zu dieser Zahl.<br />

9. Teile den Inhalt von R23 durch 4.<br />

67


Assembler-Befehle für Sprünge<br />

68


Mnemo-<br />

nics<br />

Sprungbefehle<br />

Operands Description Operation Flags #<br />

Clocks<br />

RJMP k8 Relative Jump PC ← PC + k8 + 1 None 2<br />

JMP k16 Jump PC ← k16 None 2<br />

CALL k16 Call Subroutine PC ← k16 None 3 / 4 (1)<br />

RET Subroutine Return PC ← STACK None 4 / 5 (1)<br />

RETI Interrupt Return PC ← STACK None 4 / 5 (1)<br />

CP Rd, Rr Compare Rd – R r Z,C,N,V,S,H 1<br />

CPI Rd, k8 Compare with Immediate Rd – k8 Z,C,N,V,S,H 1<br />

SBRC Rr, b Skip if Bit in Register<br />

Cleared<br />

if (Rr(b) = 0) then<br />

PC ← PC + 2 or 3<br />

SBRS Rr, b Skip if Bit in Register Set if (Rr(b) = 1) then<br />

PC ← PC + 2 or 3<br />

BRBS s, k8 Branch if Status Flag Set if (SREG(s) = 1) then<br />

PC ← PC + k8 + 1<br />

BRBC s, k8 Branch if Status Flag<br />

Cleared<br />

if (SREG(s) = 0) then<br />

PC ← PC + k8 + 1<br />

None 1 / 2 / 3<br />

None 1 / 2 / 3<br />

None 1 / 2<br />

None 1 / 2<br />

69


Vergleiche: Beispiel<br />

• Aufgabe: Ist r16 > 100, so setze r16 = 100.<br />

• Idee: r16 > 100 ist äquivalent zu r16 � 101. Berechne r16 – 101. Ist<br />

das Resultat nicht negativ (also das Flag N = 0), so war r16 � 101<br />

oder r16 > 100.<br />

• Lösung:<br />

label: …<br />

cpi r16,101<br />

brbs 2,label ;2: N-Flag<br />

ldi r16,100<br />

• Statt brbs 2,label akzeptiert der Assembler auch die Abkürzung<br />

brmi label („Branch if Minus“).<br />

70


Schleifen: Beispiel Verzögerungsschleife für<br />

Blinklicht<br />

ldi r16,0b11111111<br />

sts PORTE_DIR,r16 ;Port E (LEDs) als Ausgang<br />

eor r0,r0 ;r0 = 0<br />

again: com r0 ;r0 invertieren<br />

sts PORTE_OUT,r0 ;r0 an Port E ausgeben<br />

ldi r21,250 ;Verzögerung<br />

m2: ldi r20,250<br />

m1: dec r20<br />

brbc CPU_Z_bp,m1 ;(= brne)<br />

dec r21<br />

brbc CPU_Z_bp,m2<br />

rjmp again ;Unendlich wiederholen<br />

71


Wie lange verzögert die Schleife?<br />

ldi r20,250 ; 1 x 1 clocks<br />

m: dec r20 ; 250 x 1 clocks<br />

brbc CPU_Z_bp,m ; 249 x 2 + 1 x 1 clocks<br />

• Bei der Taktfrequenz von 2 MHz ergibt sich als Verzögerung:<br />

750 clocks / 2 MHz = 375 �s<br />

72


Übungsaufgaben (I)<br />

1. Schreibe in Assembler: Ist r16 < 25, so setze r16 = 25.<br />

73


Übungsaufgaben (II)<br />

2. Betrachte folgende Verzögerungsschleife:<br />

ldi r16,0<br />

m: cpi r16,a<br />

brbs CPU_Z_bp,end<br />

end: …<br />

inc r16<br />

rjmp m<br />

a ist durch eine Zahl zu ersetzen. Die Taktfrequenz betrage 2 MHz.<br />

a) Wie groß muss a gewählt werden, damit eine Verzögerung von<br />

möglichst genau 100 µs erreicht wird?<br />

b) Wie groß ist die erzielte Verzögerung dann genau?<br />

74


Stack und Unterprogramme<br />

75


Stack<br />

• Der Stack („Stapelspeicher“) ist ein Mechanismus zur Speicherung<br />

von Daten nach dem „LIFO“-Prinzip (last in, first out).<br />

• Realisierung bei uns:<br />

– Stackpointer (SP) zeigt auf eine Adresse im Datenspeicher.<br />

– Anweisung push Rr legt Rr auf der Adresse des SP ab und erniedrigt<br />

SP.<br />

– Anweisung pop Rd erhöht SP und speichert Wert an Adresse des SP in<br />

Rd ab.<br />

– SP ist standardmäßig auf höchste Adresse im internen SRAM<br />

(INTERNAL_SRAM_END) gesetzt.<br />

Adresse Inhalt<br />

SP → 3FFF xx<br />

3FFE xx<br />

3FFD xx<br />

76


Unterprogramme<br />

• Motivation: Mehrfaches Wiederverwerten eines kleinen Programmstücks<br />

(„Unterprogramm“, englisch „subroutine“) in einem Programm<br />

Beispiel:<br />

delay: …<br />

ret<br />

…<br />

call delay<br />

…<br />

call delay<br />

…<br />

Hauptprogramm<br />

Unterprogramm<br />

• call legt die Rücksprungadresse auf den Stack und springt dann zu der<br />

angegebenen Adresse.<br />

• ret holt die Rücksprungadresse vom Stack und springt dort hin zurück.<br />

77


Unterprogramme: Besonderheiten<br />

• Wenn Unterprogramme Register verwenden, „zerstören“ sie vom<br />

Hauptprogramm in diesen Registern gespeicherte Werte.<br />

– Abhilfe (1): <strong>Für</strong> das gesamte Programm wird per Konvention bestimmt,<br />

welche Register in einem Unterprogrammaufruf „zerstört“ werden<br />

dürfen. (Das Hauptprogramm sichert solche Register ggf. vor dem<br />

Unterprogramm-Aufruf.)<br />

– Abhilfe (2): Das Unterprogramm sichert verwendete Register z. B. durch<br />

Umschalten auf eine zweite Registerbank oder<br />

Abspeichern/Zurückholen von Registern (push/pop).<br />

• Assembler-Unterprogramme haben keinen Mechanismus zur<br />

Übergabe von Parametern/Rückgabe von Werten (anders als C).<br />

– Abhilfe: Übergabe in Registern, auf dem Stack oder im Speicher<br />

(Konvention).<br />

78


Übungsaufgabe<br />

1. Schreibe ein Unterprogramm, das mit Hilfe von<br />

Verzögerungsschleifen eine Verzögerung von möglichst genau a<br />

mal 100 �s erzeugt. Der Parameter a werde dem Unterprogramm<br />

in Register R0 übergeben. Weitere Register sollen durch das<br />

Unterprogramm nicht verändert werden. Annahme: f clk = 2 MHz.<br />

79


Interrupts<br />

80


Interrupts: Überblick<br />

• Bewirken bei Auftreten eines „Ereignisses“ (z. B. steigende Flanke<br />

an einem Port-Pin) eine Unterbrechung des laufenden Programms<br />

und einen „internen call“ zu einer vorgegebenen Adresse im<br />

Programmspeicher.<br />

• Rückkehr von einer solchen Interrupt-Service-Routine durch reti<br />

(statt ret).<br />

• Interrupts müssen vor Verwendung freigegeben („eingeschaltet“)<br />

werden.<br />

• Interrupt-Service-Routinen dürfen keine Register/Flags etc.<br />

verändern, die im Hauptprogramm verwendet werden. (Ggf. „retten“,<br />

z. B. mit push)<br />

81


Interrupts: Prioritäten („Level“)<br />

• Interrupts können verschiedene Prioritäten haben, bei uns: HIGH,<br />

MEDIUM, LOW.<br />

• Ein Interrupt höherer Priorität kann einen Interrupt niedrigerer<br />

Priorität unterbrechen.<br />

82


Interrupt-Register in Port-Modulen (I)<br />

83


Interrupt-Register in Port-Modulen (II)<br />

84


Aktivieren von Interrupts, Level (I)<br />

• Bei der jeweiligen Interrupt-Quelle (z. B. PORTD_INTCTRL) wird der<br />

Interrupt aktiviert und sein Level festgelegt:<br />

Interrupt level<br />

configuration<br />

Group configuration Description<br />

00 OFF Interrupt disabled.<br />

01 LO Low level interrupt<br />

10 MED Medium level interrupt.<br />

11 HI High level interrupt.<br />

• Global werden Interrupts durch Setzen des I-Bits im SREG aktiviert,<br />

kurz: sei (oder cei zum Deaktivieren).<br />

85


Aktivieren von Interrupts (II)<br />

• Der jeweilige Level muss zusätzlich noch im Interrupt-Controller<br />

PMIC aktiviert werden (Register CTRL im Modul PMIC):<br />

CTRL - PMIC Control Register<br />

• Bit 2 - HILVLEN: High Level Interrupt Enable<br />

When this bit is set all high level interrupts are enabled. If this bit is cleared, high level<br />

interrupt requests will be ignored.<br />

• Bit 1 - MEDLVLEN: Medium Level Interrupt Enable<br />

When this bit is set all medium level interrupts are enabled. If this bit is cleared, medium<br />

level interrupt requests will be ignored.<br />

• Bit 0 - LOLVLEN: Low Level Interrupt Enable<br />

When this bit is set all low level interrupts are enabled. If this bit is cleared, low level<br />

interruptrequests will be ignored.<br />

86


.org 0<br />

Beispiel: Loslassen von SW0 toggelt LEDs<br />

jmp start<br />

.org PORTD_INT0_vect<br />

jmp isr<br />

.org INT_VECTORS_SIZE<br />

start: ldi r16,0xff<br />

sts PORTE_DIR,r16 ;Port E als Ausgang<br />

ldi r16,0<br />

sts PORTD_DIR,r16 ;Port D als Eingang<br />

ldi r16,PORT_OPC_PULLUP_gc | PORT_ISC_RISING_gc;<br />

sts PORTD_PIN0CTRL,r16 ;PD0: Pull up, erkenne Rising Edge<br />

ldi r16,0b00000001<br />

sts PORTD_INT0MASK,r16 ;PD0 löst Interrupt 0 aus<br />

ldi r16,PORT_INT0LVL_MED_gc<br />

sts PORTD_INTCTRL,r16 ;Port D Interrupt 0: Medium Level<br />

ldi r16,PMIC_MEDLVLEN_bm<br />

sts PMIC_CTRL,r16 ;Medium-Level-Interrupts ein<br />

sei ;Interrupts global ein<br />

loop: rjmp loop<br />

isr: lds r0,PORTE_OUT ;Port E (LEDs) toggeln<br />

com r0<br />

sts PORTE_OUT,r0<br />

reti<br />

87


Interrupts: Besonderheiten<br />

• Interrupts unterbrechen das laufende Programm an einer beliebigen<br />

Stelle, daher müssen in der ISR veränderte Register, SREG usw.<br />

„gerettet“ werden.<br />

• ISRs unterbrechen das laufende Programm und sollten daher i. a.<br />

„schnell“ abgearbeitet werden (keine langwierigen Berechnungen,<br />

keine Warteschleife).<br />

88


Übungsaufgabe<br />

1. Schreibe ein Programm: Ein Hauptprogramm soll mit einer<br />

Warteschleife ein Blinklicht wahrnehmbarer Frequenz realisieren.<br />

Per Interrupt soll die Anzahl der durch SW0 verursachten<br />

steigenden Flanken in R31 gezählt werden. (Tipp: SREG retten!)<br />

89


Programmieren in C<br />

90


Zahlentypen<br />

Ganzzahltyp bei avr-gcc: Portabele Definition in<br />

stdint.h:<br />

8 Bits mit Vorzeichen<br />

8 Bits ohne Vorzeichen<br />

signed char int8_t<br />

unsigned char uint8_t<br />

16 Bits mit Vorzeichen int int16_t<br />

16 Bits ohne Vorzeichen unsigned int uint16_t<br />

32 Bits mit Vorzeichen long int32_t<br />

32 Bits ohne Vorzeichen unsigned long uint32_t<br />

91


Definitionen für Ports in avr/io.h<br />

typedef struct PORT_struct<br />

{<br />

register8_t DIR;<br />

register8_t DIRSET;<br />

register8_t DIRCLR;<br />

register8_t DIRTGL;<br />

register8_t OUT;<br />

register8_t OUTSET;<br />

register8_t OUTCLR;<br />

register8_t OUTTGL;<br />

register8_t IN;<br />

register8_t INTCTRL;<br />

register8_t INT0MASK;<br />

register8_t INT1MASK;<br />

register8_t INTFLAGS;<br />

register8_t reserved_0x0D;<br />

register8_t reserved_0x0E;<br />

register8_t reserved_0x0F;<br />

register8_t PIN0CTRL;<br />

…<br />

register8_t PIN7CTRL;<br />

} PORT_t;<br />

typedef enum PORT_INT0LVL_enum<br />

{<br />

PORT_INT0LVL_OFF_gc = (0x00


Beispiel: Loslassen von SW0 toggelt LEDs<br />

#include <br />

#include <br />

int main(void)<br />

{<br />

}<br />

PORTE.DIR = 0xff; // Port E als Ausgang<br />

PORTD.DIR = 0x00; // Port D als Eingang<br />

PORTD.PIN0CTRL =<br />

PORT_OPC_PULLUP_gc | PORT_ISC_RISING_gc;// PD0: Pull up, erkenne Rising Edge<br />

PORTD.INT0MASK = 0x01; // PD0 löst Interrupt 0 aus.<br />

PORTD_INTCTRL = PORT_INT0LVL_MED_gc; // Port D Interrupt 0: Medium Level<br />

PMIC.CTRL |= PMIC_MEDLVLEN_bm; // Medium-Level-Interrupts ein<br />

sei(); // Interrupts global ein<br />

for(;;) {<br />

}<br />

ISR(PORTD_INT0_vect)<br />

{<br />

}<br />

PORTE.OUT = ~PORTE.OUT; //Port E (LEDs) toggeln<br />

93


Energiesparen<br />

94


Energiesparen (I)<br />

• Durch „Schlafenlegen“ der CPU (und ggf. anderer Komponenten des<br />

Mikrocontrollers) lässt sich Energie sparen.<br />

• In dem einfachsten Modus „Idle“ wird nur die CPU angehalten. Durch<br />

beliebige Interrupts wird sie wieder „aufgeweckt“.<br />

• Realisierung in Assembler: Konfiguration des gewünschten Modus in einem<br />

Register im Modul SLEEP, dann Assembler-Anweisung sleep.<br />

• Realisierung in C:<br />

#include <br />

…<br />

for(;;) {<br />

// Nichts zu tun…<br />

sleep_mode();<br />

}<br />

95


Energiesparen (II)<br />

• Weitere Maßnahme zum Energiesparen: Unbenutzte Port-Eingänge<br />

mit Pull-Ups beschalten.<br />

96


Timer/Counter<br />

97


Einführung<br />

• Der ATxmega128A1 verfügt über insgesamt 8 Timer/Counter-(T/C)-<br />

Einheiten.<br />

• Grundfunktion: Eine Timer/Counter-Einheit zählt Taktimpulse oder<br />

andere „Events“ im 16-Bit-Register CNT. Erreicht der Zähler einen<br />

vorgegebenen Wert („TOP“, gespeichert im 16-Bit-Register PER), so<br />

wird er auf 0 („BOTTOM“) zurückgesetzt und ein Interrupt ausgelöst.<br />

MAX= FFFF<br />

TOP = PER<br />

BOTTOM = 0<br />

98


Clock<br />

Prescaler<br />

(Vorteiler)<br />

Events<br />

Funktion der Timer<br />

0000<br />

CNTH CNTL<br />

=<br />

PERH PERL<br />

Interrupt<br />

99


Register der Timer (Auswahl) (I)<br />

100


Register der Timer (Auswahl) (II)<br />

INTCTRLA - Interrupt Enable Register A<br />

• Bit 7:4 – Reserved<br />

• Bit 3:2 - ERRINTLVL[1:0]:Timer Error Interrupt Level<br />

These bits enable the Timer Error Interrupt and select the interrupt level.<br />

• Bit 1:0 - OVFINTLVL[1:0]:Timer Overflow/Underflow Interrupt Level<br />

These bits enable the Timer Overflow/Underflow Interrupt and select the interrupt<br />

level.<br />

101


Register der Timer (Auswahl) (III)<br />

INTFLAGS – Interrupt Flag Register<br />

• Bit 7:4 - CCxIF: Compare or Capture Channel x Interrupt Flag<br />

The Compare or Capture Interrupt Flag (CCxIF) is set on a compare match or on<br />

an input capture event on the corresponding CC channel.<br />

The flag will be cleared when the CCx register is read. Executing the Interrupt<br />

Vector will in this mode of operation not clear the flag.<br />

The flag can also be cleared by writing a one to its bit location.<br />

• Bit 3:2 - Reserved<br />

• Bit 1 - ERRIF: Error Interrupt Flag<br />

• Bit 0 - OVFIF: Overflow/Underflow Interrupt Flag<br />

The OVFIF is set either on a TOP (overflow) or BOTTOM (underflow) condition<br />

depending on the WGMODE setting. The OVFIF is automatically cleared when<br />

the corresponding interrupt vector is executed. The flag can also be cleared by<br />

writing a one to its bit location.<br />

102


Register der Timer (Auswahl) – (IV)<br />

CNTH/CNTL - Counter Register<br />

• The CNTH and CNTL register pair represents the 16-bit value CNT. CNT<br />

contains the 16-bit counter value in the Timer/Counter. The CPU and DMA write<br />

access has priority over count, clear, or reload of the counter.<br />

PERH/PERL - Period Register<br />

• The PERH and PERL register pair represents the 16-bit value PER. PER<br />

contains the 16-bit TOP value in the Timer/Counter.<br />

Hinweis: CNTH/CNTL bzw. PERH/PERL sind in C zusammengefasst als 16-Bit-Werte<br />

CNT bzw. PER ansprechbar.<br />

103


Basisadressen und Interuptvektoren der 8<br />

Timer<br />

Symbolische<br />

Basisadresse<br />

Symbolischer Interruptvektor<br />

(Overflow/Underflow Interrupt)<br />

TCC0 TCC0_OVF_vect<br />

TCC1 TCC1_OVF_vect<br />

TCD0 TCD0_OVF_vect<br />

TCD1 TCD1_OVF_vect<br />

TCE0 TCE0_OVF_vect<br />

TCE1 TCE1_OVF_vect<br />

TCF0 TCF0_OVF_vect<br />

TCF1 TCF1_OVF_vect<br />

104


Beispiel: Blinklicht (I)<br />

• Aufgabe: Interruptgesteuert soll jede Sekunde LED4 umgeschaltet<br />

werden (also mit 0,5 Hz blinken).<br />

• Mit dem Prescaler 1/1024 und f clk = 2 MHz ergibt sich:<br />

PER = t ∙ f clk / Prescaler – 1 = 1 s ∙ 2 MHz / 1024 – 1 = 1952,125 �<br />

1952<br />

105


#include <br />

#include <br />

#include <br />

int main(void)<br />

{<br />

}<br />

PORTE.DIR = 0xff;<br />

TCC0.CTRLA = TC_CLKSEL_DIV1024_gc;<br />

Beispiel: Blinklicht (II)<br />

TCC0.INTCTRLA = TC_OVFINTLVL_MED_gc;<br />

TCC0.PER = 1952; // 1 Sekunde<br />

PMIC.CTRL = PMIC_MEDLVLEN_bm;<br />

sei();<br />

for(;;) {<br />

}<br />

sleep_mode();<br />

ISR(TCC0_OVF_vect)<br />

{<br />

}<br />

PORTE.OUTTGL = 1


Compare- und Capture-Modus<br />

• Indem automatisch bei Erreichen bestimmter Werte von CNT ein<br />

Port-Pin gesetzt bzw. gelöscht wird, lassen sich PWM-Signale<br />

erzeugen (Compare Mode/Waveform Generation).<br />

• Indem bei bestimmten „Events“ (insbesondere z. B.<br />

steigende/fallende Flanken an einem Port-Pin) der aktuelle Wert von<br />

CNT „abfotografiert“ wird, lassen sich sehr genau Zeiten (z. B.<br />

Frequenz, Impulsdauer) messen (Capture Mode).<br />

• � Datenblatt<br />

107


Übungsaufgaben (I)<br />

1. Berechne PER für eine Zeit von t = 50 ms für f clk = 32 MHz.<br />

Bestimme dafür den Vorteiler, der zu der „genauesten“ Zeit führt.<br />

Welche Zeit wird tatsächlich erreicht?<br />

2. Schreibe eine Funktion delay(uint16_t x), die x Millisekunden<br />

verzögert. Aus Energiespargründen soll delay() möglichst viel<br />

„schlafen“ und mit Hilfe eines Timers aufgeweckt werden.<br />

Annahme: f clk = 2 MHz.<br />

108


Übungsaufgaben (II)<br />

3. Schreibe ein Modul in C (f clk = 2 MHz), um die Helligkeit der LED4<br />

auf dem XMEGA Xplained zu steuern. Die Steuerung soll mit Hilfe<br />

eines PWM-Signals (Periodendauer 10 ms) geschehen. Das Modul<br />

soll aus den Dateien led43.c und led43.h bestehen und die<br />

Funktionen initLed43() und setLed43(uint8_t x) anbieten.<br />

setLed43() setzt das Tastverhältnis des PWM-Signals (und damit<br />

die „Helligkeit“) auf x %.<br />

4. Schreibe ein Programm in C (f clk = 2 MHz), welches nach einem<br />

Reset die Dauer von zehn 1-Impulsen (maximale Dauer jeweils 1<br />

Sekunde) von einer externen Quelle möglichst genau erfasst und in<br />

der Einheit μs in einem Array speichert. An welchen Pin ist das<br />

externe Signal anzulegen?<br />

109


Aspekte des Software Engineerings<br />

110


• Definition:<br />

Race Condition<br />

Eine Race Condition (Wettlaufsituation) ist in der Programmierung<br />

eine Konstellation, bei der das Ergebnis einer Operation vom<br />

zeitlichen Verhalten bestimmter Einzeloperationen abhängt.<br />

• Unbeabsichtigte Wettlaufsituationen sind ein häufiger Grund für<br />

schwer auffindbare Programmfehler.<br />

Quelle: Wikipedia<br />

111


volatile int x;<br />

int main(void)<br />

{<br />

}<br />

unsigned int bad = 0;<br />

x = 1;<br />

initInterrupts();<br />

for(;;) {<br />

}<br />

Race-Condition: Beispiel<br />

if (x != 1 && x != -1)<br />

ISR(TCC0_OVF_vect)<br />

{<br />

}<br />

x = -x;<br />

bad++;<br />

112


Schlüsselwort volatile<br />

• Das Schlüsselwort volatile im vorherigen Beispiel teilt dem<br />

Compiler mit, dass sich die Variable x „magisch“ (d. h. außerhalb<br />

des normalen Programmflusses in main()) verändern kann.<br />

• Ohne volatile könnte der Compiler annehmen, dass ja x = 1<br />

gesetzt wurde und dies bei der if-Abfrage immer noch gültig sein<br />

müsste, so dass die if-Abfrage wegoptimiert werden kann.<br />

113


Race-Condition: Abhilfe für Beispiel<br />

• Temporäres Abschalten der Interrupts: cli() oder portabel durch<br />

ATOMIC_BLOCK():<br />

#include <br />

..<br />

main()<br />

{<br />

}<br />

…<br />

ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br />

}<br />

…<br />

if (x != 1 && x != -1)<br />

bad++;<br />

114


Modulare Programmierung (I)<br />

• Aufteilung eines Programms in Module (ähnlich Objekte).<br />

• Tipps:<br />

– 1 Modul = 2 Dateien (siehe nächste Folie)<br />

– Möglichst nur ganz wenige, klar definierte Funktionen als Schnittstelle<br />

zwischen den Modulen.<br />

– Globale Variablen vermeiden.<br />

– „Seiteneffekte“ von Modulen dokumentieren (z. B. Verwendung von<br />

Timer 0 in einem Modul).<br />

115


tastatur.h:<br />

tastatur.c:<br />

#include "tastatur.h"<br />

short tastWarteZeit;<br />

char tastLies() {<br />

…<br />

return c;<br />

}<br />

…<br />

Modulare Programmierung (II)<br />

extern short tastWarteZeit;<br />

extern char tastLies();<br />

display.h:<br />

extern void<br />

dispSchreib(char c);<br />

extern void<br />

dispZeilenwechsel();<br />

display.c:<br />

#include "display.h"<br />

void displaySchreib(char c) {<br />

…<br />

}<br />

void displayZeilenwechsel() {<br />

…<br />

}<br />

…<br />

116


Modulare Programmierung (III)<br />

main.c:<br />

#include "tastatur.h"<br />

#include "display.h"<br />

…<br />

main()<br />

{<br />

}<br />

…<br />

c = tastLies();<br />

…<br />

dispSchreib(c);<br />

…<br />

117


Software-Architekturen für Embedded<br />

Systems: Beispiel-Aufgabenstellung<br />

• Höhenmesser für ein Flugzeug:<br />

– Wenn ein neuer Wert von A/D-Wandler verfügbar ist, wird dieser in Fuß<br />

(1 Fuß = 0,3048 m) umgerechnet und auf einer Anzeige dargestellt.<br />

– Wird ein Taster für mindestens 3 Sekunden betätigt, so wird die aktuelle<br />

Höhe irgendwo abgespeichert.<br />

118


Software-Architekturen für Embedded<br />

Systems: Round Robin (I)<br />

• Keine Interrupts. In einer Hauptschleife werden nacheinander<br />

Ereignisse abgefragt und auf sie reagiert.<br />

• Beispiel:<br />

void main(void)<br />

{<br />

}<br />

while(1) {<br />

if („Taste gedrückt“) {<br />

}<br />

}<br />

// Kümmere Dich um Tastendruck…<br />

if („Neuer Wert vom A/D-Wandler verfügbar“) {<br />

}<br />

…<br />

// Rechne um und zeige an…<br />

119


Software-Architekturen für Embedded<br />

Systems: Round Robin (II)<br />

• Nachteil: Die Reaktionszeit auf ein Ereignis ist schlimmstenfalls so<br />

groß wie die Abarbeitung der restlichen Schleife maximal dauern<br />

kann.<br />

• Insbesondere kritisch, wenn es innerhalb der Hauptschleife weitere<br />

(Warte-)schleifen gibt.<br />

– Beispiel: „…Taster für mindestens 3 Sekunden betätigt…“<br />

…<br />

while(1) {<br />

if („Taste gedrückt“) {<br />

while („Taste gedrückt und 3 Sekunden noch nicht um“)<br />

;<br />

…<br />

if („Taste gedrückt“) {<br />

// Kümmere Dich um Tastendruck…<br />

}<br />

}<br />

if („Neuer Wert vom A/D-Wandler verfügbar“) {<br />

// Rechne um und zeige an…<br />

}<br />

} 120


Software-Architekturen für Embedded<br />

Systems: Round Robin mit Interrupts (I)<br />

• Bei externen Ereignissen werden Interrupt-Service-Routinen<br />

aufgerufen. Diese führen einfache Verarbeitungsschritte selbst aus<br />

oder setzen Variablen, auf die in der Hauptschleife reagiert wird.<br />

121


Software-Architekturen für Embedded<br />

Systems: Round Robin mit Interrupts (II)<br />

• Beispiel:<br />

volatile bool taste = 0;<br />

void tasteISR(void)<br />

{<br />

taste = 1;<br />

}<br />

void aduISR(void)<br />

{<br />

// Hole A/D-Wert von Wandler ab, rechne um und stelle dar<br />

}<br />

void main(void)<br />

{<br />

}<br />

while(1) {<br />

if (taste) {<br />

// Kümmere Dich um Tastendruck…<br />

taste = 0;<br />

}<br />

}<br />

…<br />

122


Nutzung eines (Real-Time) Operating<br />

Systems<br />

• Beispiel: FreeRTOS<br />

• Typische Funktionen:<br />

– unterbrechbare „Tasks“ mit einstellbaren Prioritäten für umfangreiche<br />

Berechnungen<br />

– Mechanismen zur Kommunikation zwischen Tasks und ISRs<br />

– „virtuelle“ Timer<br />

– umfangreiche Funktionen zur Ansteuerung von Hardware<br />

123


Serielle Schnittstelle RS-232<br />

124


• Stecker: D-Sub 9 (oder 25)<br />

Stecker<br />

• Verbindet ein DTE (Data Terminal Equipment, i. a. ein Computer)<br />

mit einem DCE (Data Communication Equipment, ursprünglich ein<br />

Modem)<br />

• Steckerbelegung:<br />

Quelle: Wikipedia<br />

Abkürzung Name Beschreibung<br />

Optional weitere Leitungen für Handshake<br />

Pin-Nr.<br />

9-pol.<br />

GND GND Datenmasse Pin 5 —<br />

TxD Transmit Data<br />

RxD Receive Data<br />

Leitung für<br />

gesendete Daten<br />

Leitung für den<br />

Empfang von Daten<br />

Pin 3 Out<br />

Pin 2 In<br />

Input/Output (vom<br />

DTE aus gesehen)<br />

125


Übertragung<br />

• Übertragung in Wörtern (meist 8 Bits, z. B. ein ASCII-Zeichen)<br />

• bitseriell<br />

• asynchron<br />

– Synchronisation auf Wortanfang durch ein Startbit (logisch 0)<br />

– Stoppbit nach Wortende (logisch 1)<br />

• Übliche Baudraten (= Kehrwert der Dauer eines Bits):<br />

300, 1200, 4800, 9600, 19200, 38400, 57600, 115200 Bits/s.<br />

• Logische 0: +3…+15 V, Logische 1: -3…-15 V<br />

• Zur Überprüfung der Übertragung kann ein zusätzliches Paritätsbit<br />

verwendet werden.<br />

126


Quelle: Wikipedia<br />

Übertragung: Beispiel<br />

127


Handshaking für Flow Control<br />

• Wird verwendet, um Sender temporär zu „stoppen“, falls der<br />

Empfänger die Daten nicht schnell genug verarbeiten kann (z. B.<br />

langsamer Drucker).<br />

• Hardware:<br />

2 zusätzliche Leitungen mit Bedeutung logisch 0 = bereit:<br />

– RTS („Request to Send“, DTE � DCE)<br />

– CTS („Clear to Send“, DCE � DTE)<br />

• Software:<br />

Einfügen der speziellen, „nicht-druckbaren“ ASCII-Zeichen XOFF<br />

(„transmission off“, ASCII-Code 19) und XON („transmission on“,<br />

ASCII-Code 17) in der Gegenrichtung.<br />

128


DATA - USART I/O Data Register<br />

Register USART (I)<br />

The USART Transmit Data Buffer Register and USART Receive Data Buffer<br />

Registers share the same I/O address referred to as USART Data Register (DATA).<br />

The Transmit Data Buffer Register (TXB) will be the destination for data written to the<br />

DATA Register location. Reading the DATA Register location will return the contents<br />

of the Receive Data Buffer Register (RXB).<br />

The transmit buffer can only be written when the DREIF Flag in the STATUS Register<br />

is set.<br />

When data is written to the transmit buffer, and the Transmitter is enabled, the<br />

Transmitter will load the data into the Transmit Shift Register when the Shift Register<br />

is empty. The data is then transmitted on the TxD pin.<br />

The receive buffer consists of a two level FIFO. The FIFO and the corresponding<br />

flags in the Status Register (STATUS) will change state whenever the receive buffer<br />

is accessed (read). Always read STATUS before DATA in order to get the correct 129<br />

flags.


STATUS - USART Status Register<br />

Register USART (II)<br />

• Bit 7 - RXCIF: USART Receive Complete Interrupt Flag<br />

This flag is set when there are unread data in the receive buffer and cleared<br />

when the receive buffer is empty (i.e., does not contain any unread data).<br />

• Bit 5 - DREIF: USART Data Register Empty Flag<br />

The DREIF indicates if the transmit buffer (DATA) is ready to receive new data.<br />

The flag is one when the transmit buffer is empty, and zero when the transmit<br />

buffer contains data to be transmitted that has not yet been moved into the Shift<br />

Register. DREIF is set after a reset to indicate that the Transmitter is ready.<br />

DREIF is cleared by writing DATA.<br />

• Bit 4 - FERR: Frame Error<br />

• Bit 3 - BUFOVF: Buffer Overflow<br />

• Bit 2 - PERR: Parity Error<br />

• Bit 1 - Reserved 130


CTRLB - USART Control Register B<br />

• Bit 7:5 – Reserved<br />

• Bit 4 - RXEN: Receiver Enable<br />

Register USART (III)<br />

• Setting this bit enables the USART Receiver. The Receiver will override normal<br />

port operation for the RxD pin when enabled.<br />

• Bit 3 - TXEN: Transmitter Enable<br />

• Setting this bit enables the USART Transmitter. The Transmitter will override<br />

normal port operation for the TxD pin when enabled.<br />

• Bit 2 - CLK2X: Double Transmission Speed<br />

• Bit 1 - MPCM: Multi-processor Communication Mode<br />

• Bit 0 - TXB8: Transmit Bit 8<br />

131


CTRLC - USART Control Register C<br />

Register USART (IV)<br />

• Bits 7:6 – CMODE[1:0]: USART Communication Mode<br />

CMODE[1:0] = 00 for „Asynchonous USART“<br />

• Bits 5:4 PMODE[1:0]: Parity Mode<br />

PMODE[1:0] = 00 (DISABLED) for „Parity Disabled“<br />

• Bit 3: SBMODE: Stop Bit Mode<br />

SBMODE = 0 for „1 Stop Bit“<br />

• Bit 2:0 – CHSIZE[2:0]: Character Size<br />

CHSIZE[2:0] = 011 (8BIT) for 8 bits<br />

132


Register USART(V)<br />

BAUDCTRLA - USART Baud Rate Register<br />

• Bit 7:0 - BSEL[7:0]: USART Baud Rate Register<br />

• This is a 12-bit value which contains the USART baud rate setting. The<br />

BAUDCTRLB contains the four most significant bits, and the BAUDCTRLA<br />

contains the eight least significant bits of the USART baud rate.<br />

BAUDCTRLB - USART Baud Rate Register<br />

• Bit 7:4 - BSCALE[3:0]: USART Baud Rate Scale factor<br />

These bits select the Baud Rate Generator scale factor. The scale factor is given<br />

in two's complement form from -7 (0b1001) to 7 (0b0111).<br />

• Bit 3:0 - BSEL[11:8]: USART Baud Rate Register<br />

133


Berechnung der Baudrate<br />

• <strong>Für</strong> uns wichtiger Bereich: BSCALE � 0. Dann gilt:<br />

BSEL∙2 BSCALE =<br />

fclk -1<br />

16 ∙ fBaud • Ein eventueller Nachkommaanteil von BSEL muss gerundet werden.<br />

Damit der Rundungsfehler möglichst gering ist, sollte BSCALE so<br />

negativ wie möglich gewählt werden, damit BSEL so groß wie<br />

möglich (aber noch mit 12 Bits darstellbar) ist.<br />

• Beispiel:<br />

<strong>Für</strong> f Baud = 9600 bei f clk = 2 MHz ergibt sich mit BSCALE = -7:<br />

BSEL = 1538,67 ≈ 1539 (Rundungsfehler: 0,02 %)<br />

134


USART-Module und Pins<br />

• PORTC, PORTD, PORTE, and PORTF verfügen jeweils über zwei<br />

USARTs. Diese heissen USARTC0, USARTC1, USARTD0,<br />

USARTD1, USARTE0, USARTE1, USARTF0 bzw. USARTF1.<br />

• RXD0/TXD0 liegen jeweils an Pin 2/3.<br />

• RXD1/TXD1 liegen jeweils an Pin 6/7.<br />

• USARTC0 wird auf dem Xplained-Board als virtuelle serielle<br />

Schnittstelle über USB bereitgestellt.<br />

135


#include <br />

#define USART USARTC0<br />

#define USART_PORT PORTC<br />

void initUSART()<br />

{<br />

}<br />

Beispiel: Initialisierung<br />

USART_PORT.DIRSET = PIN3_bm; // Pin 3 (TX) als Ausgang<br />

USART_PORT.DIRCLR = PIN2_bm; // Pin 2 (RX) als Eingang<br />

USART.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_CHSIZE_8BIT_gc |<br />

USART_PMODE_DISABLED_gc; // sowie 1 Stopp-Bit<br />

// 57600 Baud bei 2 MHz<br />

USART.BAUDCTRLA = 150; // BSELECT<br />

USART.BAUDCTRLB = -7


#include <br />

Beispiel: Schreiben und Lesen<br />

static int usart_putchar(char c, FILE *stream)<br />

{<br />

}<br />

if (c == '\n')<br />

usart_putchar('\r', stream);<br />

while ((USART.STATUS & USART_DREIF_bm) == 0) {}<br />

USART.DATA = c;<br />

return 0;<br />

static int usart_getchar(FILE *stream)<br />

{<br />

}<br />

while ((USART.STATUS & USART_RXCIF_bm) == 0) {}<br />

return USART.DATA;<br />

137


Beispiel: Assoziation mit stdin/stdout<br />

FILE usartstream = FDEV_SETUP_STREAM(usart_putchar, usart_getchar,<br />

_FDEV_SETUP_RW);<br />

int main(void)<br />

{<br />

}<br />

char c;<br />

initUSART();<br />

stdout = &usartstream;<br />

stdin = &usartstream;<br />

while(1) {<br />

}<br />

printf("Gib ein Zeichen ein.\n");<br />

c = getchar();<br />

printf("Dein Zeichen war: %c\n", c);<br />

138


Übungsaufgaben<br />

1. Bestimme geeignete Werte für BSEL/BSCALE für 19200 Baud bei<br />

f clk = 32 MHz.<br />

2. Das folgende Bild zeigt den Signalverlauf eines über eine serielle<br />

Schnittstelle RS 232 übertragenen ASCII-Zeichens (8N1).<br />

Bestimme die Baudrate und das übertragene Zeichen.<br />

139


A/D-Wandler<br />

140


Quelle: Wikipedia<br />

Zeit- und wertmäßige Quantisierung<br />

141


A/D-Wandler im ATxmega A: Überblick<br />

142


Differentieller Eingang mit Verstärkung (I)<br />

143


Differentieller Eingang mit Verstärkung (II)<br />

RES = [(VINP – VINN) / VREF] ⋅ GAIN ⋅ 2047<br />

144


Unipolarer Eingang (I): Signed und Unsigned<br />

ΔV = VREF × 0.05<br />

145


Unipolarer Eingang (II): Signed und Unsigned<br />

RES = [(VINP – VINN) / VREF] ⋅ GAIN ⋅ 2047<br />

RES = [(VINP – (-ΔV )) / VREF] ⋅ GAIN ⋅ 4095<br />

146


CTRLA - ADC Control Register A<br />

Register ADC (I)<br />

• Bits 7:6 – DMASEL[1:0]: DMA Request Selection<br />

• Bits 5:2 – CH[3:0]START: ADC Channel Start single conversion<br />

• Bit 1 – FLUSH: ADC Pipeline Flush:<br />

• Bit 0 – ENABLE: ADC Enable<br />

Setting this bit enables the ADC.<br />

147


CTRLB - ADC Control Register B<br />

Register ADC (II)<br />

• Bit 4 - CONVMODE: ADC Conversion Mode<br />

This bit controls whether the ADC should work in signed or unsigned mode. By<br />

default this bit is zero and the ADC is then configured for unsigned mode where<br />

single ended and internal signals can be measured. When this bit is set to one<br />

the ADC is configured for signed mode where also differential input can be used.<br />

• Bit 3 - FREERUN: ADC Free Running Mode.<br />

• Bits 2:1 - RESOLUTION[1:0]: ADC Conversion Result Resolution<br />

These bits define whether the ADC completes the conversion at 12- or 8-bit<br />

result. They also define whether the 12-bit result is left or right oriented in the 16bit<br />

result registers.<br />

RESOLUTION[1:0] Group Configuration Description<br />

00 12BIT 12-bit result, right adjusted<br />

01 Reserved<br />

10 8BIT 8-bit result, right adjusted<br />

11 LEFT12BIT 12-bit result, left adjusted<br />

148


Register ADC (III)<br />

REFCTRL - ADC Reference Control register<br />

• Bits 6:4 – REFSEL[1:0]: ADC Reference Selection<br />

These bits selects the reference and conversion range for the ADC.<br />

REFSEL[1:0] Group Configuration Description<br />

00 INT1V Internal 1.00 V<br />

01 INTVCC Internal V CC/1.6 V<br />

10 AREFA External reference AREF pin on PORT A.<br />

11 AREFB External reference from AREF pin on Port B.<br />

• Bit 1 – BANDGAP: Bandgap enable<br />

• Bit 0 – TEMPREF: Temperature Reference enable<br />

149


CTRL - ADC Channel Control Register<br />

Register ADC Channel (I)<br />

• Bit 7 - START: START Conversion on Channel<br />

Writing this to one will start a conversion on the channel. The bit is cleared by hardware when<br />

the conversion has started. Setting this bit when it already is set will have no effect. Writing or<br />

reading these bits is equivalent to writing the CH[3:0]START bits in ”CTRLA - ADC Control<br />

Register A”.<br />

• Bits 4:3 - GAIN[2:0]: ADC Gain Factor<br />

• Bit 1:0 - INPUTMODE[1:0]: Channel Input Mode<br />

150


Register ADC Channel (II)<br />

MUXCTRL - ADC Channel MUX Control registers<br />

• Bits 6:3 - MUXPOS[3:0]: MUX selection on Positive ADC input<br />

• Bits 1:0 - MUXNEG[1:0]: MUX selection on Negative ADC input<br />

These bits define the MUX selection for the negative ADC input when differential 151<br />

measurements are done. For internal or single-ended measurements, these bits


Register ADC Channel (III)<br />

INTFLAGS - ADC Channel Interrupt Flag registers<br />

• Bit 0 – IF: ADC Channel Interrupt Flag<br />

The interrupt flag is set when the ADC conversion is complete. If the channel is<br />

configured for compare mode, the flag will be set if the compare condition is met.<br />

IF is automatically cleared when the ADC channel interrupt vector is executed.<br />

The bit can also be cleared by writing a one to the bit location.<br />

152


Lichtsensor am ATXMEGA-A1 Xplained<br />

Quelle: Atmel/Vishay Semiconductors<br />

PB1<br />

153


int main( void )<br />

{<br />

}<br />

uint16_t ADC_result;<br />

Beispiel: Einlesen Lichtsensor<br />

ADCB.CTRLA = ADC_ENABLE_bm;<br />

ADCB.CTRLB = ADC_RESOLUTION_12BIT_gc; // unsigned, 12 bits<br />

ADCB.REFCTRL = ADC_REFSEL_VCC_gc; // internal VCC/1.6 V<br />

ADCB.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc; // Pin PB1<br />

while (1) {<br />

ADCB.CH0.INTFLAGS = ADC_CH_CHIF_bm;<br />

ADCB.CH0.CTRL = ADC_CH_START_bm | ADC_CH_GAIN_1X_gc |<br />

ADC_CH_INPUTMODE_SINGLEENDED_gc;<br />

}<br />

while(!(ADCB.CH0.INTFLAGS & ADC_CH_CHIF_bm));<br />

ADC_result = ADCB.CH0.RES;<br />

// ...<br />

154


Sensoren<br />

155


Taster/Schalter: Prellen<br />

• Prellen: Statt des sofortigen elektrischen Schließens bzw. Öffnens<br />

eines Kontaktes kurzzeitig ein mehrfaches Schließen und Öffnen.<br />

• Typische Dauer: einige 100 �s bis einige 10 ms<br />

• Beispiel:<br />

Quelle: Wikipedia<br />

156


Taster: Entprellen durch Hardware<br />

Quelle: http://www.mikrocontroller.net/articles/Entprellung<br />

157


Taster: Entprellen durch Software:<br />

Einfachste Lösung<br />

#define DEBOUNCE_TIME_MS 50<br />

uint8_t taste()<br />

{<br />

}<br />

unit8_t r = PORTD.IN & 0b000000001;<br />

_delay_ms(DEBOUNCE_TIME_MS);<br />

return r;<br />

• Hauptnachteil: Verzögerung bei jeder Abfrage der Taste<br />

– Bessere Strategie: Zeitinterruptgesteuertes „Zählen“, wie lange Pin<br />

gleichen Wert hat.<br />

158


1<br />

Matrixtastatur<br />

S1 S2<br />

S3<br />

4<br />

7<br />

*<br />

2<br />

5<br />

8<br />

0<br />

3<br />

6<br />

9<br />

#<br />

Z1<br />

Z2<br />

Z3<br />

Z4<br />

159


Drehimpulsgeber<br />

• auch: Drehgeber, Inkrementalgeber<br />

Quelle: Wikipedia<br />

160


A<br />

B<br />

Drehimpulsgeber: Ausgabe<br />

Rechtslauf →<br />

← Linkslauf<br />

161


• Gray-Code<br />

Drehimpulsgeber: Auswertung<br />

• Auswertung:<br />

Regelmäßiger Interrupt:<br />

Gray-Code dezimal<br />

00 0<br />

01 1<br />

11 2<br />

10 3<br />

– Lese AB ein und wandle in dezimal um.<br />

– Hat sich der Zustand verändert? Wenn ja, entscheide anhand des<br />

Vergleichs mit dem vorherigen Zustand die Drehrichtung.<br />

162


Serielle Bussysteme<br />

163


I 2 C<br />

� I 2 C = Inter-Integrated Circuit (Warenzeichen von NXP, ehemals<br />

Philips)<br />

� auch „Two-Wire-Interface“<br />

� seriell, synchron (Takt wird mit übertragen)<br />

� Master/Slave-Bus (auch Multi-Master-fähig)<br />

� 7-Bit-Adresse für Slaves<br />

� max. Takt 100 kHz (Standard Mode)<br />

� Slaves können aber „bremsen“, indem sie Clock-Low-Phase verlängern<br />

� Anwendungen: Verbindungen zwischen Mikrocontroller (Master)<br />

und Peripherie auf einer Leiterplatte, z. B. A/D-Wandler, E²PROM<br />

(auch: Krankenversichertenkarte)<br />

� Literatur: Philips Semiconductor: The I 2 C-bus specification (Quelle<br />

der folgenden Abbildungen)<br />

164


I 2 C: Beispiel<br />

165


� Leitungen SDA und SCL<br />

� Wired AND<br />

I 2 C: Elektrisch<br />

166


I 2 C: Rolle von SCL, Start- und<br />

Stoppbedingung<br />

� Daten ändern sich nur während SCL = 0:<br />

� Start- und Stoppbedingungen am Anfang bzw. Ende einer<br />

Übertragung:<br />

167


I 2 C: Übertragung von Bytes und Bestätigung<br />

� Es werden jeweils 8 Datenbits übertragen (MSB zuerst), danach<br />

sendet der Empfänger der Daten (kann Master oder Slave sein) ein<br />

9. Bit als Bestätigung (Acknowledgement).<br />

� Ist der Master Empfänger, sendet er nach dem letzten empfangenen<br />

Byte „not acknowledge“.<br />

168


I 2 C: Kompletter Datentransfer: Überblick<br />

169


I 2 C: Kompletter Datentransfer: Beispiele (I)<br />

� Master schreibt zum Slave:<br />

� Master liest vom Slave:<br />

170


I 2 C: Kompletter Datentransfer: Beispiele (II)<br />

� Kombination:<br />

171


Beispiel für Software-Implementierung mit<br />

Keil uVision<br />

sbit SDA = P1^0;<br />

sbit SCL = P1^1;<br />

void I2CwriteBit(bit b)<br />

{<br />

SDA = b;<br />

wait(10);<br />

SCL = 1;<br />

wait(10);<br />

SCL = 0;<br />

}<br />

172


Übungsaufgaben<br />

1. Im Folgenden ist eine Kommunikation auf dem I²C-Bus<br />

aufgezeichnet.<br />

a) Welche Adresse hat der Slave?<br />

b) Schreibt oder liest der Master?<br />

c) Welcher Wert wird geschrieben oder gelesen?<br />

d) Wie kommen die zwei kurzen „Impulse“ in dem Diagramm zustande?<br />

173


SPI<br />

� SPI = Serial Peripheral Interface<br />

� sehr lockerer Standard, ursprünglich von Motorola<br />

� seriell, synchron<br />

� Master-Slave-Bus<br />

� Adressierung jedes Slaves über individuelle CS-Leitung<br />

� Takt bis in MHz-Bereich<br />

� Anwendungen: Verbindungen zwischen Mikrocontroller (Master)<br />

und Peripherie auf einer Leiterplatte<br />

174


� Leitungen:<br />

SPI: Grundprinzip<br />

� SDO (Serial Data Out) bzw. MOSI (Master out Slave in)<br />

� SDI (Serial Data In) bzw. MISO (Master in Slave out)<br />

� SCK (Serial Clock)<br />

� CS/ (auch: SS/)<br />

� Daten werden vom Master in ein Schieberegister im Slave<br />

geschrieben. Gleichzeitig wird der „alte“ Inhalt des Schieberegisters<br />

hinausgeschrieben:<br />

Quelle: http://www.mct.de/faq/spi.html<br />

175


SPI: Anschluss mehrerer Slaves<br />

176


� Vier Modi:<br />

Modus CPOL CPHA<br />

0 0 0<br />

1 0 1<br />

2 1 0<br />

3 1 1<br />

� Parameter:<br />

� CPOL (clock polarity)<br />

SPI: Modi<br />

� CPOL = 0: Clock im Ruhezustand 0<br />

� CPHA (clock phase)<br />

� CPHA=0: Daten werden bei der ersten Flanke übernommen, nachdem SS/<br />

auf 0 gezogen wurde,<br />

� CPHA=1: Daten werden bei der zweiten Flanke übernommen.<br />

177


Quelle: Wikipedia<br />

SPI: Timing bei den verschiedenen Modi<br />

178


JTAG<br />

179


JTAG<br />

� JTAG (Joint Test Action Group) ist die gängige Bezeichnung für den<br />

Standard IEEE 1149.1<br />

� Zweck: Testen/Programmieren von Hardware direkt in der<br />

Schaltung<br />

� Grundlage: „Boundary Scan“<br />

180


JTAG<br />

� Leitungen zum TAP (Tap Access Point):<br />

� Test Data Input (TDI)<br />

� Serieller Eingang für Instruktionen und Test-Daten.<br />

� Test Data Output (TDO)<br />

� Serieller Ausgang für Test- und andere Daten.<br />

� Test Clock (TCK)<br />

� Taktet Daten in Test-Logik hinein/aus ihr heraus (unabhängig von<br />

Systemtakt).<br />

� Test Mode Select Input (TMS)<br />

� Dient zur Navigation durch den JTAG-Zustandsautomaten.<br />

� Test Reset (TRST) (optional)<br />

� Stecker nicht standardisiert.<br />

181


Quelle: http://www.caip.rutgers.edu/~bushnell/COURSE/lec28.ppt<br />

JTAG: Prinzip<br />

182


JTAG: Aufbau einer Boundary Scan Cell<br />

183


JTAG: SAMPLE/PRELOAD Instruction (I)<br />

� Speichert einen „Schnappschuss“ der derzeitigen Ein- und<br />

Ausgänge und legt diesen auf die Boundary-Scan-Kette<br />

184


JTAG: SAMPLE/PRELOAD Instruction (II)<br />

� Boundary-Scan-Kette wirkt als Schieberegister. Inhalt wird<br />

hinausgeschoben.<br />

185


JTAG: BYPASS Instruction<br />

� Umgeht Scan-Kette mit einem 1-Bit-Register. Verwendet zur<br />

Verkettung von JTAG-fähiger Hardware.<br />

186


Quelle: Wikipedia<br />

JTAG: Zustandsautomat<br />

187


Paralleles Bussystem<br />

188


Paralleles Bussystem<br />

� Dient zum Anschluss von externem Speicher und<br />

Peripheriebausteinen.<br />

� Bestandteile:<br />

Adressleitungen A[n:0]<br />

Datenleitungen D[7:0]<br />

Steuerleitungen CS/<br />

WE/<br />

RE/<br />

ALE1<br />

beim ATxmega128A1:<br />

Chip Select<br />

Write Enable<br />

Read Enable<br />

Address Latch Enable<br />

EBI (external<br />

bus interface)<br />

Ports H, J, K<br />

189


Quelle: Atmel XMEGA A Manual<br />

Schreibzyklus SRAM (I)<br />

190


Schreibzyklus SRAM (II)<br />

1. CPU gibt Adresse, auf die geschrieben werden soll, auf Adressbus<br />

aus und aktiviert CS/-Signal.<br />

2. CPU gibt zu schreibendes Datum auf Datenbus aus.<br />

3. CPU aktiviert WE/-Signal.<br />

4. CPU deaktiviert WE/-Signal (steigende Flanke). Mit dieser Flanke<br />

übernimmt angesprochener Speicher das Datum.<br />

5. CPU nimmt Datum von Datenbus weg und deaktiviert CS/-Signal.<br />

191


Lesezyklus SRAM<br />

192


Multiplexen von Adressleitungen mit ALE<br />

74x573<br />

193


Schreibzyklus SRAM<br />

mit gemultiplextem Adressbus<br />

194


� Hersteller: Cypress<br />

� SRAM<br />

Beispiel: SRAM CY7C199 (I)<br />

� Organisation: 32K x 8 =<br />

32 · 1024 Speicherstellen<br />

je 8 Bits<br />

� Steuerleitungen:<br />

WE/ = write enable<br />

OE/ = output enable<br />

CE/ = chip enable<br />

Quelle: Datenblatt CY7C199<br />

195


Beispiel: Speicher CY7C199 (II)<br />

196


Beispiel: Speicher CY7C199 (III)<br />

197


Beispiel: Speicher CY7C199 (IV)<br />

198


Beispiel: DA-Wandler AD7302<br />

� Hersteller: Analog Devices<br />

� Dual Voltage Output 8-Bit<br />

DAC<br />

Quelle: Datenblatt AD7302<br />

� Steuerleitungen:<br />

A/B = Address pin to select<br />

DAC A or B<br />

WR/ = write<br />

CS/ = chip select<br />

199


Anschluss von Speicher an eine CPU:<br />

Beispiel I<br />

CPU<br />

RE<br />

WE<br />

OE<br />

8K x 8<br />

WE<br />

/CE /CE<br />

Speicherchip 1<br />

Adress-Bus A[15:0]<br />

Daten-Bus D[7:0]<br />

OE<br />

8K x 8<br />

Speicherchip 2<br />

WE<br />

200


Anschluss von Speicher und Peripherie an eine<br />

CPU: Beispiel II: Aufgabenstellung<br />

� Aufgabe:<br />

Folgende Bausteine sind an eine CPU mit 16 Bit Adressraum<br />

anzuschließen, so dass sie an den angegebenen Adressen<br />

anzusprechen sind:<br />

Baustein Adressen im Adressraum der<br />

CPU:<br />

SRAM 32K x 8 (CY7C199) 0x0000 – 0x7FFF<br />

AD7302 0xF000 und 0xF001<br />

201


CPU<br />

Beispiel II: Mögliche Lösung (I)<br />

D7<br />

...<br />

D0<br />

ALE<br />

A7/A15<br />

...<br />

A0/A8<br />

74HC573<br />

D7<br />

…<br />

D0<br />

A15<br />

LE RAM<br />

Q7<br />

…<br />

Q0<br />

D7<br />

...<br />

D0<br />

A14<br />

...<br />

A8<br />

A7<br />

...<br />

A0<br />

CE/<br />

1<br />

A0<br />

D7<br />

…<br />

D0<br />

AD7302<br />

A/B<br />

CS/


Beispiel II: Mögliche Lösung (II)<br />

� Gleichungen des Adressdecoders:<br />

CS/ SRAM = A15<br />

CS/ AD7302 = A15/<br />

203


Beispiel II: Mögliche Lösung (III)<br />

� Resultierende Adresstabelle:<br />

A<br />

1<br />

5<br />

A<br />

0<br />

Hexadezimal<br />

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000 CS/ SRAM =0<br />

� �<br />

0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7FFF<br />

1 x x x x x x x x x x x x x x 0 8000, 8002, ..., FFFE CS/ AD7302 =0<br />

1 x x x x x x x x x x x x x x 1 8001, 8003, ..., FFFF<br />

für Adressdecodierung<br />

verwendet<br />

nicht verwendet<br />

an Peripheriebaustein<br />

angeschlossen<br />

„Spiegelungen“<br />

204


Strategien für die Adressdecodierung (I)<br />

� Minimale Adressdecodierung<br />

� Es werden nur die minimale Anzahl von Adressleitungen zur<br />

Adressdecodierung verwendet, die nötig sind, um die<br />

vorhandenen Speicher-/Peripheriebausteine in den Speicher<br />

einzublenden.<br />

� Beispiel: vorherige Folie<br />

205


Strategien für die Adressdecodierung (II)<br />

� Teilweise Adressdecodierung<br />

� Es werden einige Adressleitungen zur Adressdecodierung<br />

verwendet.<br />

� Beispiel:<br />

206


Strategien für die Adressdecodierung (III)<br />

� Vollständige Adressdecodierung<br />

� Es werden alle Adressleitungen zur Adressdecodierung verwendet.<br />

� Beispiel:<br />

CS/ AD7302 = A15 � A14 �A13 �A12 � A11/ � A10/ � A9/ � A8/ � A7/ � A6/ �<br />

A5/ � A4/ � A3/ � A2/ � A1/<br />

207


Optionen zum Anschluss von<br />

Peripheriebausteinen (z. B. DA-Wandler, LCD, ...)<br />

� Serieller Bus, z. B. I²C<br />

� Paralleler Bus, „Memory-Mapped“<br />

� Verwendung von Port-Bits<br />

� Erzeugung der Steuersignale wie E, R/W/ über Software<br />

208


Übungsaufgaben<br />

1. Ein Speicherbaustein wird mit den Adressen 0x0000 bis 0x1FFF<br />

angesprochen.<br />

a) Wie viele Adressleitungen besitzt der Baustein?<br />

b) Wie viele Speicherstellen besitzt der Baustein?<br />

2. Der CE/-Eingang eines 6264 sei an den Ausgang einer NAND-<br />

Verknüpfung der Adressleitungen A15, A14 und A13 einer CPU<br />

(Adressraum: 16 Bits) angeschlossen. Gib alle Adressen im<br />

Adressraum der CPU an, unter denen der 6264 aktiviert wird.<br />

209


Übungsaufgaben (II)<br />

3. Es wird nach der Methode der „linearen Auswahl“ folgender<br />

Adressdekoder aufgebaut:<br />

Quelle: Prof. Liebmann<br />

a) In welchen Adressbereichen der CPU werden die einzelnen<br />

Chip Select-Signale aktiv ( = low)?<br />

b) Welche Adressbereiche dürfen von der CPU nicht<br />

angesprochen werden?<br />

c) Welcher Adressbereich kann nicht dekodiert werden?<br />

210


Auswahl Mikrocontroller<br />

211


Kriterien zur Auswahl von Mikrocontrollern<br />

• Verfügbarkeit<br />

– jetzt/zukünftig<br />

• Preis<br />

– Chips, Entwicklungswerkzeuge wie Software und Programmieradapter, ggf.<br />

Schulung/Support<br />

• Bauform<br />

• Spannungen<br />

• Leistungsaufnahme<br />

• Geschwindigkeit<br />

• Integrierter/anschließbarer Speicher und integrierte Peripherie, Schnittstellen<br />

• Verfügbarkeit/Qualität von Dokumentation<br />

• Support<br />

– Hersteller/Community<br />

• Verfügbare Fremdsoftware<br />

– z. B. RTOS, Dateisystem o. ä.<br />

• Unterstützte Programmiersprachen<br />

• Programmier-/Debugmöglichkeit<br />

• Vorhandene Erfahrungen/vorhandener Code<br />

212


• 8 Bit<br />

Einige Mikrocontroller-Architekturen<br />

– MCS-51 (früher Intel, jetzt diverse Hersteller)<br />

– H8 (Renesas, früher Hitachi)<br />

– 68HC05, 68HC08, 68HC11 (Freescale, früher Motorola)<br />

– AVR (Atmel)<br />

– PIC (Microchip)<br />

– PicoBlaze (Xilinx, zur Integration in ein FPGA)<br />

• 16 Bit<br />

– C16x (Infineon, früher Siemens)<br />

– 68HC12, 68HC16 (Freescale, früher Motorola)<br />

– dsPIC (Microchip)<br />

– MSP430 (Texas Instruments)<br />

• 32 Bit<br />

– ARM (diverse Hersteller, z. B. STMicroelectronics, NXP, Atmel)<br />

– AVR32 (Atmel)<br />

– Tricore (Infineon, früher Siemens)<br />

213


• Ursprünglich: Intel 8051 (1979)<br />

MCS-51 (I)<br />

• Durch Lizensierung viele Varianten (auch aktuelle!) von vielen<br />

Herstellern, u. a. Analog Devices, Atmel, Infineon, Maxim/Dallas,<br />

Oki, NXP, Silicon Laboratories, Texas Instruments<br />

• 8 Bit<br />

• CISC-Befehlssatz<br />

– Beispiele:<br />

• DJNZ R0,marke: „decrement and jump if not zero“<br />

• ADD A,R2 linker Operand nur „Akkumulator“ (spezielles Register)<br />

• Spezielle Befehle für Bitoperationen auf einem Teil des Datenspeichers<br />

• Befehlsausführung:<br />

– 1 Befehl = 1 bis 3 Maschinenzyklen<br />

– 1 Maschinenzyklus = ursprünglich 12, jetzt oft 1 Taktzyklus<br />

214


• Besonderheiten beim Speicher:<br />

MCS-51 (II)<br />

– Getrennter Programm- und Datenspeicher (jeweils (eigentlich) max. 64<br />

kiBytes)<br />

– Unterscheidung zwischen „internem“ und „externem“ Datenspeicher<br />

• Interner Datenspeicher max. 256 Bytes<br />

• Stack nur in internem Datenspeicher<br />

– (eigentlich) 128 Bytes Special Function Registers (SFR)<br />

• Erweiterungen der Zweithersteller uneinheitlich<br />

• Unfreundlich für C-Compiler (mehrere Spracherweiterungen nötig)<br />

215


• Schaltung der Ports:<br />

Quelle: Wikipedia<br />

MCS-51 (III)<br />

216


• Hersteller: STMicroelectronics<br />

STM32 (I)<br />

• Über 75 Varianten verfügbar, auch z. B. mit LCD-, CAN-, USB-,<br />

Ethernet-Schnittstelle<br />

• Basiert auf ARM Cortex M3-CPU<br />

– 32 Bits<br />

– RISC-Befehlssatz „Thumb2“<br />

• Die meisten Befehle werden in 16 Bits codiert.<br />

– Die meisten Befehle werden in 1 Taktzyklus ausgeführt.<br />

– Sehr C-Compiler-freundlich.<br />

• Besonderheiten bei Interrupts:<br />

– Interrupt-Vektoren enthalten direkt Adressen der ISRs (keine Sprung-<br />

oder anderen Befehle).<br />

– Automatisches Speichern von einigen Registern bei einem Interrupt.<br />

• Besonderheit: Bit Banding<br />

217


Quelle: STMicro<br />

STM32: Memory Map<br />

218


STM32: Bit Banding (I)<br />

• Bit Banding: Die einzelnen Bits der 32-Bit-Worte haben eine zweite, eigene<br />

Adresse („alias“), deren Inhalt 0x00000000 oder 0x00000001 ist.<br />

219


STM32: Bit Banding (II)<br />

• Beispiel: Setze Bit 3 im Byte 0x20000000.<br />

• Ohne Bit Banding:<br />

uint8_t *p = 0x20000000;<br />

*p |= 1


Echtzeitsysteme<br />

221


Definition Echtzeit<br />

• Echtzeit (englisch real-time): Die Dauer eines Vorgangs (bei uns<br />

insbesondere: Reaktion auf ein Ereignis) ist vorhersagbar.<br />

• Unterscheidung:<br />

– Weiche Echtzeit: Eine angegebene Obergrenze für die Dauer wird<br />

„normalerweise“ nicht überschritten.<br />

– Harte Echtzeit: Eine angegebene Obergrenze für die Dauer wird<br />

(mathematisch beweisbar) niemals überschritten.<br />

222


Aufgabe<br />

1. Exakt alle 100 µs soll (per Software) Pin E0 invertiert werden.<br />

2. Bei jeder steigenden Flanke an Pin E7 soll ein Wert aus dem A/D-<br />

Wandler abgeholt werden (ADCA.CH0.RES, vorzeichenbehaftet). Ist<br />

dieser Wert größer 0, so soll Pin E1 gesetzt, andernfalls gelöscht<br />

werden.<br />

223


Fragen<br />

a) Schreibe Interrupt-Service-Routinen für die Aufgaben 1 und 2.<br />

b) Wenn nur die Aufgabe 1 ausgeführt wird, wie viel Prozent ist unser<br />

Mikroprozessor (ATxmega128A, 2 MHz) damit ausgelastet?<br />

c) Wie sollte man die Prioritäten der beiden Interrupts wählen?<br />

d) Wenn Aufgaben 1 und 2 ausgeführt werden, wie groß ist dann die<br />

Reaktionszeit für Aufgabe 2 maximal? Mit welcher Frequenz darf<br />

das Ereignis von Aufgabe 2 maximal auftreten?<br />

224


Interrupt Response Time<br />

(Quelle: XMEGA A Manual)<br />

12.4.2 Interrupt Response Time<br />

The interrupt response time for all the enabled interrupts is five<br />

CPU clock cycles minimum. During these five clock cycles the<br />

program counter is pushed on the stack. After five clock cycles,<br />

the program vector for the interrupt is executed. The jump to the<br />

interrupt handler takes three clock cycles.<br />

If an interrupt occurs during execution of a multi-cycle instruction,<br />

this instruction is completed before the interrupt is served. If an<br />

interrupt occurs when the device is in sleep mode, the interrupt<br />

execution response time is increased by five clock cycles. In<br />

addition the response time is increased by the start-up time from<br />

the selected sleep mode.<br />

A return from an interrupt handling routine takes five clock<br />

cycles. During these five clock cycles, the program counter is<br />

popped from the stack and the stack pointer is incremented.<br />

225

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!