kann mal jemand bitte einen kleinen Blick drauf werfen Fehlerverhalten

Gast #949472
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
}
Gast #949488
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
Gast #949525
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.
Gast #949526
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
Gast #949551
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 !
Gast #949553
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
}
Gast #949576
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
}
Gast #949593
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
Gast #949626
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.

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