Tiny3216 Zweikanal-Oszilloskop         


Elektronik-Labor   Projekte   AVR


TinyAVR Serie 0 und 1 im Einsatz Kap 5

Dieses einfache Oszilloskop verwendet den Seriellen Plotter der Arduino-IDE als Bildschirm. Über den ADC0 werden die Eingänge AIN7 und AIN8 angefragt und die Daten über die serielle Schnittstelle an den PC gesandt. Entsprechend der Breite des Plotters werden jeweils 500 Messungen dargestellt. Das Programm verwendet eine Zählschleife, in der die beiden AD-Messungen ausgeführt werden und die Daten aufbereitet und gesendet werden. Um eine möglichst hohe Abtastrate zu erreichen, wurden folgende Parameter optimiert:

Die Taktfrequenz wurde auf 20 MHz eingestellt. Der Takt für den AD-Wandler verwendet einen Vorteiler durch 8, was eine Taktrate von 2,5 MHz ergibt. Laut Datenblatt ist bei der vollen Auflösung von 10 Bit eine maximale Taktrate von 1,5 MHz möglich. Hier wird jedoch eine Auflösung von nur 8 Bit verwendet, was mit 2,5 MHz noch gut funktioniert. Bei noch höherer Taktrate versagt der AD-Wandler und liefert nur noch 255-Werte. Die serielle Schnittstelle wurde auf eine hohe Übertragungsrate von 500.000 Baud eingestellt. Die doppelte Baudrate von 1 MBaud ist zwar auch möglich, hat aber im Test zu vereinzelten Übertragungsfehlern geführt.


//Scope2ch3216
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#include <stdlib.h>
#include <util/delay.h>
#include <string.h>
#define F_CPU 20000000
#define USART0_BAUD_RATE(BAUD_RATE) ((float)(F_CPU * 64 /(16 * (float)BAUD_RATE)) + 0.5)

 void USART0_init(void){
    PORTB.DIRSET = 0x04;    //TXD an PB2
    PORTA.DIRCLR = 0x08;    //RXD an PB3
    USART0.BAUD = (uint16_t)USART0_BAUD_RATE(500000);
    USART0.CTRLB |= USART_TXEN_bm;

void USART0_sendChar(char c){
    while (!(USART0.STATUS & USART_DREIF_bm));
    USART0.TXDATAL = c;
}

void USART0_sendString(char *str){
    for(size_t i = 0; i < strlen(str); i++){
        USART0_sendChar(str[i]);
    }
}

int main(void) {
    _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB, 0); // 20 MHz
    VREF.CTRLA = VREF_ADC0REFSEL_2V5_gc;
    ADC0.CTRLA = ADC_ENABLE_bm | ADC_RESSEL_8BIT_gc;
    ADC0.CTRLC = ADC_PRESC_DIV8_gc;  //max. ADC-Takt
    char buffer[6];
    USART0_init();
    while (1) {
        for (uint16_t i=0; i<500;i++){
            ADC0.MUXPOS  = ADC_MUXPOS_AIN7_gc;
            ADC0.COMMAND = ADC_STCONV_bm;
            while (!(ADC0.INTFLAGS & ADC_RESRDY_bm));
            uint8_t result1 = ADC0.RES;
            ADC0.MUXPOS  = ADC_MUXPOS_AIN8_gc;
            ADC0.COMMAND = ADC_STCONV_bm;
            while (!(ADC0.INTFLAGS & ADC_RESRDY_bm));
            uint8_t result2 = ADC0.RES;
            itoa(result1,buffer,10);
            USART0_sendString(buffer);
            itoa(result2,buffer,10);
           
USART0_sendChar(9); //TAB
            USART0_sendString(buffer);
           
USART0_sendString("  \r\n");
        }
        _delay_ms(1000);
   
}
}

 
Für die Übertragung an den Arduino-Plotter wird das folgende Protokoll benötigt: Messwert1, TAB, Messwert2, Zeilenende. Der Plotter erkennt dann die beiden Kanäle und stellt sie mit unterschiedlichen Farben dar. Die Messungen, die Übertragung mit 500 kBaud und die Darstellung auf dem Bildschirm dauern nur rund 100 ms. Das Bild bleibt dann eine Sekunde lang bis zur nächsten Messung stehen. Die Messungen kann man auch im Seriellen Monitor ansehen. 

Das Oszillogramm zeigt zwei 50-Hz-Signale, eines aus dem Netz, das andere aus einem analogen Sinusgenerator, der nach seiner Skala auf 50 Hz eingestellt wurde. Man erkennt, dass die Frequenzen recht gut übereinstimmen, wobei keine feste Phasenbeziehung besteht.

 

 

Die Abtastrate liegt nur bei rund 5 kHz. Für noch schnellere Messungen muss man die AD-Abtastung und die Datenübertragung trennen, was weiter unten demonstriert wird.  Aber für viele Aufgaben ist auch dieses langsame Oszilloskop bereits brauchbar. 






Taschenbuch: https://www.amazon.de/dp/B0D5798R53

E-Book: https://www.amazon.de/dp/B0D54Q9D7L
 


Elektronik-Labor   Projekte   AVR