Skip to content

MSP430 - Mixed-Signal-Module

Analog-Digital-Wandler

Übersicht

Flash- oder Parallelwandler

alt: "Aufbau Flash-ADC", src: "Wikipedia Commons", w:50

Prinzip der sukzessiven Approximation

alt: "Aufbau SAR-ADC", src: "Wikipedia Commons", w:50

Sigma-Delta-Wandler

alt: "Aufbau SD-ADC", src: "Wikipedia Commons", w:50

ADC10 des MSP430F2274

alt: "Übersicht ADC10", src: "Familiy Guide S. 535", w:75

  • 10-bit SAR

    • Formel zur Berechnung des ADC-Ergebnisses:

      \[ N\ped{ADC} = 1023 \cdot \frac{V\ped{IN} - V\ped{R-}}{V\ped{R+} - V\ped{R-}} \]
    • ADC-Clock Selection:
      • Typische Taktquellen: ACLK, MCLK, SMCLK
      • Zusätzlich ADC10OSC mit ca. 5 MHz
    • Sample & Hold-Schaltung
    • Sample-Zeit kann eingestellt werden
    • Hold-Zeit entsprechend der Conversion-Zeit
    • Analoger Multiplexer
    • Verschiedene Eingangssignale können gemessen werden
    • Analoge Eingänge A0 bis A7 am Port 1 des MSP430G2553
    • Temperatursensor an INCH = 10
    • AVcc / 2 an INCH = 11
    • Referenzspannungsquellen:
    • z. B. \(V\ped{R+} = V\ped{CC}\), \(V\ped{R-} = V\ped{SS}\) oder \(V\ped{R+} = V\ped{REF+}\), \(V\ped{R-} = V\ped{SS}\)
    • Interne Referenzspannungsquelle kann auf 1,5 V oder 2,5 V eingestellt werden
    • Data Transfer Controller
    • sinnvoll für viele schnelle Messungen hintereinander, wenn CPU es nicht schafft ADC-Ergebnis in RAM abzuspeichern
    • auch genannt DMA (direct memory access)
    • DTC speichert ADC-Ergebnis automatisch an gewünschter Stelle im RAM ab.
    • z. B. Erstellen eines Ringspeichers: zyklisches Abspeichern eines Messwertes

Programmierung

alt: "Pinbelegung des MSP430G2553 mit 20 Pins", w: 75, src: "https://github.com/RobFro96/MSP430Pinouts"
alt: "Register ADC10CTL0", src: "Family Guide S. 553f", w: 75
alt: "Register ADC10CTL1", src: "Family Guide S. 555f", w: 75

Auslesen des analogen Potentiometer-Eingangs

#include <msp430.h>
#include <stdint.h>

int main(void) {
    WDTCTL = WDTPW | WDTHOLD;    // stop watchdog timer

    BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ;

    ADC10CTL0 = ADC10ON + ADC10IE;
    ADC10CTL1 = INCH_7;
    ADC10AE0 |= BIT7;

    // RGB LED
    P2OUT &= ~(BIT1 + BIT3 + BIT5);
    P2DIR |= BIT1 + BIT3 + BIT5;

    __enable_interrupt();

    while (1) {
        ADC10CTL0 |= ENC + ADC10SC;
        __low_power_mode_0();

        uint16_t result = ADC10MEM;
        if (result < 204) {
            // red
            P2OUT |= BIT1;
            P2OUT &= ~(BIT3 + BIT5);
        } else if (result < 409) {
            // yellow
            P2OUT |= BIT1 + BIT3;
            P2OUT &= ~ BIT5;
        } else if (result < 613) {
            // green
            P2OUT |= BIT3;
            P2OUT &= ~(BIT1 + BIT5);
        } else if (result < 818) {
            // cyan
            P2OUT |= BIT3 + BIT5;
            P2OUT &= ~BIT1;
        } else {
            // blue
            P2OUT |= BIT5;
            P2OUT &= ~(BIT1 + BIT3);
        }
    }
}

#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR() {
    __low_power_mode_off_on_exit();
}

Anmerkungen zur Sampling-Zeit

alt: "Ersatzschaltbild zur Betrachtung der Samplezeit", src: "Family Guide S. 538", w: 50

\[ R\ped I < 2\,\text k\Omega,\quad C\ped I < 27\,\text{pF} \]
\[ t_{\text{sample}} > R_{\text{ges}} \cdot C\ped I \cdot \ln(2^{11}) \]

Integrierter Operationsverstärker

  • Manche MSP430 haben einen integrierten OPV - der MSP430G2553 nicht!
  • Verschiedene Funktionen des OA-Moduls:
    alt: "Funktionen des OA-Moduls", src:"Family Guide S. 514", w:50
  • Aufbau des OA-Moduls:
    alt: "Aufbau des OA-Moduls", src: "Family Guide S. 513", w:75
  • Ausgangssignale:
    • Analoger Ausgang durch OAxO an Pins
    • Verwendung als Eingangssignal des ADC-Wandlers (z. B. Vorverstärkung des Eingangssignals durch OA)

Integrierter Komparator

Übersicht

  • Das Comparator A+ Modul ist im MSP430G2553 verbaut.
  • Aufbau des Comparator A+
    alt: "Aufbau Comparator A+", src: "Family Guide S. 524", w:75
  • Vergleich des Spannungslevels verschiedener Eingangssignale
  • Vergleich mit verschiedenen Referenzspannungen: Vcc/2, Vcc/4, 0.55 V
  • Weiterverarbeiten des Komparatorausgangs durch Interrupt, TimerA, CAOUT-Ausgang

Beispiel der Widerstandsmessung

alt: "Beschaltung des MSP430", src: "Family Guide S. 528", w: 50
alt: "Spannungsverlauf und Berechnungen", src: "Family Guide S. 529", w: 75

Kapazitives Touch

  • Grundprinzip: Menschliche Körper stellt eine zusätzliche Kapazität gegen Masse dar
  • Vorteile:
    • Simples Sensordesign:
      • Ledglich zusätzliche Leiterbahn auf Leiterplatte
      • Keine mechanischen Bauelemente, wie Taster notwendig
    • Vorteile bei wasserfesten Anwendungen

Programmierung beliebiger Mikrocontroller

  • Ablauf des Programms:
    • Pin wird als Ausgang, High geschaltet
    • Circa. \(500\,\mu\text s\) warten, bis alle Kondensatoren auf 3,3 V geladen sind
    • Pin wird als Ausgang, Low geschaltet → interne Kondensator entlädt sich
    • Pin wird als Eingang geschaltet → externen Kondensatoren laden internen Kondensator auf
    • Nach ca. \(30\,\mu\text s\) wird der Eingangswert des Pins gelesen
      • Wenn der Eingang auf Low liegt, wird der Sensor nicht berührt
      • Wenn der Eingang auf High liegt, wird der Sensor berührt

Touchsensor mit einem regulären GPIO

#include <msp430.h>
#include <stdint.h>

int main(void) {
    WDTCTL = WDTPW | WDTHOLD;    // stop watchdog timer

    P1DIR |= BIT0;

    __enable_interrupt();

    while (1) {
        P1OUT |= BIT4;
        P1DIR |= BIT4;
        __delay_cycles(500);

        P1OUT &= ~BIT4;
        P1DIR &= ~BIT4;
        __delay_cycles(30);

        if (P1IN & BIT4) {
            P1OUT |= BIT0;
        } else {
            P1OUT &= ~BIT0;
        }
    }
}

alt: "Oszilloskop-Aufnahme ohne Berührung", w:50
alt: "Oszilloskop-Aufnahme mit Berührung", w:50

Möglichkeiten der Pin Oscillator-Funktion

alt: "Aufbau des Pin Oscillator", src: "Family Guide S. 330", w:66
alt: "Pin Oscillator Kennlinie", src: "Family Guide S. 331", w:33

  • Automatisches Umladen der Pin-Kapazität durch eine Inverterschaltung
  • Frequenz der entstehenden Schwingung ist abhängig von der Umladegeschwindigkeit
  • Umladegeschwindigkeit ist abhängig von dem internen Ladewiderstand und der Pin-Kapazität
  • Durchführen einer Frequenzmessung durch Timer
  • Mit Pin Oscillator kann eine deutlich empfindlichere Kapazitätsmessung durchgeführt werden
    → Berührungsdetektion ohne galvanische Verbindung ist möglich
    → Entscheidend für wasserdichtes Gehäuse und Korrosionsschutz der Kontaktfläche

Touchsensor mit der MSP430 Pin Oscillator-Funktion

#include <msp430.h>
#include <stdint.h>

void uart_print(char *str) {
    while (*str != 0) {
        while (!(IFG2 & UCA0TXIFG)) {
        }
        UCA0TXBUF = *str;
        *str++;
    }
}

void uart_hex(uint8_t number) {
    char str[3];
    for (uint8_t i = 0; i < 2; i++) {
        uint8_t digit = number & 0xf;
        if (digit < 10) {
            str[1 - i] = '0' + digit;
        } else {
            str[1 - i] = 'a' + digit - 10;
        }
        number >>= 4;
    }

    str[2] = 0;
    uart_print(str);
}

int main(void) {
    WDTCTL = WDTPW | WDTHOLD;    // stop watchdog timer

    BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ;

    // LED
    P1DIR |= BIT0;

    // UART
    P1SEL |= BIT2;
    P1SEL2 |= BIT2;
    UCA0CTL1 |= UCSWRST;
    UCA0CTL0 = 0;
    UCA0CTL1 |= UCSSEL_2;
    UCA0BR0 = 104;
    UCA0BR1 = 0;
    UCA0MCTL = (1 << 1);
    UCA0CTL1 &= ~UCSWRST;

    IE1 |= WDTIE;

    __enable_interrupt();

    while (1) {
        TA0CTL = TASSEL_3 + MC_2;                   // TACLK, cont mode
        TA0CCTL1 = CM_3 + CCIS_2 + CAP;               // Pos&Neg,GND,Cap

        P1DIR &= ~ BIT4;
        P1SEL &= ~ BIT4;
        P1SEL2 |= BIT4;

        WDTCTL = WDTPW + WDTTMSEL + WDTCNTCL + WDTSSEL + WDTIS1;              // WDT, ACLK, interval timer
        TA0CTL |= TACLR;                        // Clear Timer_A TAR

        __low_power_mode_0();   // Wait for WDT interrupt
        TA0CCTL1 ^= CCIS_1;                      // Create SW capture of CCR1
        uint16_t meas_cnt = TACCR1;                      // Save result
        WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer
        P1SEL2 &= ~BIT4;

        uart_hex(meas_cnt >> 8);
        uart_hex(meas_cnt & 0xFF);
        uart_print("\r\n");

        if (meas_cnt < 0x5000) {
            P1OUT |= BIT0;
        } else {
            P1OUT &= ~ BIT0;
        }
    }
}


#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void) {
    TA0CCTL1 ^= CCIS_1;                        // Create SW capture of CCR1
    __low_power_mode_off_on_exit();
}

Einführung in die digitale Signalverarbeitung

Überblick

alt: "Überblick digitale Signalverarbeitung", src: "Hochschule Karlsruhe", w: 75

  • Entscheidend für alle Schritte des digitalen Signalverarbeitung: Abtastzeit TS
  • TS bestimmt die Grenzfrequenzen des Eingangs- und Ausgangstiefpass
  • Nicht alle digitalen Signalverarbeitungskette besitzen ein Ausgangssignal
  • Datenanalyse im digitalen Signalprozessor möglich

Beispiel eines digitalen Filter

  • Differenzengleichung

    \[y[k] = 0{,}25 \cdot u[k] + 0{,}25 \cdot u[k-1] +0{,}25 \cdot u[k-2] + 0{,}25 \cdot u[k-3]\]
  • Analyse des Frequenzgangs des digitalen Filters

    • Übertragungsfunktion:

      \[ G(z) = 0{,}25 \cdot (1+z^{-1}+z^{-2}+z^{-3}) = 0{,}25 \cdot \frac{z^3+z^2+z+1}{z^3} \]
    • Analyse des Frequenzgangs mit MATLAB:
      freqz([.25, .25, .25, .25], [1])

      alt: "Filter-Frequenzgang aus MATLAB", w:75

  • Erstellen des Blockschaltbildes
  • Wichtigste Funktionen der DSV:
    • Verzögerungsglied (Zugriff auf vergangene Abtastwerte)
    • Verstärkungsglied (Multiplikation mit festen Faktor)
    • Additionsglied (Addition zweier Signale)

Multiplikation in einem MCU / DSP

  • Eine Multiplikation benötigt eine Vielzahl von Schiebe- und Additionsoperationen
  • Das Ergebnis einer Multiplikation ist immer doppelt so groß, wie die Eingangswerte:
    Bsp. \(15 \cdot 15 = 225\)\(2\cdot 4\,\text{Bit} = 8\,\text{Bit}\)
  • Implementierung einer Multiplikation mit Assembler-Sprache: langsamer Programmablauf
  • Manche MCU und DSP haben daher einen Hardware-Multiplizierer eingebaut
    z. B. Aufbau eines 4-bit Multiplizierer
    alt: "Aufbau 4-bit Mulitplizierer", src: "http://holzers-familie.de/", w: 50
  • Hardware-Multiplizierer des MSP430 (eingebaut in manchen MSP430 der x2xx-Familie)
    alt: "MSP430 Hardware Multiplier", src: "Family Guide S. 350", w:75
    • Verschiedene Operationen sind möglich:
      • Unsigned / Signed Multiply
      • Multiply / Multiply Accumulate
      • 8bit oder 16bit Operatoren
    • Operatoren werden in den entsprechenden Speicherzellen geladen
    • Das Ergebnis ist innerhalb eines CPU-Taktes in den Ergebnis-Speicherzellen verfügbar und kann weiterverarbeitet werden
  • Beim DSP auch MAC-Einheit genannt

Programmierung von Verzögerungen

Programmieren von Verzögerungen - Erste Idee

uint16_t u_speicher[4] = {0, 0, 0, 0};

uint16_t filter(uint16_t u) {
  u_speicher[3] = u_speicher[2];
  u_speicher[2] = u_speicher[1];
  u_speicher[1] = u_speicher[0];
  u_speicher[0] = u;

  uint16_t y = 0;
  y += 0.25 * u_speicher[0];
  y += 0.25 * u_speicher[1];
  y += 0.25 * u_speicher[2];
  y += 0.25 * u_speicher[3];

  return y;
}

  • Problem: Werte des Datenspeichers müssen immer "weitergerückt" werden
    → erhöhte CPU-Laufzeit
  • Verwenden eines Ringspeichers
    alt: "Symbolisierung eines Ringspeichers", src: "https://www.delphientwickler.de", w:25

Programmieren von Verzögerungen - mit Ringspeicher

uint16_t u_speicher[4] = {0, 0, 0, 0};

uint16_t filter2(uint16_t u, uint16_t k) {
  u_speicher[k & 0b11] = u;

  uint16_t y = 0;
  for (uint8_t i = 0; i<4; i++) {
    y += 0.25 * u_speicher[i];
  }

  return y;
}

  • Verkettete Verzögerungen von Signalen immer als Ringspeicher implementieren!
  • Ringspeicher mit vielen Elementen möglich
  • Vereinfachen der Programmierung bei Verwendung einer Zweierpotenz als Größe des Ringspeichers (32, 64, 128, 256, ...)
    • Vereinfacher Modulo-Operator
    • Division durch Bitverschiebung bei gleichgewichteten Filter → auch ohne MAC-Einheit schnelle Laufzeit!
  • Downsampling einer digitalen Signales mit Hilfe eines Ringspeichers
  • Erzeugen eines Hall-Effektes mit circa 40000 Verzögerungselementen

Weitere Besonderheiten eines DSP

  • Mehrere Bussysteme gleichezeitig aufrufbar
  • Hardwaregesteuerte Schleifen: Befehle 50mal ausführen, kein Softwarezähler nötig
  • Shifter: Umwandeln von 32bit in 16bit Ergebnissen
  • Begrenzer: verhindert Überlauf von Ergebnissen
  • Round to nearest:
    • MSP430 schneidet Ergebnisse beim Runden immer ab → Ergebnisse werden immer kleiner
    • DSP können automatisch Ergebnisse mathematisch runden → <0.5 abrunden, >0.5 aufrunden

Sprungvorhersage

  • CPU benötigt mehrere Schritte zum Ausführen eines CPU-Befehls:
    • FETCH: Befehl aus den Speicher auslesen
    • DECODE: Befehl wird durch Steuerwerk dekodiert
    • READ: Operanden werden aus den Speicher geholt
    • EXECUTE: Befehl wird ausgeführt
    • WRITE BACK: Schreiben des Resultats
  • Pipelining: 5 Schritte werden für die vermutlich nächsten fünf Befehle ausgeführt
  • Problem: Durch Sprungbefehle können nächsten fünf Befehl meist nicht bestimmt werden
    Sprungvorhersage (engl. branch prediction)
  • Verfolgen von unbedingten Sprüngen (JMP, CALL, RETURN)
  • Compiler kündigen Schleifen auf eine bestimmte Art an, die vom Prozessor dann erkannt wird
  • 95% Genauigkeit der Sprungvorhersage ist erreichbar

Beispiel für die Sprungvorhersage beim Lesen von Datensätzen verschiedener Größe und Reihenfolge:
alt: "Prefetcher Graph", src: "https://www.youtube.com/watch?v=TJHgp1ugKGM", w: 50

Gleitkommazahlen

  • engl. floating point number → C: float
  • Idee: Abspeichern einer Zahl in Exponentialdarstellung
    z. B. \(172{,}625 = 1{,}72625 \cdot 10^2\)
  • Verwenden der Darstellung mit Basis 2
  • Aufbau des Datentypes float
    alt: "Aufbau float", src: "http://www.c-jump.com/", w: 50
  • Deutlich erhöhter Wertebereich: \(\pm 1.18\cdot 10^{-38} ... \pm 3.4\cdot 10^{38}\)
  • Achtung! Diskretisierungsabstand ist nicht konstant:
    alt: "Genauigkeit von Gleitkommazahlen", src: "Wikipedia Commons", w: 50
  • Weitere Beispiele:
    0b0 11111111 00000000000000000000000 = 0x7f80 0000 = infinity
    0b1 11111111 00000000000000000000000 = 0xff80 0000 = −infinity
    
    0b0 10000000 10010010000111111011011 = 0x4049 0fdb ≈ 3.14159274101 ≈ π ( pi )
    0b0 01111101 01010101010101010101011 = 0x3eaa aaab ≈ 0.333333343267 ≈ 1/3
    
  • Verwendung von Gleitkommazahlen in einen DSP benötigt zwingend eine FPU (floating point unit)
  • Verwendung des Datentyps float beim MSP430 bedeutet, dass eine Bibliothek verwendet wird, die die Gleitkommazahlen in den MSP430 implementiert.
    → Für Addition und Multiplikation werden viele Taktzyklen benötigt!!!