PMW mit Atmega 32

Gast #3862123
Lesenswert?

Moin,
ich möchte 2 PWM´s mit dem Atmega 32 Programmieren, deren Frequenz so 
niedrig ist (2Hz), dass man LED´s sichtbar zum blinken bringen kann. Nur 
leider blinkt keine der 3 angeschlossenen LED´s. Die an PD0 glimmt, die 
an PD4 und PD5 sind aus. Weiß jmd weiter?
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <avr/interrupt.h>
4
#include <stdio.h>
5
#define F_CPU 8000000
6

7
int main(void)
8
{
9
DDRD = 0xff;
10
ICR1 = 4000000;    //8MHz/4M = 2Hz
11
OCR1A =  2000000;  //Duty-Cycle 0,5  
12
OCR1B = 1000000;  //Duty-Cycle 0,25
13
TCCR1A = (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
14
TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10);
15
TIMSK = (1<<OCIE1A)|(1<<OCIE1B)|(1<<TOIE1);
16

17
sei();                      
18
while(1)
19
{
20
}
21
}
22
ISR(TIMER1_OVF_vect)
23
{
24
  PORTD ^= (1<<PD0);
25
}
26
ISR(TIMER1_COMPA_vect)
27
{
28
  PORTD ^= (1<<PD5);      
29
}
30
ISR(TIMER1_COMPB_vect)          
31
{
32
  PORTD ^= (1<<PD4);          
33
}
Gast #3862134
Lesenswert?

ICR1 ist 16bit groß, da passen keine 4 Millionen rein. Was nachher 
tatsächlich in dem Register steht weiss ich nicht, aber vermutlich nix 
sinnvolles.
2 Hz ist in Software vermutlich sinnvoller zu machen (ich glaube, das 
ist ein Lernprojekt und nichts zeitkritisches, nicht?) aber mit dem 
Timer1 ginge es so:

- PWM Modus 8 (Datenblatt Seite 109)
- ICR1 auf 65536 (=16bit)
- Prescaler auf 1024 (Seite 110)

Macht dann 8Mhz/1024/65536/2 (wegen dual slope)= 0,059Hz. Das müsste 
langsam genug sein.
Kannst auch Modus 14 nehmen, Fast PWM mit ICR1 als TOP, dann entfällt 
das "/2" in der Gleichung.
Gast #3862618
Lesenswert?

Zu früh gefreut, so richtig funktioniert es doch noch nicht. Ich habe 
den Code verändert aber es blinkt nur PD4, warum?
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <avr/interrupt.h>
4
#include <stdio.h>
5

6
int main(void)
7
{
8
DDRD = 0xff;
9
ICR1 = 64000;    
10
OCR1A =  32000;    
11
OCR1B = 16000;  
12
TCCR1A = (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
13
TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10)|(1<<CS11);
14
TIMSK = (1<<OCIE1A)|(1<<OCIE1B)|(1<<TOIE1);
15

16
sei();                      
17
while(1)
18
{
19
}
20
}
21
ISR(TIMER1_OVF_vect)
22
{
23
  PORTD ^= (1<<PD0);
24
}
25
ISR(TIMER1_COMPA_vect)
26
{
27
  PORTD ^= (1<<PD5);    
28
}
29
ISR(TIMER1_COMPB_vect)          
30
{
31
  PORTD ^= (1<<PD4);  
32
}
Gast #3862777
Lesenswert?

D.h. die Software ist soweit korrekt? Die Led´s sind nicht defekt, schon 
getestet. Muss ich überhaupt PORTD ^= (1<<PD4) schreiben? Oder toggelt 
PD4 automatisch, da PD4 dem OC1B entspricht und dieser bei Bottom bzw 
Compare match seinen Status automatisch ändert?
Gast #3863270
Lesenswert?

Guest schrieb:

> D.h. die Software ist soweit korrekt?

Nein, nicht in dem Sinne, daß sie tun würde, was du haben willst. Aber 
die LEDs sollten immerhin alle drei blinken Und zwar so:

PD0: 1:1 Tastverhältnis, ~0,98Hz
PD4: ~1:3 Tastverhältnis, ~1,95Hz
PD5: ~1:2 Tastverhältnis, ~1,95Hz

Tun sie das nicht, stimmt irgendwas an der Hardware nicht. Oder das 
Programm, was du gepostet hast ist nicht identisch mit dem Programm, was 
tatsächlich auf dem µC läuft.

Übrigens: die beiden COMPx-ISRs sind völlig nutzlos und verbrauchen nur 
Rechenzeit, ohne irgendwas zu bewirken. Abgesehen von dem sinnlosen 
Rechenzeitverbrauch schaden sie allerdings auch nicht weiter.

Ich würde mal darauf tippen, daß dein Hardware-Werk so dermaßen Scheiße 
ist, daß sich der µC in den Reset verabschiedet, sobald irgendwelche 
LEDs plötzlich Strom verbrauchen. Dann wacht er wieder auf, um erneut 
abzustürzen, sobald die erste LED leuchtet.

Also vermutlich hat da mal wieder so ein Ober-Checker kraft seiner 
Wassersuppe auf Stützkondensatoren und/oder auf LED-Vorwiderstände 
verzichtet, obwohl alle Erwachsenen sagen, daß man sowas tatsächlich 
braucht...
(Firma: matzetronics) #3863319
Lesenswert?

c-hater schrieb:
> Abgesehen von dem sinnlosen
> Rechenzeitverbrauch schaden sie allerdings auch nicht weiter.

Da bin ich mir nicht so sicher, da der TE genau an den Pins rumfummelt, 
die die Hardware OC Register selbst bearbeiten.
Das macht der Mega von ganz alleine, nur die Pins auf Output stellen und 
die Polarität der Pins mit dem COM1X Bits wählen - die Compare ISRn 
kannst du dir sparen.
Für dich ist 'Clear on Compare Match' der richtige Modus.
Gast #3863344
Lesenswert?

Matthias Sch. schrieb:

> Da bin ich mir nicht so sicher, da der TE genau an den Pins rumfummelt,
> die die Hardware OC Register selbst bearbeiten.

Ist aber so. Schau dir einfach das Prinzipschaltbild der Portbits an 
(das steht verdammt nochmal ebenfalls im Datenblatt). Alternative 
Portfunktionen haben bezüglich PORTx-Ausgaben immer absoluten Vorrang, 
bezüglich DDRx meistens (im Falle der Timer-OC-Ausgänge allerdings 
nicht).

Da er nur an den PORTx rumfummelt, ist es praktisch genauso, als wenn er 
garnix tut.
#3863440
Lesenswert?

Matthias Sch. schrieb:
> Da bin ich mir nicht so sicher, da der TE genau an den Pins rumfummelt,
> die die Hardware OC Register selbst bearbeiten.

Das macht nichts. Die Pins werden von der PWM übernommen. Aber so ein 
Unsinn gehört da natürlich trotzdem nicht hin.

Guest schrieb:
> Muss ich überhaupt PORTD ^= (1<<PD4) schreiben?

Nein, natürlich nicht. Sinn des PWM-Modes ist, dass der Timer das 
alleine macht.

mfg.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren