mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik binäre Uhr lässt sich nicht stellen.


Autor: Dominic K. (kuene)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen!

Ich bin ganz neu hier im Forum und ganz frisch in die Welt der Atmel 
Controller und deren Programmierung mittels AVR-Studio 4 und dem GCC 
Compiler eingestiegen.

Ich verwende einen Mega8, das Atmel Evaluationsboard von P*llin (v 2.0.1 
(Fertigmodul)) und PonyProg zum schreiben des Flashes.

Nach einigen Wochen Spielerrei wollte ich nun mal etwas "Sinnvolles" zu 
Tage bringen. Ein vermutlich typisches Anfängerprojekt: eine binäre Uhr.

Es funktioniert soweit auch, jedoch nicht beim Stellen der Uhr. Ich habe 
den Code angehängt und es geht mir um die letzte If-Konstruktion. Wenn 
PIND2 (also der 3. Pin des Registers) HIGH ist, soll eine Sekunde 
addiert werden und "ausgegeben" werden. Zuvor wird durch einen Interrupt 
an PD3 der Timer "deaktiviert" und die Millisekunden (welche natürlich 
keine sind ;-)) auf 0 gesetzt. Bei einem weitern Interrupt an PD3 soll 
die Uhr weiterlaufen.

Sobald ich an 3 Interrupte, blinkt alles wild vor sich hin. Nichts geht 
mehr. Lasse ich die Ifabfrage weg, funktioniert der Interrupt an PD3 wie 
gewollt. Am Board liegt es nicht, das habe ich einem anderem Programm 
geprüft. Wo ist der Fehler?

Der Einfacheit halber werden hier z.Z. nur die Sekunden ausgegeben.

Ich hoffe und bitte um Hilfe!

MFG
Küne


// Edit: Das mit dem Rücksetzen der Millisekunden fehlt hier. Sollte die 
Funktion außer der auftretenden Ungenauigkeit nicht beeinträchtigen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR (INT1_vect)
{
  if (set==0)
  {
    set=1;
    TIMSK = (0<<OCIE2);

So kann man nicht gezielt 1 Bit löschen.
Diese Anweisung ist identisch zu
   TIMSK = 0;

Eine 0 kannst du nach links schieben so oft du willst, das Ergebnis wird 
immer 0 bleiben.

Ein Bit gezielt löschen macht man so

    TIMSK &= ~(1<<OCIE2);

das setzt gezielt das Bit OCIE2 im Register TIMSK auf 0. Alle anderen 
Bits werden nicht verändert.


Deine ganze riesige switch-case Konstruktion lässt sich zusammenfassen 
zu

    PORTB = s % 8;
    PORTD = ( ( s / 8 ) << 5 ) | 0b00000100;

5 Seiten Code in 2 Zeilen eingestampft. Nicht schlecht. Du darfst dich 
nie zu solchen Verteilern hinreissen lassen. Es gibt da immer 
irgendwelche Formeln, du musst sie nur finden. Meistens sind es 
Divisionen, Modulo-Divisionen, ein paar Schiebeoperationen (um die Bits 
an die richtige Stelle zu schieben) und ein paar Veroderungen. Mit der 
Zeit wirst du ein Gefühl dafür entwickeln.
Und natürlich musst du binär zählen können. Das ist aber ziemlich 
trivial


if (set==1)
{

  DDRD &= ~(1<<2);
  PORTD |= (1<<2);


  if (PIND & (1<<2))
  {
    s++;
  }

Tja. Du hast hier etwas nicht bedacht.
> blinkt alles wild vor sich hin. Nichts geht mehr.

Was du siehst, ist die pure Power deines µC. Deine Abfrage

  if (PIND & (1<<2))
  {
    s++;
  }

erhöht s, SOLANGE die Taste gedrückt ist, und nicht 1 Erhöhung bei 1 
Tastendruck. Deine Hauptschleife arbeitet dein µC aber viele tausend mal 
in der Sekunde durch. So schnell kannst du eine Taste gar nicht drücken 
und wieder loslassen, dass du hier nur eine Erhöhung um 1 zustande 
bringen würdest.

(Apropos: Was liefern deine Tasten, wenn sie gedrückt werden. Eine 1 
oder eine 0. Üblich ist nämlich eine 0 und nicht eine 1. Damit macht 
deine if Abfrage: Solange die Taste NICHT gedrückt ist, erhöhe s. Und 
das viele tausend male in der Sekunde :-)

Du musst den Vorgang des Taste-drückens rausfiltern. Wann wird eine 
Taste gedrückt. Genau dann wenn sich der Zustand des Port-Pins ändert.
Wie kannst du das feststellen. Ganz einfach du merkst dir den Zustand 
und verlgeichst den neuen Pin Zustand mit dem Zustand im 
Schliefendurchgang unmittelbar davor.
int main()
{
   ....

   PinState = 0;

   while( 1==1 ) {

      ....

     
     NeuerState = ( PIND & ( 1<<2 ) );
     // Hat sich was geändert?
     if( PinState != NeuerState ) {
       // Ja!!!!

       mach dein Ding

       // und merk dir den aktuellen Zustand für den
       // nächsten Durchgang
       PinState = NeuerState;
     }
   }
}

Tja. Das Leben könnte so schön sein. Wenn Tasten nicht prellen würden.
http://www.mikrocontroller.net/articles/Entprellung

Autor: Dominic K. (kuene)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Vielen, vielen Dank für die doch sehr ausführliche Antwort! Ich habe 
dadurch viel gelernt!

Ich habe die änderungen Übernommen und beim debuggen beobachtet, dass 
das ganze wunderbar funktioniert, danke!

Jedoch muss irgendwo ein Hardwarefehler vorliegen. Den Käfer habe ich 
bereits ausgestauscht, der wars nicht. In einigen Testprogrammen ließen 
sich die Taster garnicht mehr abfragen. Igendetwas ist da komisch auf 
dem Board. Ich konnte mit den Testprogrammen nicht ermitteln ob es 
Active-High oder Active-Low Taster sind. Dem Schaltplan entnehme ich 
Taster die bei Druck durchlassen. (Schaltplan auf Seite 6: 
http://www.pollin.de/shop/downloads/D810038B.PDF) Die Jumper stecken 
auch ;-).

Zum Durchmessen bin ich noch nicht gekommen, da das Messgerät z.Z. 
verliehen ist. Ich habe aber auch festgestellt, dass an ausgeführten 
Pins am 39Pol-Stecker 5V anliegen, selbst wenn kein Controller auf dem 
Board steckt. Sehr komisch das Ganze.


Vielen Dank nocheinmal!

MFG

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dominic Künemund schrieb:
> Ich konnte mit den Testprogrammen nicht ermitteln ob es
> Active-High oder Active-Low Taster sind. Dem Schaltplan entnehme ich
> Taster die bei Druck durchlassen. (Schaltplan auf Seite 6:
> http://www.pollin.de/shop/downloads/D810038B.PDF) Die Jumper stecken
> auch ;-).

Sie sind laut Schaltplan high-aktiv, wenn man die Kondis (C17..19) 
rausnimmt.
Mit Kondis sind es CPU-Absturztaster.


Peter

Autor: Dominic K. (kuene)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Mit Kondis sind es CPU-Absturztaster.

Warum?

Autor: Dominic K. (kuene)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt scheint der Controller hinüber zu sein. Ports die auf High gesetzt 
sind, flackern mit ca. 10 Hz als würde er sich immer wieder zurück 
setzen.

Im Programm wurde nicht viel verändert, die Absturztaster habe ich auch 
mal getrennt (Jumper), geht nicht. War das Board eventuell eine 
Fehlinvestition?

MFG

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.mikrocontroller.net/articles/Pollin_ATM...

http://www.mikrocontroller.net/articles/AVR_Checkliste


R7 R8 R11 C19 C17 C18 entfernen und die Taster gegen Masse schalten.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.