Forum: Mikrocontroller und Digitale Elektronik Frage zu C


von Hans (Gast)


Lesenswert?

Hallo,

Ich bin gerade dabei, mich ein wenig in C einzuarbeiten. Und da hab ich 
schon eine Frage. Ich habe deinen Code geschrieben, der eine LED 
einschaltet und danach gleich wieder ausschaltet. Ich wollte dies machen 
um die maximal erreichbare Frequenz zu messen (mit Oszi).
Doch wenn ich den Ausgang am Oszi ansehe, habe ich ein Tastverhältnis 
von 25% und nicht die (von mir) erwarteten 50%. Warum ist das so?

Ich verwende einen ATMega8.

Mein Code:

#include <avr/io.h>
#include <stdlib.h>
#define TAKT 8000000

void main(void)
{
//  unsigned char akku;
  DDRD = 0x20;
  while(1)
  {
  PORTD = (1 << PD5);
  PORTD = (0 << PD5);
  }
}


Danke für eure Infos!!

von Patrick (Gast)


Lesenswert?

Hallo Hans,

weil das while(1) auch Zeit braucht. Nachdem der Port auf 0 gesetzt 
wurde,
prüft der µC erst noch die Bedingung 1 ab und setzt erst dann wieder den 
Port high.

Gruß
Patrick

von Jörg B. (manos)


Lesenswert?

Wird wohl daran liegen dass er zwar in einem Takt von "1" auf "0" aber 
für die umgekehrte Richtung durchläuft das Programm wieder eine Abfrage.

von Hans (Gast)


Lesenswert?

Danke, das wollte ich wissen!!

Tolles Forum hier!!

mfg
Hanns

von johnny.m (Gast)


Lesenswert?

1.: Du programmierst in C, also in einer Hochsprache. Das bedeutet, dass 
das, was Du programmierst nicht unbedingt (sogar eher selten) das ist, 
was der Controller hinterher macht. Wenn Du Dir ansiehst, was der 
Compiler aus Deinem Code macht, dann wird da etwas in der Art von
1
LOOP:
2
    ldi r16, (1 << PD5) ;r16 mit Bitmaske laden
3
    out PORTD, r16  ;PD5 setzen
4
    clr r16         ;r16 löschen
5
    out PORTD, r16  ;Port D "0" setzen
6
    rjmp LOOP       ;Sprung zurück (Endlosschleife)
Die Bezeichner (LOOP, PORTD, PD5...) hab ich jetzt nur der Übersicht 
halber reingeschrieben. Wie man sieht, wenn man ein bisschen was von 
Assembler versteht, kommt nach dem Löschen des Portregisters der 
Rücksprung. Und der braucht nunmal zwei Zyklen. Während dieser zwei 
Zyklen und anschließend während des "ldi r16, (1 << PD5)" ist der Port 
0. Dadurch ist das Tastverhältnis natürlich nicht mehr 50%.

2.: "PORTD = (0 << PD5)" ist Unsinn. Wenn man eine Null verschiebt, 
bleibt es eine Null. Dann kannste gleich schreiben
1
PORTD = 0;
Bits setzen, ohne andere Bits im selben Register anzutasten geht mit
1
REGISTER |= (1 << BITNAME);
Bit löschen mit
1
REGISTER &= ~(1 << BITNAME);

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.