Forum: Mikrocontroller und Digitale Elektronik Arduino Leonardo Timer 3 Probleme


von Michael K. (Firma: privat) (ban)


Lesenswert?

Hallo zusammen,

ich habe das Problem, dass ich mit dem 16-Bit Timer 3 vom Arduino 
Leonardo keine PWM erzeugen kann.
Ich bin folgendermaßen vorgegangen:

Ich habe einen Code für den ATmega32U4 mit Atmel Studio erstellt:
1
// include statements
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
int main(void)
6
{
7
      
8
      cli(); // disable global interrupts
9
    
10
      // init output pins
11
      DDRC |= (1<<DDC6); // PC6 as output / OC3A as output / D5 as output // OC3A als PWM-Pin / Timer/Counter1
12
      DDRC |= (1<<DDC7); // onboard LED - Arduino Pin 13
13
    
14
      //PRR1 |= 1<<PRUSB; // disable usb
15
16
      TCCR3A |= (1<<COM3A0); // Toggle OC3A on compare match
17
      TCCR3B |= (1<<WGM32); // turn on CTC-Mode // Mode 4: CTC-Mode mit OCR3A als TOP
18
      TCCR3B |= (1<<CS31); // Pre-Scaler N=8
19
      TIMSK3 |= (1<<OCIE3A); // Output Compare A Match Interrupt Enable
20
21
      // set 25 Hz -- OCR3A --> 39.999
22
      OCR3A = 60000;
23
24
      sei(); // enable global interrupts
25
26
    while (1) 
27
    {
28
    }
29
}
30
31
ISR(TIMER3_COMPA_vect)
32
{
33
  PINC |= (1<<PINC7);
34
}

Wenn ich diesen Code mit dem ARVISP mkII Programmer ( 
http://www.atmel.com/tools/avrispmkii.aspx ) auf den Arduino Leonardo 
flashe (über die ISP-Schnittstelle auf dem Arduino), funktioniert die 
PWM wunderbar.

Um danach den Bootloader wiederherzustellen, nutze ich einen Arduino UNO 
und die Anleitung auf dieser Seite:
https://learn.sparkfun.com/tutorials/installing-an-arduino-bootloader

Danach kann ich den Arduino Leonardo wieder mit der Arduino IDE normal 
benutzen. Meine Idee war, dass ich jetzt den Code aus dem Atmel Studio 
in die Arduino IDE kopiere und den Timer dann von dort aus installiere. 
Dass ich die Arduino IDE wieder benutzen möchte, hat den Hintergrund, 
dass ich hier einfach auch die USB-Schnittstelle für UART-Kommunikation 
zum PC nutzen kann. Ich möchte später auch andere Code-Teile nutzen, die 
mit Arduino-Bibliotheken erstellt wurden.

Hier der Arduino-IDE-Code:
1
// include statements
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
void setup() {
6
  // put your setup code here, to run once:
7
     cli(); // disable global interrupts
8
    
9
      // init output pins
10
      DDRC |= (1<<DDC6); // PC6 as output / OC3A as output / D5 as output // OC3A als PWM-Pin / Timer/Counter1
11
      DDRC |= (1<<DDC7); // onboard LED - Arduino Pin 13
12
    
13
      //PRR1 |= 1<<PRUSB; // disable usb
14
15
      TCCR3A |= (1<<COM3A0); // Toggle OC3A on compare match
16
      TCCR3B |= (1<<WGM32); // turn on CTC-Mode // Mode 4: CTC-Mode mit OCR3A als TOP
17
      TCCR3B |= (1<<CS31); // Pre-Scaler N=8
18
      TIMSK3 |= (1<<OCIE3A); // Output Compare A Match Interrupt Enable
19
20
      // set 25 Hz -- OCR3A --> 39.999
21
      OCR3A = 60000;
22
23
      sei(); // enable global inte
24
}
25
26
void loop() {
27
  // put your main code here, to run repeatedly:
28
29
}
30
31
ISR(TIMER3_COMPA_vect)
32
{
33
  PINC |= (1<<PINC7);
34
}

Diesen Code kann ich hochladen, sodass die Meldung "Hochladen 
abgeschlossen" erscheint, allerdings wird der Timer nicht gestartet, die 
Debug-LED blinkt nicht und insgesamt passiert einfach nichts. Auch das 
Auskommentieren von sei und cli hilft nicht.

Meine Fragen sind nun, woran das liegt, und vielleicht noch wichtiger, 
wie ich das Problem beheben kann.

Schonmal vielen Dank für die Antworten !!

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Verstehe ich Dich recht, daß der Timer3 nicht mehr funktioniert, nachdem 
Du den Bootloader wieder aufgespielt hast?
Wenn Ja, könnte ich mir vorstellen, daß Dieser wohl den Timer3 für sich 
benutzt und die ISR auf eine eigene Routine 'zurecht gebogen' habt.

Deine ISR also als unbenutzter Programmcode zurück bleibt.

MfG

von Michael K. (Firma: privat) (ban)


Lesenswert?

Danke für die Antwort. Sowas in der Richtung habe ich mir auch gedacht. 
Ich fürchte, es wird in diesem Fall keine einfache Möglichkeit geben, 
den Bootloader anzupassen oder den Timer freizugeben. Ich werde also 
entweder andere Timer ausprobieren oder einen FTDI-Chip nehmen.

von Philipp K. (philipp_k59)


Lesenswert?

manchmal initialisiert Arduino die Timer und andere Register für interne 
Funktionen vorweg..

Abhilfe vor die eigene initialisierung:

TCCR3A =0;
TCCR3B =0;
TIMSK3 =0;

: Bearbeitet durch User
von Michael K. (Firma: privat) (ban)


Lesenswert?

Sehr gute Idee!!

Denn: so hat es funktioniert.

Bleibt zu hoffen, dass die eigene Nutzung des Timers den Controller 
nicht der Nutzung anderer Funktionen/Funktionalitäten beraubt.

Danke !!

von Philipp K. (philipp_k59)


Angehängte Dateien:

Lesenswert?

Michael K. schrieb:
> Bleibt zu hoffen, dass die eigene Nutzung des Timers den Controller
> nicht der Nutzung anderer Funktionen/Funktionalitäten beraubt.

Kann man einfach das Core durchsuchen so sieht man das vor dem Setup 
Timer 3 auf 8 Bit, prescaler 64 gestellt wird
1
#if defined(TCCR3B) && defined(CS31) && defined(WGM30)
2
  sbi(TCCR3B, CS31);    // set timer 3 prescale factor to 64
3
  sbi(TCCR3B, CS30);
4
  sbi(TCCR3A, WGM30);    // put timer 3 in 8-bit phase correct pwm mode
5
#endif

sowie in der Datei "wiring_analog.c" für den analogWrite() DutyCycle 
verwendet wird.

Damit funktioniert analogwrite dann nicht mehr auf den Pins die über 
Timer3 verwaltet werden oder man bessert es selbst aus.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.