PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ungleichmäßge Pulslängen bei PWM mit TIMER1 auf mega8



The Man
16.10.2009, 14:40
Hallo da,

ich habe im Mega8 den Timer 1 so aufgesetzt, dass ich über Pin OC1A ein PWM bekomme.
Hier die Bitmuster:


TCCR1A |= (1<<COM1A1)|(1<<WGM11);
TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
ICR1 = 1500;
OCR1A = 250;


Aus irgendeinem Grund erhalte ich ungleichmäßige Pulslängen. Sie Attechment.
Hat jemand eine Idee, woran das liegt?
Hab das auch schon auf zwei Controlern getestet.

mfg,
The Man

lowtzow
17.10.2009, 07:41
so funkts bei mir - zum testen
mfg





#define OC1A_PIN PB1 // OC1A pin (ATmega8 use PB1)
#define OC1A_DDR DDRB // OC1A DDR (ATmega8 use DDRB)



int main(void)
{
uint8_t i = 0;

// set OC1A pin as output, required for output toggling
OC1A_DDR |= (1<<OC1A_PIN);


// enable 8 bit PWM, select inverted PWM
TCCR1A = (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0);

// timer1 running on 1/8MCU clock with clear timer/counter1 on Compare Match
// PWM frequency will be MCU clock / 8 / 510, e.g. with 8Mhz Crystal 1960 Hz.
TCCR1B = (1<<CS11) | (1<<CS10);


/*
* Dimm LED on and off in interval of 2.5 seconds
*/
for (;;)
{
/* dimm LED on */
for (i=0; i<255; i++)
{
OCR1AL = i;
_delay_ms(40); // delay 10 ms
}

/* dimm LED off */
for( i=255; i>0; i--)
{
OCR1AL = i;
_delay_ms(40); // delay 10 ms
}
}
}

yaro
17.10.2009, 12:46
Vieleicht ist es ja ein Hardware-Problem, vieleicht resettet er ab und zu wegen irgendwelchen äußeren Einwirkungen.
Um das zu testen, mach ein Delay vor dem Starten des PWM rein.

Gruß, Yaro

The Man
17.10.2009, 14:33
An den Resetpin hab ich nen Pullup gelötet und das ganze noch mal getestet.
Ich hab mal mit nem Oszi gemessen und an der Zeitbasis gedreht.
Im Attechment ist das Bild dazu. ich hoffe es ist nicht zu dunkel.
Das sieht nach nem systematischen Problem aus. Habe auch mal den Vorteiler des Timer erhöht aber das ist das gleiche in langsam.
Und wie gesagt, das Problem ist auf mehr als einem Controler.

yaro
17.10.2009, 16:19
Versuch mal mit ICR1 = 10000; OCR1A = 5000; und zeig mal, was dabei rauskommt.

Gruß, Yaro

The Man
17.10.2009, 16:39
getan
=> Quotenbuchstaben<=

The Man
17.10.2009, 16:43
getan
=> Quotenbuchstaben<=

yaro
17.10.2009, 18:26
Woher kommen diese Peaks, die dort in Regelmäßigen Abständen auftreten? (ich meine diese vertikalen Striche, die während einer High oder Low-Zeit 3-4 mal auftreten) oder ist das nur soeine Messskala, die man einblenden kann?

Auf jeden Fall tritt hier nicht dieses Problem auf, dass ab und zu ein Puls doppelt kommt, so wie es beim ersten Mal der Fall war.

Ich habe leider im Moment kein Oszi hier, erst nächste oder übernächste Woche, kann es also erst später bei mir simulieren .

Wahrscheinlich hab ich nächste Woche ein Oszi, kann dir dann besser helfen, denn so dauert das zu lange, wenn man immer für ne Messung fragen muss =)

Hast du sonst noch irgendwelchen Code, den du gerade auf dem AVR hast, oder machst du nur PWM?

Gruß, Yaro

The Man
17.10.2009, 18:36
Auf dem AVR ist wirklich nur der Code, um PWM zu machen.
Und die erste und zweite Messung ist die selbe. Nur einmal mit nem Digital Analyzer und einmal mit nem Oszi.
Und es macht auch keinen Unterschied, ob ich das PWM von der Hardware machen lasse oder im Interrupt den Pin toggle.
Weiterhin ist mir aufgefallen, wenn ich an dem Run/Stop Kopf spiele, ist diese "Störfrequenz" weg. Also wenn ich die Aufnahme anhalte.



#include <avr/io.h>
#include <avr/interrupt.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
"nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 3686400 definiert"
#define F_CPU 16000000UL /* Quarz mit 3.6864 Mhz */
#endif
#include <util/delay.h>

volatile int command_h = 0;
volatile int command_l = 0;
volatile int mhh = 0;
volatile int mhl = 0;
volatile int mlh = 0;
volatile int mll = 0;
volatile int tmp_shift = 0;
volatile int puls_counter = 0;
volatile int shift_counter = 0;
volatile int byte_counter;
volatile int ubertrgung_aktiv = 0;
volatile int halb_bit_counter = 0;
volatile int command [4];
volatile int command_num = 0;
volatile int bit = 0;


SIGNAL(TIMER1_COMPA_vect){// TIMER2_COMP_vect
static int tmp = 0;



if (tmp == 0) tmp = 2;
else tmp = 0;
PORTB = tmp;
}

int main (void)
{
int n = 0;
TCCR1A |= (0<<COM1A1)|(1<<WGM11);
TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
ICR1 = 1000;
OCR1A = 500;

DDRB |= 0b00001111;


TIMSK = 0b00010000;
main2:
sei();
cli();
_delay_ms(100);
goto main2;
return 0;
}

avion23
17.10.2009, 19:04
Kann es nicht sein, dass dein Oszi die Fehlerquelle ist?