Forum: Mikrocontroller und Digitale Elektronik Rechtecksignalauswerung mit ATtiny 45


von U. H. (dx145)


Lesenswert?

Hallo zusammen.

Ich habe ein Rechtecksignal bei dem ich eine Frequenzauswertung machen 
will (Schwellfrequenzüberwachung).
Dazu benötige ich eine Positive Flanke und ich weiss nicht wie das geht, 
bin Anfänger auf MCs.

Meine Programmierüberlegung:

  while(1)
  {
 if (POSITIVE FLANKE PINB)
 {
   _delay_ms(0.8);
   if (PINB & (1<<PB2))
   {
     laenger_0_8ms();
   }
   else
   {
     kuerzer_0_8ms();
   }
  }
}
void laenger_0_8ms()
{
  PORTB=(0<<PB0);
}
void kuerzer_0_8ms()
{
  PORTB=(1<<PB0);
}

Jetzt weiss ich nur nicht wie ich eine positive Flanke mache, kann mir 
da jemand helfen?

Danke bereits im Voraus und Gruss

von 936 (Gast)


Lesenswert?

Entweder du tastest ab, wie es dein Beispiel zeigt, oder die verwendest 
PCINT (Pin change interrupts).

Zur Abtastung und Erkennung der positiven Flanke:
1
int state = (PINB << PB2) & 1; /* PB2 auslesen */
2
3
while(1) {
4
   int current = (PINB << PB2) & 1;
5
   if(state == 0 && current) {
6
      /* letzter Zustand 0 und PB2 ist jetzt das erste mal 1
7
         --> positive Flanke */
8
      state = 1;
9
   }
10
   else if(state == 1 && !current) {
11
      /* letzter Zustand 1 und PB2 ist jetzt das erste mal 0
12
         --> negative Flanke */
13
      state = 0;
14
   }
15
}

Nicht funktionierend ist
1
_delay_ms(0.8)
da wird ein Integer erwartet.

Zu Interrupts: 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Interrupts

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

U. H. schrieb:
> Dazu benötige ich eine Positive Flanke und ich weiss nicht wie das geht,
> bin Anfänger auf MCs.

Hallo!
Ich würde den INT0 verwenden. Für den kannst du einstellen, den kannst 
du nämlich so einstellen, dass er nur durch eine positive Flanke 
ausgelöst wird und nicht durch eine negative. Beim Pin-change-Interrupt 
ist das leider nicht möglich.

Bis zu welcher Frequenz soll die Auswertung funktionieren?
Wenn du in den MHz-Bereich kommst, dann würde ich eher Assembler 
verwenden.

Als Alternative könntest du die Takt-Zählfunktion des µC verwenden. Je 
nachdem, wie schnell du auf den Frequenzwechsel reagieren willst...

von U. H. (dx145)


Lesenswert?

Von einer Hardwareflanke INT0 habe ich schonmal etwas gehört, aber wie 
verwende ich diese? wird dadurch nicht ein Interrupt ausgelöst?

Danke und gruss

von kopfkratzer (Gast)


Lesenswert?

U. H. schrieb:
> Von einer Hardwareflanke INT0 habe ich schonmal etwas gehört, aber
> wie
> verwende ich diese? wird dadurch nicht ein Interrupt ausgelöst?
>
> Danke und gruss

Das ist der Knackpunkt !
Du liest Dir erstmal das Datenblatt durch und versuchst zu verstehen was 
INT0 bedeutet und wie man die Register für die steigende Flanke 
beschickt.
Dann nimmst Du den INT0 Interrupt der jedesmal mit der steigenden Flanke 
ausgelöst wird und zählst in der IRQ eine volatile Variable hoch.
Nun weißt Du wie oft das passiert ist und brauchst noch was um Deine 
Frequenz zu erhalten ?

von Erwin (Gast)


Lesenswert?

Ja, GANZ SCHRECKLICH, bei richtiger Beschaltung und
Freigabe des INT0 wird dieser Interrupt ausgelöst!

Und nun?

Dann wertest du ihn in der INT0-Interrupt-Routine
aus.

Und dann?

Dann haste, was du wolltest.

von U. H. (dx145)


Angehängte Dateien:

Lesenswert?

Ich muss ja in die Bits ISC01 und ISC00 im MCUCR je eine 1 schreiben, um 
eine rising edge Interrupt auslösen zu können.

wie mach ich das nun? und wo? vor der while(1) Schleife in der main 
Schleife oder vor der main Schleife?

und wie setze ich die Bits?
So:
MCUCR=(1<<ISC00)|(1<<ISC01); ?
und wie verwende ich nun das Interrupt das ausgelöst wird?

Danke und Gruss

von kopfkratzer (Gast)


Lesenswert?

U. H. schrieb:
> Ich muss ja in die Bits ISC01 und ISC00 im MCUCR je eine 1
> schreiben, um
> eine rising edge Interrupt auslösen zu können.
>
> wie mach ich das nun? und wo? vor der while(1) Schleife in der main
> Schleife oder vor der main Schleife?
>
> und wie setze ich die Bits?
> So:
> MCUCR=(1<<ISC00)|(1<<ISC01); ?
> und wie verwende ich nun das Interrupt das ausgelöst wird?
>
> Danke und Gruss

Ob Du die Initialisierung nun direkt in der main oder einer eigenen 
init() Prozedur machst ist egal.
Das es VOR der Hauptschleife sein muß sollte klar sein, oder willst Du 
für immer den IRQ neu anschalten ?
Woher kennst Du die Bits die gesetzt werden müssen ?
Lies Dir hier die Tutorials durch, dann weißt Du auch wie man einen 
Internetvektor verwendet.
Achte bei der Variable die in der IRQ einfach
1
uZaehler++;
macht darauf das sie volatile ist und wie bekommst Du nun eine Frequenz 
von dem Wert ?

von U. H. (dx145)


Lesenswert?

Sorry aber was ist IRQ?

Und wäre es vielleicht möglich, dass Du mir ein Beispielprogramm machen 
könntest, wie ich das Interrupt verwenden kann, das durch die Positive 
Flanke ausgelöst wird?
Die Aufgerufenen Bits reichen schon oder? Oder muss ich da auch noch 
etwas machen?

von Erwin (Gast)


Lesenswert?

Hast du noch nie ein Programm geschrieben?

Ein C-Programm beginnt mit der main()-Funktion.

Dann initialisiert man alles - und danach beginnt
eine while(1)-Schleife, in der alles  abgehandelt wird,
was vom Programm bearbeitet werden soll.

Neben der main()-Funktion werden Interrupt-Routinen
(z.B. für INT0) und weitere Funktionen programmiert.

Hier musst du
- ein paar Speicherplätze global vorhalten
(z.B. für den Messwert aus der INT0-Routine),
- einen freilaufenden Timer passend für die Zeitmessung
initialisieren  und den
- INT0 initialisieren.

In der INT0-Routine fragst du den Zählerstand des
Timers ab, speicherst ihn ab und setzt den Timer wieder
auf NULL.

In der while(1)-Schleife schaust du nach, ob am vereinbarten
Speicherplatz ein neuer Messwert (ungleich NULL) von der
INT0-Routine vorhanden ist.
Diesen Messwert kopierst du und schreibst in den vereinbarten
Speicherplatz wieder eine NULL. Jetzt überprüfst du den Wert
und reagierst entsprechend...


Wenn das nicht hilft, solltest du erst mal
mit "hello_world.c" anfangen!

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

U. H. schrieb:
> Sorry aber was ist IRQ?

Tante Wikipedia ist so schlau, die weiß fast alles. Probiers ruhig mal, 
sie beißt nicht! :-)

Besser erklären als sie könnt ich es auch nicht.

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.