Autonome Mobile Systeme Dr. Stefan Enderle
2. Mikrocontroller
Einleitung Unterschied Controller / Prozessor: Speicher (RAM, Flash, Eprom) intern Viele I/Os (Digital, Analog) Bus-Unterstützung (Seriell, I2C, CAN, ) Vorteile von Controllern billig klein robust (Temperatur, Klima) Absolute Kontrolle (kein BS) langfristige Erhältlichkeit
von Neumann Architektur bisher: Programme auf Lochkarten Daten im Speicher (Relais) neu (1945): Programme sind auch Daten EIN Speicher für beides! Komponenten ALU Memory (für Prg. und Daten) Control Unit I/O Unit Verbindungssystem Von-Neumann Flaschenhals Verbindungssystem = Engpass. CPUs schneller als Speicher Caches
Harvard Architektur Trennung von Programmund Datenspeicher Befehl und zugehörige Daten in 1 Zyklus in ALU Heute mehrere ALUs Daten- und Befehlsbreite können unterschiedlich sein In Controllern meist Programm im Flash, Daten im RAM/EEPROM
Intel 8051 Urvater aller Mikrocontroller: 1980 8 Bit Harvard-Architektur 255 Befehle Memory 64K Programmspeicher 256Bytes internes RAM I/O 32 Pins (4 Ports à 8 Pins) Serieller Port Sonstiges 2x 16 Bit Timer / Counter
Atmel AVR Familie Features Harvard Architektur Single cycle execution 1.8V 5.5V Sleep mode Architektur für C-Code ISP (In-system programming)
Beispiel: ATmega32 32K Flash 2K RAM 1K EEprom 32 GPIOs 16 MHz I2C Bus
ATmega32 - Architektur
ATmega32 - Anschlüsse Versorgungsspannung Quarz-Anschlüsse Reset 4 Ports ISP (MISO,MOSI,SCK)
mega32 - Grundschaltung
Test auf Steckbrett
Roboter-Controllerboard Spannungsversorgung (meist 5V) Controller Motortreiber Sensor-Eingänge (digital, analog) Download-Anschluss Optional: LEDs Taster Bus Digital-Ausgänge
Fertiges Controllerboard (qfix)
Controller-Programmierung Meist Assembler oder C Neuerdings auch C++ (reduziert) Vorteile von C/C++ gegenüber Assembler Keine kryptischen ASM Befehle Schneller (Programmierung) Time to market Mehr Entwickler verfügbar Wiederverwendbarkeit größer Viele Libraries Aber: Keine zeitkritischen Abläufe
Programmierumgebung Für Windows: Paket WinAVR : GCC AVR Cross-Compiler AVR C-Library Editor Programmer s Notepad Download Tools (avrdude) Für Linux: Controller Lab s.o.
Pins und Ports Pin: Einzelne Leitung des Controllers Port: 8 Pins zusammengefasst Port belegt ein Byte (PORTA, PORTB, ) Pin belegt ein Bit Ansteuerung einzelner Pins über Bit- Befehle
Wichtig: Bit-Befehle Setzen von PA0: PORTA = PORTA 1; Löschen von PA0: PORTA = PORTA & (255-1); Setzen von PA7: PORTA = PORTA 128;
Beispiel: LED Schaltung (Tafel) LEDs leuchten, wenn PIN PB4-PB7 auf Masse (low aktiv) DDRB = 255; PORTB = 0;
Beispiel: Taster abfragen Der Taster T0 zieht PA7 auf Masse Pullup für definiertes High Abfrage mit PINA! DDRA = 0; PORTA = 255; while(1) { if (PINA & 128) ledoff(); else ledon(); }
Beispiel: Motoren ansteuern mega32 kann nur 40 ma bei 5V treiben Motor zieht aber z.b. 500mA bei 12V AN/AUS mit Relais oder Transistor (Bild Tafel) Umschalten mit Relais oder H-Brücke (Bild Tafel) Freilaufdiode nicht vergessen!
H-Brücke mit MOS-FETs 2 Controller Pins: Richtung AN/AUS (PWM)
Integrierte H-Brücke L293D Pro Motor 3 Pins: Enable, A, B
Beispiel: Motor anschalten PC2 = enable PC4 = input1, PC5 = input 2 DDRC = 255; PORTC = 16; // input1 = 1 PORTC &= (255-32); // input2 = 0 PORTC = 4; // enable = 1
Geschwindigkeitsregelung Naiv: Durch regelbaren Vorwiderstand Bild Tafel Problem: Verlustleistung P = U*I = R*I² Beispiel Tafel Besser: Schnelles An/Ausschalten Pulsweitenmodulation
Pulsweitenmodulation (PWM) Trägheit des Motors wird ausgenutzt Energie im Motor wird reduziert E = U*I*t Periodendauer immer gleich! Weiter Bereich möglich (100Hz 100kHz)
Beispiel: PWM in Hauptschleife Idee: Counter zählt immer 255 0 speed bestimmt High-Low Übergang int counter=255; int speed =150; while(1) { if (counter < speed) PORTC = 4; // enable1 = 1 else PORTC &= (255-4); // enable1 = 0 } if (counter==0) counter=255; else counter--;
Timer Interrupts Periodische Abläufe Mehrere Timer (8 Bit / 16 Bit) Bei Überlauf wird Interrupt-Routine ausgeführt
Timer Interrupts Ablauf: 1. Interrupt-Routine schreiben SIGNAL (SIG_OVERFLOW0) {... } 4. Timer wählen TIMSK=1;
Timer Interrupts (2) 1. Clock / Prescaler wählen TCCR0=1; 8. Anschalten sei();
Beispiel: LED Blinker SIGNAL (SIG_OVERFLOW0) { PORTB ^= 16; } TIMSK=1; // enable timer 0 TCCR0=1; // prescaler: 1 = no prescaler sei(); // enable interrupts
Timer Interrupts - Feinsteuerung Aufruf bei Überlauf des 8 Bit Timers Direkter Zugriff auf TCNT0 möglich TCNT0=128; // double rate
Beispiel: Blinken mit 1Hz Takt = 8MHz Taktdauer = 125ns prescaler=8 1us TCNT0=155 100us Eigener Zähler mit 10.000 1s
Beispiel: PWM als Interrupt-Routine SIGNAL (SIG_OVERFLOW0) { static int counter=255; if (counter < speed) PORTC = 4; // enable1 = 1 else PORTC &= (255-4); // enable1 = 0 } if (counter==0) counter=255; else counter--; TCCR0=1; // prescaler: 1=no prescaler TIMSK=1; // enable timer 0 sei(); // enable interrupts speed = 150;
Analogwerte einlesen Alle 8 PINs des Port A können A/D Ablauf: 1. Ports initialisieren DDRA = 0; 3. A/D Wandler anschalten ADCSRA=128; 5. A/D Wandlung starten // all bits input // set A/D enable bit (ADEN) ADMUX=0; // select analog input (0) ADMUX = (1<<ADLAR); // left adjust -> we use only ADCH ADCSRA = (1<<ADSC); // start conversion while (ADCSRA & 64); // wait until ADSC is low again int value = ADCH; // read 8 bit value fom
Blinker mit Poti //Blinker wie oben per Interrupt int analog() { ADMUX=0; // select analog input (0) ADMUX = (1<<ADLAR); // left adjust -> we use only ADCH ADCSRA = (1<<ADSC); // start conversion while (ADCSRA & 64); // wait until ADSC is low again int value = ADCH; // read 8 bit value fom ADCH return value; } int main() { DDRA = 0; ADCSRA=128; // all bits input // set A/D enable bit (ADEN) } while (1) { speed = analog(); }
Externe Interrupts Beispiel INT7/PE7 auf mega128! Ablauf: 1. Eingänge initialisieren DDRE=0; // all input PORTE =128; // PE7 pullup 4. Interrupt-Routine schreiben SIGNAL (SIG_INTERRUPT7) {... }
Externe Interrupts (2) 1. Eingang wählen EIMSK=128; 3. Art wählen EICRB=64; // enable INT7 // INT7 for any change on PE7 5. Anschalten sei();
Beispiel: Fernsteuerung Signal siehe Tafel Auswertung durch Kombination von Timer-Interrupts und Externe Interrupts: Externer Interrupt reagiert auf Signal- Übergänge und misst Zeit mittels Timer Timer Interrupt setzt Kanal-Zähler zurück