Forum: Mikrocontroller und Digitale Elektronik kann mal jemand bitte einen kleinen Blick drauf werfen Fehlerverhalten


von Thomas (Gast)


Lesenswert?

Hi,

bin Anfänger und hoffe, dass mir jemand hilft.

Wollte ein wenig mit PWM mich beschäftigen -  nur habe anscheinend einen 
Fehler drin  -  die Frequenz soll größer und kleiner werden  -  das 
funktioniert auch  - allerdings gibt es immer wieder "Aussetzer" 
(Ausgang dann auf low)  und ich weiß nicht warum
1
#include <stdint.h>
2
#include <avr/io.h>
3
4
5
int main()
6
 { 
7
 
8
uint16_t test,test2;
9
uint16_t t2;
10
11
DDRB=0b00000110;
12
 
13
TCCR1A = (1<<COM1A1) | (1<<WGM11);
14
  TCCR1B = (1<<WGM13) | (1<<WGM12) |  (1<<CS12);
15
16
17
18
19
start:
20
21
22
t2=600;
23
test2=0;
24
25
26
27
while(test2<600){
28
 test2++;
29
 while (test<1000){test++;};
30
  test=0;
31
 
32
  t2++;
33
34
  OCR1A=(t2 / 2);
35
  ICR1=t2;
36
}
37
38
test2=0;
39
40
while(test2<600){
41
 test2++;
42
 while (test<1000){test++;};
43
  test=0;
44
  t2--;
45
46
  OCR1A=(t2 / 2);
47
  ICR1=t2;
48
}
49
50
51
52
53
goto start;
54
return 0;
55
}

von spess53 (Gast)


Lesenswert?

Hi

Sollte nicht irgendwo der Controller vereinbart sein?.
Wenn die PWN längere Zeit den Pegel nicht wechselt, ist das OC-Register 
in dieser Zeit entweder 0 oder Maximum (255 oder 65535, je nach Timer).

MfG Spess

von Thomas (Gast)


Lesenswert?

Hallo,

nein nein  -  das läuft, ja alles  -  nur es setzt so im ca 1 
Sekundentakt für ne halbe Sekunde aus ....

bitte helft mir -  ist der Code richtig ?

von Thilo M. (Gast)


Lesenswert?

Was ist die Funktion von ICR1 (input-capture)?
Wieso beschreibst du dieses Register?

von Gast (Gast)


Lesenswert?

Hi,

1) ich vermute es liegt daran, dass wenn ein Zyklus durchgelaufen ist 
wieder mit goto start; an den Anfang gesprungen wird und bevor
1
OCR1A=(t2 / 2);
2
ICR1=t2;

gesetzt wird erst einmal wieder gewartet wird:
1
while(test2<600){
2
 test2++;
3
 while (test<1000){test++;};

2) Schau dir for-Schleifen einmal an, dann wird dein Code lesbarer und 
lass das goto weg; verwende stattdessen eine Endlosschleife.

von spess53 (Gast)


Lesenswert?

Hi

Ich
>Wenn die PWM längere Zeit den Pegel nicht wechselt....

Du
> nur es setzt so im ca 1 Sekundentakt für ne halbe Sekunde aus ....

Worin siehst du da einen Unterschied?

Was mir noch aufgefallen ist:

uint16_t t2;
...
OCR1A=(t2 / 2);

OCR1A ist ein 8-Bit-Register

Ich weiss nicht, was C bei t2/2 > 255 macht?

MfG Spess

von Matthias L. (Gast)


Lesenswert?

>Ich weiss nicht, was C bei t2/2 > 255 macht?

Meineswissens wird dann einfach das Low-byte genommen.

von Thomas (Gast)


Lesenswert?

Hi,

habe das Problem viel enger fassen können:


Es kommen ca im 1 Sekundentakt "Aussetzer"
1
int main()
2
 { 
3
 
4
uint16_t a,b;
5
6
DDRB=0b00000110;
7
 
8
TCCR1A = (1<<COM1A1) | (1<<WGM11);
9
TCCR1B = (1<<WGM13) | (1<<WGM12) |  (1<<CS12);
10
OCR1A=1;
11
12
13
14
15
16
while(1){
17
18
 ICR1=400;
19
 for(a=0; a<10; a++){};
20
 ICR1++;
21
}
22
23
24
}


Sobald ich ICR++ ausklammere geht es  -  warum ???

vielen Dank für eure Hilfe !

von Thomas (Gast)


Lesenswert?

..auch jetzt noch
1
int main()
2
 { 
3
 
4
DDRB=0b00000110;
5
 
6
TCCR1A = (1<<COM1A1) | (1<<WGM11);
7
TCCR1B = (1<<WGM13) | (1<<WGM12) |  (1<<CS12);
8
OCR1A=1;
9
10
11
12
while(1){
13
 ICR1=400;
14
 ICR1++;
15
}
16
17
}

von Thomas (Gast)


Lesenswert?

Darf man ICR1 nicht so oft beschreiben ?

von Thomas (Gast)


Lesenswert?

@ Thilo -  ich will die Frequenz des PWM-Generators ändern  -  geht das 
auch anders ?

von spess53 (Gast)


Lesenswert?

Hi

Wenn der Controller anscheinend geheim ist, dann verrate wenigstens ob 
du einen 8-Bit oder 16-Bit-Timer benutzt.

MfG Spess

von Thomas (Gast)


Lesenswert?

Hi  -  nix geheim   ATMEGA8


sorry !

von spess53 (Gast)


Lesenswert?

Hi

Und weiter. Könntest du mal Fragen vollständig beantworten. Du kannst 
keine Hilfe erwarten, wenn man dir alles aus der Nase ziehen muss.

MfG Spess

von Thomas (Gast)


Lesenswert?

@Spess


Was meinst Du mit weiter ?


Atmega8  -  korrekt angeschlossen bei 5V  - interner Oszillator verwandt

Programmiert über AVR-Studio, hex-file über Ponyprog hochgeladen ( ging 
bisher auch immer korrekt)


Was kann ich noch mehr sagen ?



Alle Software-Einstellungen sieht man hier:
1
int main()
2
 { 
3
 
4
DDRB=0b00000110;
5
 
6
TCCR1A = (1<<COM1A1) | (1<<WGM11);
7
TCCR1B = (1<<WGM13) | (1<<WGM12) |  (1<<CS12);
8
OCR1A=1;
9
10
11
12
while(1){
13
 ICR1=400;
14
 ICR1++;
15
}
16
17
}

von spess53 (Gast)


Lesenswert?

Hi

>Alle Software-Einstellungen sieht man hier:...

1.Man kann z.B. keine Einstellungen überprüfen, wenn man nicht weiß, was 
damit erreicht werden soll ->Kommentare.

2. Ich hatte nach Timertyp gefragt. Soll ich oder andere erst im 
Datenblatt nachsehen, was du meinst?

MfG Spess

von t.b.d. (Gast)


Lesenswert?

...
 ICR1=400;
 for(a=0; a<10; a++){};
 ICR1++;
 ...
wenn zum Zeitpunt ICR1=410 --> ICR1=400 gilt 400<TCNT1 dann ist die 
Bedingung für das Schalten des PWM-Ports (TCNT1==ICR1) erst nach einem 
kompletten Timerdurchlauf erfüllt.

von Thomas (Gast)


Lesenswert?

t.b.d. .... du bist ein Schatz ;)  -  1000 DANK !

von Thilo M. (Gast)


Lesenswert?

Thomas wrote:
> @ Thilo -  ich will die Frequenz des PWM-Generators ändern  -  geht das
> auch anders ?

Ja, durch verändern von OCR1A.

von Pete K. (pete77)


Lesenswert?

Statt
for(a=0; a<10; a++){};

besser die Routinen aus <avr/delay.h> verwenden. Z.B. _delay_us(10);

Einige Compiler optimieren Schleifen ohne erkennbare Funktionen einfach 
weg.

von LÖW (Gast)


Lesenswert?

"Ja, durch verändern von OCR1A."

Quark  -  das damit wird nur der Zeitpunkt des H->L  bzw. L->H 
gewechselt   -  Frequenz bleibt gleich !


Gruß Walter

von Thilo M. (Gast)


Lesenswert?

Stimmt. Hatte Frequenz mit Tastverhältnis verwechselt. ;)

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.