TestLab für den Arduino Nano
Elektronik-Labor
Projekte
Mikrocontroller PicoBasic
Das TestLab wird wieder über das PicoBasic für den Nano
gestartet, sodass man zuerst ein zur Aufgabe passendes Programm laden
kann. Hier wurde das DDS-Programm gestartet und mit einer
Rechteckfunktion geladen. Das PWM-Signal wurde auf die höchste
Ausgabefrequenz von 31 kHz eingestellt und über ein Tiefpassfilter mit
1 k und 22 µF an AD0 gelegt. Dann wurde das TestLab-Oszilloskop an
AD0 mit 0,2 s/div gestartet. Das Messergebnis zeigt die typischen
Lade- und Entladekurven eines RC-Filters. Ein Vergleich zeigte, dass
die kleinste PWM-Frequenz von 30 Hz zum gleichen Ergebnis führt, weil
die Grenzfrequenz des RC-Glieds mit 7,2 Hz immer noch weit genug unter
der PWM-Frequenz liegt.
Wenn man die PWM-Ausgänge eines Arduino Nano programmiert, liegt
die Frequenz normalerweise bei 490 Hz. Um flexibel zu bleiben und aus
Timing-Gründen musste alles in reinem C geschrieben werden.
Insbesondere wollte ich ganz ohne Interrupts auskommen und musste daher
auf alle Arduino-typischen Konstrukte verzichten, die sonst ganz still
und heimlich im Hintergrund mit void setup() und void loop()
eingerichtet werden. Das Hauptprogramm liegt deshalb jetzt in int
main(void), wie ich es auch im Arduino Messlabor gemacht habe. Hier werden der USART und die drei Timer initialisiert.
int main(void){
...
UBRR0H = 0; //USART
UBRR0L = 0; //1: 500kBaud, 0: 1 MBaud
UCSR0B = 0x18; //TX, RX an
UCSR0C = 0x06; //8N1
ADMUX = 0x60; //Ref = VCC, Left adjusted
ADCSRA = 0xC2; //1. Start, 4 MHz
while((ADCSRA & 0x40));
TCCR1A = 0x21; //PWM, Phase Correct, 8-bit
TCCR1B = 3;
OCR1BL = 0;
TCCR2A = 0x81; //PWM, Phase Correct, 8-bit
TCCR2B = 4;
OCR2A = 0;
DDRB = 0x0C; //PWM outputs
TCCR0A = 0x02; // CTC-Modus
OCR0A = 249; //1 ms
TCCR0B = 3; //16MHz /64 = 250 kHz
TCNT0 = 0;
Wegen der Anordnung der Ausgänge musste ich zwei verschiedene
Timer, Timer1 und Timer2 für die PWM-Ausgänge verwenden. Timer 0
läuft als Zeitgeber im Hintergrund mit Überläufen im Millisekundentakt.
Die Funktionen für die PWM-Ausgänge im TestLab steuern nun ebenfalls
direkt die Register der Mega328 an.
void d79(){uint16_t n = USART_readInt();OCR1BL= n;} //O PWM1
void d80(){uint16_t n = USART_readInt();OCR2A = n;} //P PWM2
...
void
d86(){
//V PWM-Freq
uint16_t n = USART_readInt();
if (n==4) {TCCR2B=1;TCCR1B=1;} //Prescaler 1
if (n==3) {TCCR2B=2;TCCR1B=2;} //Prescaler 8
if (n==2) {TCCR2B=4;TCCR1B=3;} //Prescaler 64
if (n==1) {TCCR2B=6;TCCR1B=4;} //Prescaler 256
if (n==0) {TCCR2B=7;TCCR1B=5;} //Prescaler 1014
}
Gegenüber dem Rpi Pico hat der Nano den Vorteil, dass man die
Referenz für den AD-Wandler umschalten kann. Es gibt hier drei
Einstellungen: 1,1V, Extern und VDD. Wie beim Tiny3216 gibt es auch
hier einen zusätzlichen Schiebeschalter dafür. Die Variable Uref legt
die Registereinstellung fest und wird in der Funktion uint8_t
adc(uint8_t ch) wirksam.
void
d87(){
//W ADC Ref
uint16_t n = USART_readInt();
if (n==0) {uref=0xE0;} //Ref 1.1 V
if (n==1) {uref=0x20;} //Ref ext
if (n==2) {uref=0x60;} //Ref 5 V
}
uint8_t adc(uint8_t ch){
ADMUX = uref+ch;
ADCSRA = 0xC2; //1. Start, 4 MHz
while((ADCSRA & 0x40));
return ADCH;
}
Die Einstellung Extern macht es möglich, eine beliebige Referenz am
Eingang REF anzuschließen. Eine Verbindung nach 3V3, am besten über
einen Schutzwiderstand von 100 Ohm, ergibt einen Messbereich bis 3,3 V.
Und man kann sogar mit variablen Referenzen arbeiten, und z.B. die
Spannungen zweier Dioden vergleichen. Eine mit einem größeren Strom
dient als Referenz und eine mit weniger Strom liegt am ADC. Damit
lassen sich Temperatur-Differenzmessungen durchführen. Oder man könnte
mit einem PWM-Ausgang ein Referenzsignal erzeugen, das dann frei
veränderlich ist.
Elektronik-Labor
Projekte
Mikrocontroller
PicoBasic