mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Source Code Problem (Attiny2313 BASCOM)


Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen alle. ! Ich bin es mal wieder :).

Habe jetzt meine Platine erweitert, indem ich einen Taster dran 
geschlossen habe der auch funktioniert. Pullup-Widerstände sind intern 
aktiviert.

Was ich möchte:

Wenn man einmal (Modus=1) auf die Taste drückt, soll die LED ständig 
leuchten.
Wenn man nochmal drückt (Modus=2), soll die LED in 1'er sek. Takt 
leuchten.
Wenn man nochmal drückt (Modus=3), wird sowas wie ein "reset" realisiert 
und die LED leuchtet wieder ständig.

Aber irgendwie klappt das nicht so, wie ich es möchte und kann meinen 
Fehler auch nicht finden.

Hier ist der Code:
$regfile = "2313def.dat"
$crystal = 12000000
$lib "mcsbyte.lbx"




Config Pinb.2 = Output
Portd = &B0100000

Dim Modus As Integer

Do

   If Pind.5 = 0 Then
         Modus = Modus + 1
   Else

   End If


   If Modus = 1 Then
      Portb.2 = 1
   End If

   If Modus = 2 Then

      Toggle Portb.2
      Wait 1
      Toggle Portb.2
      Wait 1
   End If

   If Modus = 3 Then
      Modus = 0
      Portb.2 = 1
   End If
                                                '//Weiße LED

Loop


Danke

Autor: ES (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt ein www.bascom-forum.de
Da ist deine Anfrage richtig aufgehoben.

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ES.

Aber ich warte einfach mal, es gibt bestimmt einige Personen die mir 
weiter helfen können.

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

was mir auffällt:
Du arbeitest mit dem Wait-Befehl, der hält dir das Programm an, wird in 
dieser Zeit ne Taste gedrückt bekommt das Programm das nicht mit. 
Verwende Statt des Wait-Befehls lieber nen Timer den du durchlaufen 
lässt, das hält dein Programm nicht an.
Du verwendest keine Tastenentprellung, solltest du aber nehmen das 
Programm wird sonst unzuverlässig und "springt". Verwende am besten den 
"Debounce" Befehl, in der Bascom-Hilfe steht ein Beispiel.
Wie ist der Pin des Tasters genau beschaltet? Nimmst du einen externen 
Pull-Up und der Taster zieht den Pin nach GND oder nimmst du den 
Internen R? Schreibe die Definitionen im Programm am Anfang lieber mal 
aus, das erleichtert die Fehlersuche ungemein.

Beschreibe mal genau was genau nicht funktioniert dann kann ich dir 
sicherlich helfen.

Roland :)

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Roland :)

Mein Schalter benutzt den internen PullUp Widerstand und ist so 
angeschlossen:
PD5------Taster----->GND


Also wenn ich auf den Taster einmal drücke, leuchtet diese ganz schnell 
und schwach und geht dann über zu den Blink Modus...


Kannst du meinen Source Code etwas bearbeiten ? Habe bis jetzt noch nie 
mit Timer'n gearbeitet.

Danke dir

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

Bewertung
0 lesenswert
nicht lesenswert
Dein Programm wird (mit Ausnahme des Falles, wenn Modus den
Wert 2 hat) die do - Loop ein paar 10-tausend mal pro
Sekunde durchlaufen. Wenn also der Taster aus dem Grundzustand
heraus gedrückt ist, erhöhst du Modus um 1. Die darauffolgende
Abfrage erkennt dies auch und schaltet die LED ein. Aber:
Nach ein paar weiteren µSekunden beginnt die Schleife schon
wieder von vorne, die Taste ist immer noch gedrückt und dein
Programm erkennt schon wieder einen Tastendruck und schaltet
weiter in den Modus 2.

Du musst dir darüber im klaren sein, dass dein µC viel zu schnell
arbeitet, als dass du mit einem simplen

   If Pind.5 = 0 Then

einen einzelnen Tastendruck erkennen kannst. Selbst wenn du
ultraschnelle Finger hast, wird dein Programm diese Abfrage
viele tausend male in der Sekunde abarbeiten und demenstprechend
erkennt dein Programm viele tausend 'Tastendrücke'.

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das mit dem Geschwindigkeitsproblem ist mir auch eingefallen, war 
mir aber nicht so sicher. Was mach ich nun ? :)

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

ich werde dein Programm etwas bearbeiten und hier wieder Posten. Kann 
aber etwas dauern da ich heute erst in der Mittagspause dazu komme.

Was Karl Heinz Buchegger schreibt ist ein weiterer Punkt auf der Liste, 
der uC ist so schnell daß er die Taste mehrere Tausend mal pro Sekunde 
als gedrückt erkennt und rasend schnell die Modus-Variable 
weiterschaltet (ok, zugegeben die Wait befehle bremsen das etwas du 
bleibst immer bei denen hängen)
Der Debounce-Befehl verhindert die dann auch da der nur auf die Flanke 
und nicht auf den Zustand reagiert.
Was für eine Taktquelle verwendest du? Ext. Quarz?

Roland

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze einen externen Quarz (das Teil mit zwei Beinen und der 
glänzenden Metallgehäuse :P ). Dieser hat 12 MHZ.

Danke dir !

peter

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK,

ich habe in der Mittagspause schon mal das Programm auf Timer und 
entprellung erweitert, sobald ich fertig bin (heute im laufe des 
Nachmittags) poste ich das Proggie hier. Muß leider nebenher noch 
Arbeiten :D

Roland

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja vielen dank ! Sehr nett von dir.

Autor: Roland Z. (r-zimmermann)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So,

hier der Programmcode. Es ist zwar kein schönheitswettbewerb da nur 
schnell zusammengetippt aber er sollte laufen. Leider habe ich grade 
keinen Tiny2313 mit Testplatine da zum testen, könnte ich aber sonst 
morgen in der firma schnell auf dem Breadboard zusammenstöpseln.
Wenn jemand einen Fehler findet (auch ich bin nicht perfekt :) immer her 
damit.
Die "Blinkfrequenz" kann durch ändern des Vorteilers des Timer1 geändert 
werden oder wenns genau sein soll durch vorladen des Timers mit einem 
Wert.
Wenn was unklar ist Frag, dafür sind Foren ja nun mal da :D

Roland
$regfile = "attiny2313.dat"
$crystal = 12000000
$lib "mcsbyte.lbx"
$hwstack = 32
$swstack = 10
$framesize = 40

Config Portb.2 = Output                                     ' LED Ausgang
Config Portd.5 = Input                                      ' Taster Eingang
Portd.5 = 1                                                 ' Eingangs Pull-Up Widerstand Einschalten

Led Alias Portb.2                                           ' Alias-Namen zuweisen (besser wenn du Ports naher aendern willst)
Taster Alias Portd.5                                        ' wie oben :)


Config Timer1 = Timer , Prescale = 256                      ' Timer einrichten mit Vorteiler des Taktes, Blinkfrequenz kann hier geaendert werden
Start Timer1                                                ' Timer1 starten
On Timer1 Interrupt1                                        ' Interrupt Einrichten wenn Timer1 ueberläuft wird
Enable Interrupts                                           ' zum angegebenen Programmteil gesprungen

Config Debounce = 30                                        ' Entprellzeit in ms fuer das Debounce

Dim Modus As Byte                                           ' Statusvariable
Dim Blinken As Bit                                          ' Blink-Variable bedient von Timer1 :)

' Mainloop

Do
Debounce Pind.5 , 0 , Taster1 , Sub                         ' Bei Tastendruck wird jeweils EINMAL in die Subroutine gesprungen
If Modus = 0 Then Led = 1                                   ' LED einschalten wenn Modus = 0
If Modus = 1 Then Led = Blinken                             ' LED blinkt wenn Modus = 1
If Modus = 3 Then Modus = 0                                 ' Ruecksetzen wenn ueberlauf
Loop



' Subroutinen

Taster1:                                                    ' wird angesprungen wenn der Taster gedrueckt wird
Modus = Modus + 1                                           ' Tastervariable inkrementieren
Return                                                      ' Ruecksprung ins Hauptprogramm

' Interrupt-Routine von Timer1

Interrupt1:                                                 ' hier wird immmer hingesprungen wenn der Timer1 ueberlaeuft
Toggle Blinken                                              ' Blink-Variable wird mit jedem Aufruf getoggelt (=Umgeschaltet)
Return                                                      ' Ruecksprung ins hauptprogramm


End

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werde das morgen austesten !

Vielen dank Roland :) Sehr freundlich.

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

keine Ursache ich helfe gerne dafür sind Foren ja da :D

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was machst du denn Beruflich, wenn ich fragen darf ?

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entwicklung von Steuerungen von Maschinen, sowie instandhaltung dieser 
dinger im Industriebereich.

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow hört sich cool an.

Ich habe jetzt den Source Code drauf gebrannt und ihn getestet und habe 
folgendes festgestellt:

Wenn das Programm "startet" leuchtet die LED.  Das ist richtig.
Wenn man einmal klick ist die LED aus und blinkt auch nicht...das mit 
dem Reset funktioniert. Könnte das Problem an dem Prescaler liegen ? 
Kann man das ausrechnen wie groß dieser Wert sein muss, wenn man mit 12 
MHZ 1 sek erreichen möchte ?

Danke

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

hmmm, vielleicht hab ich ja beim Timer was übersehen, ich schau gleich 
noch mal rein :)

Den Timer berechnest du ganz einfach:

Taktfrequenz des uC  Prescaler  65535 (Bei Timer1 mit 16bit)
das was da raus kommt ist die Zeit in sec. die der Braucht um einmal 
hochzuzählen.

Roland

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aso danke gut zu wissen... ich versuche gerade mein Gerät in das Gehäuse 
rein zu bekommen... naja wenn es dich interessiert.. hab ich mir eine 
Front-Fahrradbeleuchtung gebaut... die alte war kaputt und nicht so hell 
genug und hab mir das Gehäuse genommen, bischen rumgebastelt. Ich 
benutze eine superhelle weiße LED die sehr schönes Licht macht und 
jeweils links und rechts zwei blaue LEDs.. sieht vom weiten cool aus. 
Damit man mich besser sieht, soll das ganze blinken, wenn ich möchte 
(Taster=Modus) und darum hab ich das mit dem Attiny2313 realisiert und 
wenn ich was anderes will, einfach das Verhalten der LEDs 
umprogrammieren ;).

Danke

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

sorry ich bin eben erst an das Proggie drangehockt, bin vorher wegen 
leichter Arbeitsüberlastung nicht dazu gekommen. :)

Hmm Interessante sache das, ich hätte aber noch ein paar 
Anmerkungen/Fragen dazu:

Wie wird die schaltung versorgt? Akkus, Batterien oder aus dem 
Fahrraddynamo.
Was für LEDs verwendest du, was für einen Strom wollen die haben? Wenn 
du mehr als 20mA aus einem Portpin des uC rausziehst machst du den auf 
Dauer kaputt. Lieber nen Transistor als "Verstärker" hintendran hängen. 
Falls du nur 20mA ziehst (pro LED) beachte das Maximum der VCC und 
GND-Pins, der ATtiny2313 kann soweit ich weiß max. 100mA. Genaueres 
steht im Datenblatt unter "Electrical Caracteristics".

Wenn ich das Proggie fertig habe poste ich das wieder hier :)

Roland

Autor: Roland Z. (r-zimmermann)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo hier der Programmcode, habe diesen nochmals probiert und muß zu 
meiner Schande gestehen daß ein kleiner Fehler von mir drin war. Es ist 
alles korrekt eingestellt, aber ich habe vergessen dem Timer1 zu 
erlauben interrupts auszulösen :)
Sorry kann mal in der Hektik vorkommen :D
$regfile = "attiny2313.dat"
$crystal = 12000000
$hwstack = 32
$swstack = 10
$framesize = 40

Config Portb.2 = Output                                     ' LED Ausgang
Config Portd.5 = Input                                      ' Taster Eingang
Portd.5 = 1                                                 ' Eingangs Pull-Up Widerstand Einschalten

Led Alias Portb.2                                           ' Alias-Namen zuweisen (besser wenn du Ports naher aendern willst)
Taster Alias Portd.5                                        ' wie oben :)


Config Timer1 = Timer , Prescale = 256                      ' Timer einrichten mit Vorteiler des Taktes, Blinkfrequenz kann hier geaendert werden
Start Timer1                                                ' Timer1 starten
On Timer1 Isr                                               ' Interrupt Einrichten wenn Timer1 ueberläuft wird
Enable Timer1                                               ' interrupt Fuer Timer1 Freigeben
Enable Interrupts                                           ' zum angegebenen Programmteil gesprungen

Config Debounce = 30                                        ' Entprellzeit in ms fuer das Debounce

Dim Modus As Byte                                           ' Statusvariable
Dim Blinken As Byte                                         ' Blink-Variable bedient von Timer1 :)
Dim Test As Byte

' Mainloop

Do
Debounce Pind.5 , 0 , Taster1 , Sub                         ' Bei Tastendruck wird jeweils EINMAL in die Subroutine gesprungen
If Modus = 0 Then Led = 1                                   ' LED einschalten wenn Modus = 0
If Modus = 1 Then Led = Blinken                             ' LED blinkt wenn Modus = 1
If Modus = 2 Then Modus = 0                                 ' Ruecksetzen wenn ueberlauf
Print Blinken
Print Timer1
Waitms 200
Loop




' Subroutinen

Taster1:                                                    ' wird angesprungen wenn der Taster gedrueckt wird
Modus = Modus + 1                                           ' Tastervariable inkrementieren
Return                                                      ' Ruecksprung ins Hauptprogramm

' Interrupt-Routine von Timer1

Isr:                                                        ' hier wird immmer hingesprungen wenn der Timer1 ueberlaeuft
Blinken = Blinken + 1                                       ' Variable hin und her schalten
Return                                                      ' Ruecksprung ins hauptprogramm


End


Poste mal was für eine Spannungsquelle du verwendest. Je nach 
Stromversorgung solltest du in den Fusebits den Brown-Out einschalten 
damit der uC nicht "hängenbleibt" wenn die Versorgungsspannung 
zusammenbricht. Den Watchdog würde ich im Programmcode auch noch 
einschalten und konfigurieren der "fängt" den uC nach einem eventuellen 
Absturz wieder und startet den neu... :D

Je nach Schaltungsbelegung kannst du dir den Ein/Aus Schalter sparen 
wenn du den uC in den Power-Down Mode schickst (Der uC geht quasi pennen 
und klemmt vorher allen angeschlossenen Verbrauchern an den Portpins den 
Saft ab) der Strom verbrauch ist dann im uA-Bereich. :) "Aufwecken" 
kannst du diesen dann mittels eines "Level-Change" interrupt, d.h. wenn 
sich an dem besagten Pin was Tut wacht der uC wieder auf.

Roland

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Roland !

Danke für dein Source Code, diesen werde ich es morgen testen können.

Ich benutze 3 mal 1.5V Batterien und habe bereits einen Ein/Aus Schalter 
dran geschlossen :P. Und natürlich habe ich diese super hellen LED's, 
welche bis zu 30mA nehmen, nicht direkt an den µC angeschlossen sondern 
habe dafür den ULN 2003AC (7 Darlington Transistor Array) benutzt ;)

Also:

µC Output---------Input ULN 2003AC | Output ULN 2003AC------>LED

Der ULN 2003 AC wird dann direkt mit der Batterie betrieben, wie der 
Attiny2313...

Das dürfte den Attiny2313 nich schaden.

peter

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Roland !

Ok habs getestet, es funktioniert einwandfrei !

Danke.

Wenn ich den Prescaler Wert verkleine, blinkt die LED zwar schneller, 
aber nicht so schön regelmäßig, sondern sehr variierend.... könnte man 
das verhinden, wenn ja, wie ?

schönen tag noch.

peter

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

schön das das Proggie geht :D Auf was hast du den Prescaler verändert, 
Poste bitte mal beispiele. Normalerweise rennt der Timer immer durch und 
es sollte keine unregelmäßigkeiten geben.
Bitte poste den Programmcode (nur der ausschnitt wo du was geändert hast 
reicht) und eine genaue beschreibung.

Wenn du die Zeit ganz genau einstellen willst (als sehr genau) dann 
solltest du den CTC-Mode des Timers verwenden. Damit sind auch "krumme" 
zwischenwerte der Timerzeiten möglich.

Roland :D

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi roland !

ich hab den Prescale Wert nur geändert, also 64 ma getestet mehr auch 
nicht ^^

peter

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

was meinst du genau damit daß die Zeiten variieren?
Kannst du daß genauer beschreiben?

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm,

hat das jetzt doch noch geklappt? Da du dich hier nicht mehr meldest 
betrachte ich das mal als erledigt :)

Roland

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.