Forum: Mikrocontroller und Digitale Elektronik Fortlaufender Zähler in C


von Sebastian H. (baschti)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
Ich bin gerade dabei ein Programm zu entwickeln, das bei Knopfdruck 
einen bestimmten Wert herunterzählt, währenddessen einen Ausgang 
ansteuert und bei abgelaufener Zeit diesen Ausgang wieder abschaltet.
Diese Funktion ist im Anhang bereits realisiert. Jedoch möchte ich, dass 
bei erneutem Drücken des Tasters während der Zähler herunterzählt die 
ursprüngliche Zahl im Zähler zum aktuellen Zählerstand addiert wird.

Beispiel:

Zählt von 10 nach 0, Zählerstand ist bei 6, nach erneutem Drücken des 
Tasters ist der Zählerstand bei 6 + 10, also bei 16, jetzt zählt der 
Zähler von 16 naach 0, Zählerstand is inzwischen bei angenommen 3, nach 
erneutem Drücken des Tasters is der Zählerstand nun bei 3 + 10, also bei 
13 usw...

Vielleicht kann mir jemand helfen
Danke schon mal für die Bemühungen
Basti

von Michael (Gast)


Lesenswert?

Das wird so wahrscheinlich nicht funktionieren, da du während der delays 
keine Tasterabfrage machen kannst. Ich würde mich in die Timerfunktion 
einarbeiten (ist nicht wirklich schwer) und es hiermit umsetzen.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR

von Klaus W. (mfgkw)


Lesenswert?

Magst du den Quelltext vielleicht bitte vernünftig formatieren und als 
.c-Datei anhängen statt als Grafik?

von Michael (Gast)


Lesenswert?

Ach ja - du darfst auf keinen Fall vergessen, deinen Taster zu 
entprellen. Sonst zählt er ab und zu X * 10 (also 20 oder 30 ...) dazu.

von Sebastian H. (baschti)


Angehängte Dateien:

Lesenswert?

Tut mir leid, hab gedacht bilder sind hier mehr erwünscht...

von Klaus W. (mfgkw)


Lesenswert?

Danke.

Michael hat natürlich recht; du brauchst einen anderen Aufbau deines 
Programms wie im Tutorial beschrieben.

von Sebastian H. (baschti)


Lesenswert?

@ michael,

muss ich dann mit interrupt auch arbeiten? sorry, aber ich hab leider 
nicht so viel Ahnung, könntest du mir vielleicht einen Vorschlag machen 
wie ich es realisieren könnte?
gruß

von Michael (Gast)


Lesenswert?

Prinzipiell würde ich das so machen:

Globale Variable Counter

Timer Interrupt (jede 1 s)
{
  Wenn Counter > 0
     Counter --;
}

Main
{
  Wenn Counter == 0
     PORTB = Zustand1
  Sonst
     PORTB = Zustand2

  Wenn (Taste kurz gedrückt) // Entprellung nicht vergessen
    Counter += 10
}


Zum Entprellen des Tasters kann ich die Codes von Peter Dannegger 
empfehlen:
http://www.mikrocontroller.net/articles/Entprellung#Debounce-Makro_von_Peter_Dannegger

von Michael (Gast)


Lesenswert?

Wenn du weitere Hilfe brauchst, einfach melden

von Sebastian H. (baschti)


Lesenswert?

hey danke mal!
ich werd versuchen mich reinzulesen, aber komm warscheinlich nochmal auf 
deine hilfe zurück :)
grüße Basti

von Michael (Gast)


Lesenswert?

Gerne - ich geben gern zu, dass es am Anfang etwas unübersichtlich ist. 
Ich würde zunächst das Programm ohne Entprellen so wie dein obiges 
Beispiel bauen. Also durch drücken auf die Taste, wird Counter auf 10 
gesetzt (nicht addiert). Dann spielt nämlich das Prellen des Tasters 
keine maßgebliche Rolle und das Programm wird erstmal einfacher. 
Erweitern können wir es dann anschließend.

von Düsendieb (Gast)


Lesenswert?

Michael schrieb:
> Wenn (Taste kurz gedrückt) // Entprellung nicht vergessen

mit: Wenn (Taste kurz gedrückt)&(counter==0) Counter += 10;

könnte man sich die Entprellung sparen, da dann der eigene Timer das 
Entprellen übenimmt.

von Michael (Gast)


Lesenswert?

@Düsendieb: Entweder ich habe dich jetzt nicht verstanden, oder das 
funktioniert so nicht.

Wenn die Taste einmal gedrückt wird, wird Counter auf 10 gesetzt (da 
Counter = 0 und Taste gedrückt). Jetzt zählt er auf 4 runter und ich 
drücke die taste erneut. Erwarten würde ich, dass counter jetzt auf 14 
gesetzt wird. Da counter aber ungleich 0 ist deine Bedingung unwahr und 
es wird nichts addiert.

von Düsendieb (Gast)


Lesenswert?

Michael schrieb:
> Da counter aber ungleich 0 ist deine Bedingung unwahr und
> es wird nichts addiert.

Stimmt, das mit dem Nachtriggern habe ich übersehen.

von Sebastian H. (baschti)


Lesenswert?

servus Michael,
Ich komm mit dem counter, der jede Sekunde durch den Interrupt 
unterbrochen werden soll, gar nicht zurecht, außerdem kann ich nirgendwo 
herauslesen wie der interrupt ordendlich programmiert wird. Kannst Du 
mir sagen wie ich das schreiben soll?

Also sorry wenn ich hier auf Anfängerkram rumhacke, aber hab halt 
ziemlich wenig Ahnung...

gruß

von Michael (Gast)


Lesenswert?

Hallo Sebastian,
was hast du denn für einen Controller? Du programmierst mit dem AVR-GCC?

Viele Grüße
Michael

von Michael (Gast)


Lesenswert?

Und mit welcher Taktfrequenz läuft der Controller? Sind das wirklich 
3,68 MHz?

von Peter (Gast)


Lesenswert?

Mit Timerinterrupt ist es sicher eleganter aber für dieses Problem geht 
es auch noch genausogut ohne Interrupt:
1
#include <avr/io.h>
2
#include <avr/delay.h>
3
4
#ifndef F_CPU
5
#define F_CPU 3686400UL
6
#endif
7
8
void WaitAndCheck(*i)
9
{
10
  int e; 
11
  for(e=100; e>0, e++)          // 100 x 10ms = 1s
12
  {
13
    _delay_ms(10);              // auch gut zur Entprellung
14
    if (PINB == 0b11111110)
15
    {
16
       while(PINB==0b11111110); // warte bis Taster losgelassen
17
       *i = *i + 10;            // aktueller zähler + 10
18
    }    
19
  }
20
}
21
22
23
int main (void)
24
{
25
  DDRA = 0xFF;         //Ausgang PORTA
26
  DDRB = 0x00;        //Eingang PORTB
27
  PORTA = 0xFF;        //LED Aus
28
  //unsigned char x;
29
  int i,e;
30
  while(1)
31
  {
32
    if (PINB == 0b11111110)
33
    {
34
      while(PINB==0b11111110);          // warte bis Taster losgelassen
35
      for(i=10; i>0; i--)
36
      {
37
        PORTA = 0b11111110;
38
        WaitAndCheck(&i);
39
      }
40
      PORTA = 0xFF;
41
      WaitAndCheck(&i);
42
    }
43
  }  
44
  return 0;
45
}

von Peter (Gast)


Lesenswert?

Oups, kleine Korrektur:
1
  for(e=100; e>0, e--)          // 100 x 10ms = 1s

von Peter D. (peda)


Lesenswert?

Sebastian Haunei schrieb:
> Also sorry wenn ich hier auf Anfängerkram rumhacke, aber hab halt
> ziemlich wenig Ahnung...

Laß mal den ganzen Programmierkram beiseite, das kommt erst 10 Schritte 
später.
Du mußt erstmal damit anfangen, Dir eine Programmstruktur zu überlegen. 
Also auf welche Bedingung soll wie reagiert werden. Und das in ganz 
kleinen Schritten, also immer nur die nächste Aktion, sonst verhaspelst 
Du Dich nur (Spaghetticode).

Und dann mußt Du versuchen, zur Mainloop zurückkehrend zu denken. Also 
wenn eine Bedingung erfüllt ist, mache was, das ist ok.
Aber wenn die Bedingung nicht erfüllt ist, warten bis zum Sankt 
Nimmerleinstag, ist nicht ok. Das versaut Dir den ganzen Ablauf. Also 
zurück zur Mainloop und die nächste Aufgabe aufrufen.
Du hast schon mindenstens 3 Aufgaben, die sich nicht blockieren dürfen:
- Entprellen
- Taste auswerten
- Zeit ablaufen lassen

Am besten, schalte den PC aus und schreibe erstmal in Worten die ganzen 
Bedingungen und Aktionen auf (Programmablaufplan).
Erst wenn man weiß, wie etwas erfolgen soll, kann man es auch als Code 
einhacken.


Peter

von Michael (Gast)


Lesenswert?

Stimmt - so geht es natürlich auch. Aber für spätere Entwicklungen 
(falls das nicht die einzige Aufgabe des uC sein soll) und als 
Lerneffekt ist es mit dem Interrupt sicher besser.

Bei deiner Variante bleibt das Programm im Übrigen auch hängen, wenn man 
die Taste drückt. Weiterlaufen tut es erst, wenn man loslässt.

von Peter (Gast)


Lesenswert?

>Bei deiner Variante bleibt das Programm im Übrigen auch hängen, wenn man
>die Taste drückt. Weiterlaufen tut es erst, wenn man loslässt.

Natürlich müsste man sich überlegen und definieren, was das Program tun 
soll, wenn die Taste gedrückt bleibt:
 => jede Sekunde einmal um 10 hochzählen
 => alle 10ms um 10 hochzählen
 => warten bis Taste wieder losgelassen

von Michael (Gast)


Lesenswert?

Oder - wie ich es bisher gedacht habe - einfach gar nichts. Sprich, 
weiter herunterzählen und erst um 10 inkrementieren, wenn Taste 
losgelassen wird.

von Peter D. (peda)


Lesenswert?

Ohne eine Struktur kann man sich das Programm natürlich beliebig 
kompliziert und undurchschaubar machen.

Meine wichtigste Devise beim Programmieren:
Teile (die Aufgaben) und Herrsche (verstehe, was Du machst).


Peter

von Sebastian H. (baschti)


Lesenswert?

Hallo nochmal,
ihr müsst vielleicht wissen, der Controller soll beim Knopfdruck ein 
Relais anschalten und der Knopfdruck wird duch einen Münzeinwurf 
realisiert. Wie lange man jetzt auf dem Taster drücken muss dass etwas 
passiert kann man also praktisch garnicht beeinflussen, Der Münzeinwurf 
schaltet nur kurz einen Kontakt.
Und mein Gedanke war eben, nach dem Einwurf einer Münze schaltet das 
Relais durch und wenn von mir aus 15 Minuten vergangen sind schaltet das 
Relais wieder aus.
Das wäre an sich ja nicht schwierig zu realisieren, jedoch wollte ich 
dass man die Zeit, die das Relais durchschaltet beliebig durch erneutes 
Einwerfen verlängern kann.

Grüße Basti

von Michael (Gast)


Lesenswert?

@Sebastian: Wenn du Hilfe brauchst, solltest du mir noch meine Fragen 
beantworten :-)

von Sebastian H. (baschti)


Lesenswert?

Entschuldigung Michael,
momentan habe ich den Atmega 8515 im STK500, ich programmiere mit GCC. 
Und was die Taktfrequenz angeht habe ich nur den Wert genommen dass die 
Zeit in meinem Programm, dass ich am Anfang hochgestellt habe, mit der 
Echtzeit übereinstimmt. Würde ich das nicht in den Kopf schreiben würde 
mein Controller zwar zählen, aber nicht in Echtzeit.

Mit dem Programm von peter komm ich auch nicht wirklich zurecht, probier 
seit Stunden rum, ich möchte es nun nochmal mit dem Interrupt versuchen, 
weil mir dein Programmschema sogar logisch erscheint :)

gruß Basti

von Sebastian H. (baschti)


Lesenswert?

hobbla, sorry, ATmega 8535, aber is ja fast gleich glaub ich

von Michael (Gast)


Lesenswert?

Gut - dann würde ich zunächst einmal den Timer initialisieren.
Also in main vor der Endlosschleife (= Initialisirung):

[c]
  DDRA = 0xFF;         //Ausgang PORTA
  PORTA = 0xFF;        //LED Aus

  // Timer 0 konfigurieren
  TCCR0A = (1<<WGM01); // CTC Modus
  TCCR0B |= (1<<CS01); // Prescaler 8
  // ((1000000/8)/1000) = 125
  OCR0A = 125-1;

  // Compare Interrupt erlauben
  TIMSK |= (1<<OCIE0A);

  // Global Interrupts aktivieren
  sei();
[\c]

Über der Main Funktion eine globale Variable deklarieren:

[c]
volatile unsigned char toggle=0;
volatile unsigned int count=0;
[\c]

Dann machst du eine neue Funktion (unter der Main Funktion):

[c]
ISR (TIMER0_COMPA_vect)
{
  count ++;

  if (count == 1000)  // alle 1000 ms LED toggeln
  {
    if (toggle == 0)
    {
      PORTA = 0b11111110;
      toggle = 1;
    }
    else
    {
      PORTA = 0b11111111;
      toggle = 0;
    }
    count = 0,
  }
}
[\c]

Theoretisch sollte deine LED jetzt blinken. Bitte beachten, dass ich von 
einer Taktfrequenz von 1 MHz ausgegangen bin und die LED dann wohl 
schneller blinken wird, als 1x pro Sekunde. Im Übrigen hab ich das grade 
aus dem Kopf geschrieben und kann es in der Arbeit leider nicht 
austesten.

Bin dann mal in der Mittagspause.

von Sebastian H. (baschti)


Lesenswert?

´n gutn!

ich probiers mal aus

von Michael (Gast)


Lesenswert?

Und - wie schauts aus?

von Sebastian H. (baschti)


Angehängte Dateien:

Lesenswert?

blinkt nix...
der zeigt no 6 fehler an, aber schau doch ob ich´s überhaupt richtig 
gemacht hab so

von Michael (Gast)


Lesenswert?

Wer zeigt No6 Fehler an? Der Compiler? Dann kann ja auch nichts blinken.

Gibts eine Fehlermeldung dazu?

von Michael (Gast)


Lesenswert?

Die ISR (Interrupt Routine) darf NICHT in die main Funktion, sondern 
muss nach der Mainfunktion (also der letzten geschweiften Klammer-Zu) 
rein. Das ist eine eigenständige Funktion.

von Sebastian H. (baschti)


Angehängte Dateien:

Lesenswert?

ich kanns mit fehlermeldungen ja nicht auf den Controller schreiben, so 
siehts im Programm aus

von Michael (Gast)


Lesenswert?

Die Fehlermeldungen sagen, dass die Register für den Timer nicht 
deklariert sind. Ich schau mal schnell nach, ob die beim Mega8535 auch 
so heißen.

von Michael (Gast)


Lesenswert?

Ok - ändere bitte mal die Bezeichnungen wie folgt ab:
TCCR0A = TCCR1A
TCCR0B = TCCR1B
OCR0A = OCR1A
OCIE0A = OCIE1A
TIMER0_COMPA_vect = TIMER1_COMPA_vect

von Michael (Gast)


Lesenswert?

Das ist ein 16 Bit Timer. Dann müsstest du noch aus

OCR0A oder OCR1A = OCR1AL machen.

von Peter D. (peda)


Lesenswert?

Sebastian Haunei schrieb:
> ihr müsst vielleicht wissen, der Controller soll beim Knopfdruck ein
> Relais anschalten und der Knopfdruck wird duch einen Münzeinwurf
> realisiert. Wie lange man jetzt auf dem Taster drücken muss dass etwas
> passiert kann man also praktisch garnicht beeinflussen, Der Münzeinwurf
> schaltet nur kurz einen Kontakt.
> Und mein Gedanke war eben, nach dem Einwurf einer Münze schaltet das
> Relais durch und wenn von mir aus 15 Minuten vergangen sind schaltet das
> Relais wieder aus.

Sag doch einfach, eine Parkuhr.
Wie schon oben gesagt, das sind 3 Aufgaben. Die kann man nacheinander 
implementieren und testen. Nicht alles zugleich machen und miteinander 
verwoben, sondern alles schön getrennt.

Warscheinlich willst Du die Zeit auch anzeigen, das ist dann die 4. 
Aufgabe:
1
int main()
2
{
3
  for(;;){
4
    // entweder:
5
      if( timerflag == 0 )    // warten auf Timer (Überlauf oder Compare)
6
        continue;
7
    // oder:
8
      _delay_ms( 10 );        // 10ms Zeitbasis mit Delay
9
10
    entprelle(();
11
    taste_gedrueckt_aktion(); // Ausgang an, zeit setzen
12
    zaehle_zeit();            // count down
13
    zeit_0_aktion();          // 0 erreicht
14
    anzeige_zeit();
15
  }
16
}
Und schon ist das Grundgerüst fertig.

Schreibe ruhig einzelne Funktionen. Das erleichtert die Übersicht und 
die Strukturierung.
Das bischen Stack für nen Funktionsaufruf kostet nix.


Peter

von Sebastian H. (baschti)


Angehängte Dateien:

Lesenswert?

...keine Fehler mehr, so sieht das Programm jetzt aus

von Michael (Gast)


Lesenswert?

Gut, was macht die LED?

von Peter (Gast)


Lesenswert?

Ok, nun ist mir klar was Du genau bezwekst:

Ein Münzautomat, der pro Münzeinwurf für einen bestimmten Zeitkredit 
irgend was einschaltet, z.B. Warmwasser zum Duschen oder eine 
Waschmaschine...

Mein obiges Programm war wegen kleinen Flüchtigkeitsfehlern tatsächlich 
nicht kompilierbar, das folgende Beispiel sollte nun aber gehen...

Ev. noch zu berücksichtigen: für wieviele ms wird der Kontakt beim 
Münzeinwurf geschlossen? Ich gehe mal von >1 ms aus
1
#ifndef F_CPU
2
#define F_CPU 3686400UL
3
#endif
4
5
#include <avr/io.h>
6
#include <avr/delay.h>
7
8
#define Credit   (10)            // Zeitkredit pro Münze in Sekunden
9
#define Debounce (10)            // Prellzeit in ms
10
11
void WaitAndCheck(int *i);
12
13
int main (void)
14
{
15
  DDRA  = 0xFF;                  // Ausgang PORTA
16
  DDRB  = 0x00;                  // Eingang PORTB
17
  PORTA = 0xFF;                  // LED Aus
18
  int i;
19
  while(1)
20
  {
21
    if (PINB == 0b11111110)
22
    {
23
      _delay_ms(Debounce);       // zur Entprellung
24
      while(PINB==0b11111110);   // warte bis Taster losgelassen
25
      _delay_ms(Debounce);       // zur Entprellung
26
      PORTA = 0b11111110;        // einschalten
27
      for(i=Credit; i>0; i--)
28
      {
29
        WaitAndCheck(&i);
30
      }
31
      PORTA = 0b11111111;        // ausschalten
32
    }
33
  }
34
  return 0;
35
}
36
37
void WaitAndCheck(int *i)
38
{
39
  int e;
40
  for(e=1000; e>0; e--)          // 1000 x 1ms = 1s
41
  {
42
    _delay_ms(1);
43
    if (PINB == 0b11111110)
44
    {
45
      _delay_ms(Debounce);       // zur Entprellung
46
      while(PINB==0b11111110);   // warte bis Taster losgelassen
47
      _delay_ms(Debounce);       // zur Entprellung
48
      *i = *i + Credit;          // aktueller zähler + 10
49
      e = e-(Debounce*2);        // Korrektur für Prellwartezeit
50
    }
51
  }
52
}

von Sebastian H. (baschti)


Lesenswert?

es leuchtet keine LED
er schreibt:

#warning "This header file is obsolete. Use <avr/interrupt.h>

aber so hab ich´s ja geschrieben



@Peter
Ich weiß mit einzelnen Teilen leider nichts anzufangen, weil ich nicht 
weiß wie ich sie verknüpfen soll und was für initialisierungen usw. ich 
benötige.

von Michael (Gast)


Lesenswert?

Füg mal bitte "PORTA = 0b11111110;" direkt nach "counter++;" ein und 
kommentiere den Rest der Funktion (vom "if" bis "}") aus. Dann sehen 
wir, ob er überhaupt in die Interrupt-Routine reingeht.

Wie gesagt - ich kanns hier leider nicht testen, sonst würde es 
schneller gehen.

Kannst du deine LED so grundsätzlich anschalten? PORTA = 0b11111110;

Vg

von Martin (Gast)


Lesenswert?

Meine  Fresse,  Sebastian, lern  endlich selbst programmieren.

Diese Fehlermeldungen haben eine Bedeutung,  die fallen nicht vom 
Himmel.

von Peter D. (peda)


Lesenswert?

Sebastian Haunei schrieb:
> @Peter
> Ich weiß mit einzelnen Teilen leider nichts anzufangen

Das ist ja nur das Grundgerüst, damit die einzelnen Aufgaben klar 
werden.
Die einzelnen Funktionen erfüllt man dann später mit Leben 
(Top-Down-Methode).

Zum Austausch der Informationen zwischen den Funktionen benutzt man 
Argumente, Returnwerte oder globale Variablen.
Der Count-Down-Zähler ist z.B. eine globale Variable.
Der Erfolg (Taste gedrückt erkannt) von entprellen() ist z.B. der 
Returnwert.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Haunei schrieb:
> es leuchtet keine LED
> er schreibt:
>
> #warning "This header file is obsolete. Use <avr/interrupt.h>
>
> aber so hab ich´s ja geschrieben

Dann korriegiere es.
In der Fehlermeldung steht am linken Rand, dass sie sich auf das Include 
File signal.h bezieht.
Und die Fehlermeldung lautet, dass dieses File obsolet (als nicht mehr 
notwendig ist) und du statt dessen interrupt.h benutzen sollst.

Was also ist dein Vorschlag, was du da tun könntest?


Zum Problem:
1
  // Timer 0 konfigurieren
2
  TCCR1A = (1<<WGM01); // CTC Modus
3
  TCCR1B |= (1<<CS01); // Prescaler 8

du hast einen Mega 8535, richtig?

Dann ist das falsch.,
Für CTC muss WGM12 gesetzt sein und dieses Bit steht im Register TCCR1B
1
  // Timer 0 konfigurieren
2
  TCCR1B |= (1<<WGM12) | (1<<CS01); // CTC, Prescaler 8
 ´
Mit der Originaleinstellung war das kein CTC MOdus, sondern ein PWM 
Modus. Und der war ca. um einen Faktor 524 zu lang. Wenn du also rund 10 
Minuten gewartet hättest, hätte die LED getoggelt.


Lies das AVR-GCC-Tutorial zum Theme Timer. Und dann lies das 
Datenblatt, Abschnitt Timer. Das Datenblatt ist deine letztendliche 
'Bibel' der du trauen kannst.
UNd schau dir anderen Code an. Timer sind wirklich sehr einfach. Aber 
irgendwie hab ich das Gefühl, auch du hast mitlerweile in einen "bitte 
betet mir das vor, damit ich nichts selber machen muss" Modus 
geschaltet. Ist leider gang und gäbe hier im Forum.

von Sebastian H. (baschti)


Lesenswert?

@ Michael
ja, die LED leuchtet.

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:
> Füg mal bitte "PORTA = 0b11111110;" direkt nach "counter++;" ein und
> kommentiere den Rest der Funktion (vom "if" bis "}") aus. Dann sehen
> wir, ob er überhaupt in die Interrupt-Routine reingeht.
>
> Wie gesagt - ich kanns hier leider nicht testen, sonst würde es
> schneller gehen.

Du hast dich mit dem Konfigurationsbits des Timers vertan.

Ich geb jetzt wieder zurück an dich :-)
Mach weiter so. Du kriegst ihn schon noch soweit, dass er Timer 
versteht. Nur bete es ihm nicht zu detailiert vor. Ein bischen 
nachdenken muss er selber auch.


so ists laut Datenblatt Mega8535 richtig
1
  // Timer 0 konfigurieren
2
  TCCR1B |= (1<<WGM12) | (1<<CS01); // CTC, Prescaler 8
verifiziert im Simulator.

von Michael (Gast)


Lesenswert?

Dann setz doch mal bitte schnell die Änderung von Karl Heinz um.

von Michael (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Du hast dich mit dem Konfigurationsbits vertan.

Ja - genau so hab ich mir das gedacht :-) Aber vielen Dank für den 
Hinweis, bevor ich noch lange hier ohne Programmierumgebung rumrate oder 
das Datenblatt durchforsten muss.

von Sebastian H. (baschti)


Lesenswert?

@ Karl Heinz
Danke mal und ich weiß, am liebsten würde ich sagen schreibt mir mal 
bitte dieses und jenes Programm, ist ja auch verlockend wenn am anderen 
Ende lauter Profiprogrammierer sitzen...:)
Aber natürlich will ich auch was dabei lernen.

@ Michael, habs umgeschrieben, die LED leuchtet konstant

ich hab glaub ich schon wieder Fragen überlesen
@ Peter, ich schau mir dein Programm auch noch genauer an, nur muss ich 
mich momentan auf eine Sache konzentrieren, Danke trotzdem mal

von Michael (Gast)


Lesenswert?

Bitte kopiere nach jeder Änderung einmal deinen Sourcecode mit an deinen 
Post. Damit ich weiß, welche Software denn nun im Controller läuft.

von Sebastian H. (baschti)


Angehängte Dateien:

Lesenswert?

aktuelles programm im controller

von Sebastian H. (baschti)


Lesenswert?

ok michael, hatte noch die led angeschaltet, jetzt blinkt die erste LED

von Karl H. (kbuchegg)


Lesenswert?

Bitte häng deinen Code nicht als txt File an.

Nimmm dein *.c File so wie es ist und häng es als Attachment an.
Der Vorteil: Wir alle kommen in den Genuss von C-Syntax Highlighting.
Und Arbeit ist es für dich auch weniger.

von Michael (Gast)


Lesenswert?

Ja - jetzt musst du natürlich die Zeile "PORTA = 0b11111110;" unter 
"counter ++;" wieder rausnehmen. Das war nur testweise, ob die Funktion 
überhaupt aufgerufen wird.

Wenn die LED blinkt, sollten wir als nächstes rauskriegen, mit wieviel 
MHz dein Prozessor denn nun läuft.

von Michael (Gast)


Lesenswert?

Ich vermute mal, dass der Takt vom STK500 kommt. Ich kenne das STK500 
nicht wirklich, aber ich meine, da kann man per Software die Frequenz 
einstellen?

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

Karl Heinz Buchegger schrieb:
> Bitte häng deinen Code nicht als txt File an.
>
> Nimmm dein *.c File so wie es ist und häng es als Attachment an.
> Der Vorteil: Wir alle kommen in den Genuss von C-Syntax Highlighting.
> Und Arbeit ist es für dich auch weniger.

Vergleich mal deinen Anhang mit dem hier angehängten.
Das ist dann schon ein Unterschied.

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:
> Ich vermute mal, dass der Takt vom STK500 kommt. Ich kenne das STK500
> nicht wirklich, aber ich meine, da kann man per Software die Frequenz
> einstellen?

Es soll dir einfach sagen, wie lang die Hell Dunkel Zyklen sind.

Wahrscheinlich hat er 1Mhz und die LED brennt 1 Sekunde und ist 1 
Sekunde dunkel.

Das reicht dann schon. Für seine Zwecke genau genug. Du brauchst nur die 
Zahl, damit du damit rechnen kannst.

(BTW: ich würde dann auf 10 oder gar 100 ms IRQ Frequenz gehen. Mit 1 ms 
gehts mit dem counter sonst nur bis 65 Sekunden hoch und das wird ein 
wenig wenig werden.)
Was hast du dir fürs Entprellen vorgestellt? debounce-Makro?

von Sebastian H. (baschti)


Lesenswert?

mein Clock-generator ist auf 3,6864 MHz eingestellt

von Michael (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wahrscheinlich hat er 1Mhz und die LED brennt 1 Sekunde und ist 1
> Sekunde dunkel.

Daran zweifel ich nur ein bisschen, weil er in seinem Programm 3,6 MHz 
eingegeben hat und meinte, die Zahl durch Versuch ermittelt zu haben.


Karl Heinz Buchegger schrieb:
> ich würde dann auf 10 oder gar 100 ms IRQ Frequenz gehen.

Da hast du sicherlich recht.

Karl Heinz Buchegger schrieb:
> Was hast du dir fürs Entprellen vorgestellt? debounce-Makro?

Joah - da würde ich das Makro von Peter nehmen.

von Sebastian H. (baschti)


Lesenswert?

eine Blinkperiode dauert etwas über eine halbe Sekunde

von Michael (Gast)


Lesenswert?

ok - dann würde ich statt
OCR1AL = 125 - 1;

OCR1AH = 1;
OCR1AL = 204;

einstellen.

Dann sollte dein Blinkrhythmus eig. bei ca. 1 Sekunde an und 1 Sekunde 
aus liegen.

von Sebastian H. (baschti)


Lesenswert?

mach ich,
leute ich muss leider feierabend machen, ich bin dann morgen wieder 
hier.
auf jeden Fall mal vielen Dank für eure Hilfe soweit.
grüße Basti

von Michael (Gast)


Lesenswert?

schönen Feierabend

von Sebastian H. (baschti)


Lesenswert?

Danke! gleichfalls!

von Karl H. (kbuchegg)


Lesenswert?

@Michael

Die große Frage ist jetzt:
Hat er verstanden, was da jetzt abgeht?

Im Moment zweifle ich da noch. Wenn ich einen Vorschlag machen darf: 
Sieh zu, dass du ihm nahebringst wie ein Timer generell arbeitet (der 
zählt vor sich hin), was es mit diesen Compare Sachen auf sich hat (bei 
bestimmten Zählerständen kann man etwas auslösen lassen) und was ein CTC 
Modus ist (nicht nur auslösen, sondern den Timer auch auf 0 
zurücksetzen).

Im Idealfall ist er in der Lage, aus dem Verständnis der Arbeitsweise 
heraus, die Compare Konstanten zu berechnen.

Ich fänds schade, wenn er am Ende mit einem Programm dasteht und nicht 
weiß, wie es eigentlich funktioniert.

von Michael (Gast)


Lesenswert?

Karl Heinz, ich geb dir 100% Recht. Ich versuche ihm morgen mal zu 
erklären, was das Programm bis dorthin macht und wie der Timer generell 
funktioniert.

Danke dir für die Unterstützung!

von Peter D. (peda)


Lesenswert?

Schau Dir mal das hier an, das ist von der Aufgabenstellung sehr 
ähnlich, also leicht anzupassen:

Beitrag "Re: LED Programm"

Der Trick ist, daß die Mainloop mit einem Delay in einem festen 
Zeitraster ausgeführt wird. Dadurch kann man mit Zählern ganz leicht 
beliebige Zeitabläufe realisieren. Ganz ohne Interrupts und Timer.
Die 10ms sind so kurz, daß sie den Ablauf für den Menschen nicht merkbar 
behindern.


Peter

von Michael (Gast)


Lesenswert?

@Sebastian: Gibts dich noch? Oder habe ich meine Zeit ganz umsonst 
investiert?

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.