2017-06-06 2 views
0

Ich versuche, PWM-Ausgang von PB7 Pin mit Timer0 auf Atmega2560 ohne Glück bekommen. Es sollte Ton für die angeschlossenen repro.My PWM-Einstellungen erzeugen sind:Atmega2560 PWM auf PB7

DDRB = 0b11100000; 
PORTB = 0b00000000; 

OCR0A = 0x04; 
TCCR0A = (0 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (0 << WGM00); 
TCCR0B = (0 << WGM02) | (0 << CS02) | (0 << CS01) | (0 << CS00); 

und dann habe ich diese Funktion, die den Klang erzeugen soll:

void SoundOutput(unsigned int uintTone) 
{ 
    if (uintTone != 0) 
    { 
     LED_2(1); 
     OCR0A = uintTone; 

     TCCR0B |= (1 << CS02) | (1 << CS01) | (1 << CS00); 
    } 
    else 
    { 
     TCCR0B &= ~((1 << CS02) | (1 << CS01) | (1 << CS00)); 
    } 
} 

aber es passiert nichts, wenn ich es mit Ton nennen Parameter. Kannst du mir bitte helfen?

+1

Ich denke, es ist diese Zeile, die die Quelle festlegen: 'TCCR0B | = (1 << CS02) | (1 << CS01) | (1 << CS00); '. Wenn alle drei gesetzt sind, bedeutet dies: ** Externe Taktquelle an T0-Pin. Uhr an steigender Flanke **. Wenn Sie keine externe Clock-Quelle auf ** T0 ** haben, stellen Sie einfach 'CS00' ein, um zum Beispiel die CPU-Frequenz als Quelle ohne Prescaler zu erhalten. –

+0

Das funktioniert, habe ich jetzt am PB7 ausgegeben, aber die Frequenz ist jetzt zu hoch. Wenn ich SoundOutput (400) anrufe, kann ich eine O-Scope-Periode von 12.5us sehen, die für die Tonerzeugung zu hoch ist. –

+0

Ja, weil die CPU-Frequenz des 2560 16 MHz beträgt. Die Dauer Ihres Tonsignals ist also: "t = (1/f_CPU) * uintTone/2". Soll der Parameter 'uintTone' die resultierende Frequenz sein? Ich werde es später veröffentlichen, da ich Zeit als Antwort habe. –

Antwort

1

Basierend auf Ihren Kommentaren, verwenden Sie ~ 12MHz Uhr als Eingang für Ihren Timer, und von Ihrem Code, verwenden Sie 8-Bit-Timer 0 im CTC-Modus mit OCR0A als Ihr Top. Sie haben OC0A gesetzt, um bei einer Vergleichsübereinstimmung zu schalten.

Nach der 2560 Datenblatt wird die Frequenz Ihrer Timer gegeben durch:

F_CLK/(2 * (1 + OCR0A)) | F_CLK ~ = 12MHz

Dies ist ein 8-Bit-Zeitgeber, so dass bedeutet, dass die Mindestfrequenz, die Ihre PWM durch gegeben erzeugen:

12e6/(2 * (1 + 255)) ~ = 20KHz

Sie können mit dieser Konfiguration einfach keinen Signalton erzeugen, es sei denn, Sie verlangsamen die Uhr, die Sie für Ihren Timer verwenden oder verwenden einen Timer, der höher zählen kann.

1) Verwenden Sie einen 16-Bit-Zähler (d. H. Timer1). Das wird Ihnen eine Mindestfrequenz von ~ 90Hz geben und eine maximale Frequenz von ~ 6 MHz, die Ihnen viel Bereich geben sollte Töne erzeugen:

/* WGM BITS = 0100: CTC Mode */ 
/* COMA BITS = 01: Toggle OC1A on compare match */ 
/* CS BITS = 111: External clock source on rising edge */ 

TCCR1A = (0 << COM1A1) | (1 << COM1A0) | (0 << WGM01) | (0 << WGM00); 
TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS02) | (1 << CS01) | (1 << CS00); 

2) Verwenden Sie die interne Taktquelle als Zeituhr anstelle eines externe Quelle. Wenn Sie die Sicherungsbits nicht geändert haben oder Sie sie irgendwo im Code ändern, beträgt die Taktfrequenz 1 MHz. Das Vorskalieren der Uhr um 8 ergibt einen Frequenzbereich von ~ 250 Hz - ~ 60 kHz.

/* WGM BITS = 010: CTC Mode */ 
/* COMA BITS = 01: Toggle OC1A on compare match */ 
/* CS BITS = 010: Prescale the internal clock by 8 */ 

TCCR0A = (0 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (0 << WGM00); 
TCCR0B = (0 << WGM02) | (0 << CS02) | (1 << CS01) | (0 << CS00); 
+0

Ja! Ich habe die zweite Lösung verwendet und es funktioniert großartig. Vielen Dank :) –

+0

Kein Problem: Hier ist ein Link zu mehr Referenzinformationen zur Verwendung eines PWM: http://allaboutavr.com/index.php/2017/05/13/chapter-5-timers- und-pwm-pulse-width-modulation/ – rlphillipsiii

+0

Nun, meine Freude war ein wenig vorläufig. Ich kann jetzt Ton erzeugen, aber die Frequenzen sind ungerade. Ich muss genaue Frequenzen aus dem Lautsprecher ausgeben, aber ich kann (gemessen mit Agilent Frequenzzähler) Frequenzen im Bereich von 230KHz ('OCR0A = 2') und 2.69 KHz (' OCR0A = 255') und 0Hz mit 'ausgeben OCR0A = 0' oder 'OCR0A = 1' –

Verwandte Themen