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


von peter (Gast)


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:
1
$regfile = "2313def.dat"
2
$crystal = 12000000
3
$lib "mcsbyte.lbx"
4
5
6
7
8
Config Pinb.2 = Output
9
Portd = &B0100000
10
11
Dim Modus As Integer
12
13
Do
14
15
   If Pind.5 = 0 Then
16
         Modus = Modus + 1
17
   Else
18
19
   End If
20
21
22
   If Modus = 1 Then
23
      Portb.2 = 1
24
   End If
25
26
   If Modus = 2 Then
27
28
      Toggle Portb.2
29
      Wait 1
30
      Toggle Portb.2
31
      Wait 1
32
   End If
33
34
   If Modus = 3 Then
35
      Modus = 0
36
      Portb.2 = 1
37
   End If
38
                                                '//Weiße LED
39
40
Loop

Danke

von ES (Gast)


Lesenswert?

Es gibt ein www.bascom-forum.de
Da ist deine Anfrage richtig aufgehoben.

von peter (Gast)


Lesenswert?

Danke ES.

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

von Roland Z. (r-zimmermann)


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 :)

von peter (Gast)


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

von Karl H. (kbuchegg)


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'.

von peter (Gast)


Lesenswert?

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

von Roland Z. (r-zimmermann)


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

von peter (Gast)


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

von Roland Z. (r-zimmermann)


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

von peter (Gast)


Lesenswert?

Ja vielen dank ! Sehr nett von dir.

von Roland Z. (r-zimmermann)


Angehängte Dateien:

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
1
$regfile = "attiny2313.dat"
2
$crystal = 12000000
3
$lib "mcsbyte.lbx"
4
$hwstack = 32
5
$swstack = 10
6
$framesize = 40
7
8
Config Portb.2 = Output                                     ' LED Ausgang
9
Config Portd.5 = Input                                      ' Taster Eingang
10
Portd.5 = 1                                                 ' Eingangs Pull-Up Widerstand Einschalten
11
12
Led Alias Portb.2                                           ' Alias-Namen zuweisen (besser wenn du Ports naher aendern willst)
13
Taster Alias Portd.5                                        ' wie oben :)
14
15
16
Config Timer1 = Timer , Prescale = 256                      ' Timer einrichten mit Vorteiler des Taktes, Blinkfrequenz kann hier geaendert werden
17
Start Timer1                                                ' Timer1 starten
18
On Timer1 Interrupt1                                        ' Interrupt Einrichten wenn Timer1 ueberläuft wird
19
Enable Interrupts                                           ' zum angegebenen Programmteil gesprungen
20
21
Config Debounce = 30                                        ' Entprellzeit in ms fuer das Debounce
22
23
Dim Modus As Byte                                           ' Statusvariable
24
Dim Blinken As Bit                                          ' Blink-Variable bedient von Timer1 :)
25
26
' Mainloop
27
28
Do
29
Debounce Pind.5 , 0 , Taster1 , Sub                         ' Bei Tastendruck wird jeweils EINMAL in die Subroutine gesprungen
30
If Modus = 0 Then Led = 1                                   ' LED einschalten wenn Modus = 0
31
If Modus = 1 Then Led = Blinken                             ' LED blinkt wenn Modus = 1
32
If Modus = 3 Then Modus = 0                                 ' Ruecksetzen wenn ueberlauf
33
Loop
34
35
36
37
' Subroutinen
38
39
Taster1:                                                    ' wird angesprungen wenn der Taster gedrueckt wird
40
Modus = Modus + 1                                           ' Tastervariable inkrementieren
41
Return                                                      ' Ruecksprung ins Hauptprogramm
42
43
' Interrupt-Routine von Timer1
44
45
Interrupt1:                                                 ' hier wird immmer hingesprungen wenn der Timer1 ueberlaeuft
46
Toggle Blinken                                              ' Blink-Variable wird mit jedem Aufruf getoggelt (=Umgeschaltet)
47
Return                                                      ' Ruecksprung ins hauptprogramm
48
49
50
End

von peter (Gast)


Lesenswert?

Ich werde das morgen austesten !

Vielen dank Roland :) Sehr freundlich.

von Roland Z. (r-zimmermann)


Lesenswert?

Hallo Peter,

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

von peter (Gast)


Lesenswert?

Was machst du denn Beruflich, wenn ich fragen darf ?

von Roland Z. (r-zimmermann)


Lesenswert?

Entwicklung von Steuerungen von Maschinen, sowie instandhaltung dieser 
dinger im Industriebereich.

von peter (Gast)


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

von Roland Z. (r-zimmermann)


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

von peter (Gast)


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

von Roland Z. (r-zimmermann)


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

von Roland Z. (r-zimmermann)


Angehängte Dateien:

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
1
$regfile = "attiny2313.dat"
2
$crystal = 12000000
3
$hwstack = 32
4
$swstack = 10
5
$framesize = 40
6
7
Config Portb.2 = Output                                     ' LED Ausgang
8
Config Portd.5 = Input                                      ' Taster Eingang
9
Portd.5 = 1                                                 ' Eingangs Pull-Up Widerstand Einschalten
10
11
Led Alias Portb.2                                           ' Alias-Namen zuweisen (besser wenn du Ports naher aendern willst)
12
Taster Alias Portd.5                                        ' wie oben :)
13
14
15
Config Timer1 = Timer , Prescale = 256                      ' Timer einrichten mit Vorteiler des Taktes, Blinkfrequenz kann hier geaendert werden
16
Start Timer1                                                ' Timer1 starten
17
On Timer1 Isr                                               ' Interrupt Einrichten wenn Timer1 ueberläuft wird
18
Enable Timer1                                               ' interrupt Fuer Timer1 Freigeben
19
Enable Interrupts                                           ' zum angegebenen Programmteil gesprungen
20
21
Config Debounce = 30                                        ' Entprellzeit in ms fuer das Debounce
22
23
Dim Modus As Byte                                           ' Statusvariable
24
Dim Blinken As Byte                                         ' Blink-Variable bedient von Timer1 :)
25
Dim Test As Byte
26
27
' Mainloop
28
29
Do
30
Debounce Pind.5 , 0 , Taster1 , Sub                         ' Bei Tastendruck wird jeweils EINMAL in die Subroutine gesprungen
31
If Modus = 0 Then Led = 1                                   ' LED einschalten wenn Modus = 0
32
If Modus = 1 Then Led = Blinken                             ' LED blinkt wenn Modus = 1
33
If Modus = 2 Then Modus = 0                                 ' Ruecksetzen wenn ueberlauf
34
Print Blinken
35
Print Timer1
36
Waitms 200
37
Loop
38
39
40
41
42
' Subroutinen
43
44
Taster1:                                                    ' wird angesprungen wenn der Taster gedrueckt wird
45
Modus = Modus + 1                                           ' Tastervariable inkrementieren
46
Return                                                      ' Ruecksprung ins Hauptprogramm
47
48
' Interrupt-Routine von Timer1
49
50
Isr:                                                        ' hier wird immmer hingesprungen wenn der Timer1 ueberlaeuft
51
Blinken = Blinken + 1                                       ' Variable hin und her schalten
52
Return                                                      ' Ruecksprung ins hauptprogramm
53
54
55
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

von peter (Gast)


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

von peter (Gast)


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

von Roland Z. (r-zimmermann)


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

von peter (Gast)


Lesenswert?

hi roland !

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

peter

von Roland Z. (r-zimmermann)


Lesenswert?

Hallo Peter,

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

von Roland Z. (r-zimmermann)


Lesenswert?

Hmm,

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

Roland

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.