Attiny13 erstes Programm. Hilfe gesucht !

#4151678
Lesenswert?

Moin moin,
zuerst mal bin ich völliger Newbie in diesem Bereich und habe nicht 
wirklich viel Erfahrung im Bereich programmieren und würde mich über 
hilfreiche Beitrage die mich weiterbringen sehr freuen !

Ich möchte gerne über meinen Attiny13 2 Ausgangskarten(Pollin Bausatz) 
über einen Eingang(Taster) steuern, mit Folgender Funktion:

Wenn die Schaltung Spannung bekommt, soll als erstes Ausgangskarte 1 
einmal 5 Sekunden lang angesteuert werden. Wenn ich nun meinen Schalter 
betätige, soll Ausgangskarte 2 5 Sekunden angesteuert werden. Wenn ich 
nun meinen Schalter erneut betätige soll wiederum Ausgangskarte 1 5 
Sekunden angesteuert werden. Dies soll immer im Wechsel so weiter gehen. 
Wichtig ist, das die Steuerung beim Start immer mit der selben 
Ausgangskarte anfängt.

Ist dies einfach und mit einem Attiny13 zu realisieren ? Kann mir jemand 
bei dem Programm auf die Sprünge helfen ?

MFG Steve
(Firma: matzetronics) #4151687
Lesenswert?

Steffen Ebeling schrieb:
> Kann mir jemand
> bei dem Programm auf die Sprünge helfen ?

Starte hier:
https://www.mikrocontroller.net/articles/AVR
und mach dann mit dem AVR Tutorial weiter. Wenn du eine LED blinken 
lassen kannst, bist du in der Lage Ausgangspins zu steuern. Weiterhin 
brauchst du für dein Projekt eine Art Uhr, die beim AVR Timer genannt 
wird. Und du musst Eingangspins lesen können.
Das ist erstmal die Grundlage. Feinheiten sind z.B. die Entprellung 
deines Schalters und das Speichern seines Zustandes, damit du die 
Bedingung deines Projekts erfüllst.
Gast #4151804
Lesenswert?

Steffen E. schrieb:
> zuerst mal bin ich völliger Newbie in diesem Bereich

Dann ist der Ratschlag meines Vorschreibers sehr zu beherzigen. Nutze 
die genannten Lernhilfen!

> Ist dies einfach und mit einem Attiny13 zu realisieren

Logo.

> Kann mir jemand
> bei dem Programm auf die Sprünge helfen ?

Jetzt ist die erste Frage: Welche Programmiersprache?
Ich empfehle da Assembler, da Du den Controller und dessen Möglichkeiten 
dann mit dem Tiny13 Datenblatt in der Hand gleich von grundauf 
kennenlernst.

> Wichtig ist, das die Steuerung beim Start immer mit der selben
> Ausgangskarte anfängt.

Das wird schon dadurch sichergestellt, daß Dein Programm immer von der 
gleichen Stelle aus anfängt und Du dann eben Deine vorgesehene Karte 
samt eines sogenannten Hardware-Timers aktivierst.

> einmal 5 Sekunden lang

Für sowas brauchst Du diesen Timer des Tiny13.
Der wird in Abhängigkeit von der Taktfrequenz des Controllers zum 
Beispiel so eingestellt, daß er nach Aktivierung durch die Tasterabfrage 
los- und bei 5 Sekunden "überläuft" und dabei was sinnvolles auslöst- 
wie eben das Deaktivieren der aktuellen Karte.

Die Tasterabfrage aktiviert neben dem Timer natürlich auch die nächste, 
richtige Karte. Du hast nur zwei, also kann man sich den aktuellen 
Zustand in einer binären Variable merken (beim Controllerstart auf 0 
gesetzt). Die wird bei Timerablauf einfach noch mit invertiert, damit 
die Tasterabfrage beim nächsten Auslösen wieder die andere Karte 
aktivieren kann.

So weit so einfach- der ganz grobe Ablauf.
Eine solche Taster-Anwendung enthält aber oft noch eine besondere 
Herausforderung: Mechanische Taster prellen. Das heißt, sie können in 
kürzester Zeit mehrfach auslösen. Mit Deinem gemächlichen Vorhaben hast 
Du aber Glück: Das muß Dich nicht interessieren. Die Tasterabfrage tut 
bei aktiviertem 5s-Timer einfach nix...
Gast #4151840
Lesenswert?

Hi
Moin moin,
zuerst mal bin ich völliger Newbie in diesem Bereich und habe nicht
wirklich viel Erfahrung im Bereich programmieren und würde mich über
hilfreiche Beitrage die mich weiterbringen sehr freuen !
Nun, so allgemein wie du dein Anliegen vorbringst, liest sich das wie:" 
Ich brauch ein Programm, wer macht mir das". Das ist jetzt nicht bös 
gemeint, aber es wird ein weiter Weg, bis du ein Programm selbst 
schreiben kannst. Sicherlich hast du den bereits erwähnten Hinweis auf 
die Tutorials gesehen. Die sind gut verständlich und für Übungen bestens 
geeignet. So lernst du die Controller kennnen. Zur Sprache kann ich auch 
noch auf einen Beitrag im Forum von WWW.AVR-Praxis.de unter der Rubrik 
FAQ verweisen. Dort findest du u.A. im Beitrag "keine Angst vor 
Assembler" sicherlich alle benötigten Bausteine für deinen 
Programmwunsch ausführlich beschrieben.
Gruß oldmax
#4151848
Lesenswert?

Moby schrieb:
> Jetzt ist die erste Frage: Welche Programmiersprache?
> Ich empfehle da Assembler, da Du den Controller und dessen Möglichkeiten
> dann mit dem Tiny13 Datenblatt in der Hand gleich von grundauf
> kennenlernst.

Kommt drauf an wie weit du einsteigen willst.
Assembler ist schon eine Hausnummer mit der du dich gewaltig 
beschäftigen muss.
Schau mal nach "Arduino"!
Damit kannst du das nach zwei Tagen realisieren. Nimmst du jetzt noch 
einen "Arduino Nano", kannst du ihn nach bestandenen Tests in eine 
Schaltung auf Lochraster Platinen übernehmen. Wobei ich dir die 
Lochstreifenraster empfehle.
Wenn du mit C programmieren willst, bietet sich auch der ATmega328 an 
(der auf dem Nano ist), weil du z.B. dieses Programm dann locker auf 
einen ATtiny10 ohne große Änderungen laufen lassen kannst.
http://www.ebay.de/itm/Nano-V3-0-ATmega328-16M-5V-Micro-controller-CH340G-board-for-arduino-/371179047627?pt=LH_DefaultDomain_77&hash=item566bfecacb
(Firma: matzetronics) #4151860
Lesenswert?

foldi, der TE möchte das alles gerne mit dem ATTiny13 realisieren, was, 
wie wir uns schon einig waren, ohne jedes Problem möglich ist, sonst 
hätte ich auch gleich protestiert.
Das geht in Assembler oder in C, bei einem so überschaubaren Projekt ist 
ASM das simpelste und man lernt den MC richtig gut kennen.
Der Tiny10 ist schon wieder eine andere Liga, die TPI Programmierung 
kann nicht jeder Programmer und man muss mit den Pins ganz schön 
haushalten. Hier würde es gerade reichen...
Da wir nichts darüber wissen, was der TE für Tools hat, nehmen ich mal 
an, das der Tiny13 gerade da ist und programmiert werden kann.
#4151864
Lesenswert?

Ich hab da grad mal Bock drauf:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
#define KARTE1    PB0
5
#define KARTE2    PB1
6
#define TASTER    PB2
7

8

9

10
int main(void)
11
{
12
  // Timer
13
  TCCR0A |= (1<<WGM00) | (1<<WGM01);    // CTC
14
  OCR0A = 149;              // 9,6MHz / ((149+1) * 64) = 1KHz
15
  TIMSK0 |= (1<<OCIE0A);          // Capture Interrupt
16
  TCCR0B |= (1<<CS00) | (1<<CS01);    // Prescaler 64
17
  
18
  // IOs
19
  PORTB = 0;
20
  DDRB |= (1<<KARTE1) | (1<<KARTE2);
21
  PORTB |= (1<<TASTER);          // Pull-up enable
22
  
23
  // global Interrupt enable
24
  sei();
25
  
26
  
27
    while(1){;
28
        //Nothing to Do 
29
    }
30
}
31

32
/* 1kHz */
33
ISR (TIM0_COMPA_vect)
34
{
35
  static uint16_t debounce = 0;
36
  static uint16_t OnTime = 5000;
37
  static uint8_t Kartenwahl = 0;
38
  
39
  if (debounce) debounce--;
40
  
41
  if (!(PINB & (1<<TASTER)) && !debounce){
42
    debounce = 100;
43
    OnTime = 5000;
44
    Kartenwahl++;
45
  }
46
  
47
  if (OnTime){
48
    switch (Kartenwahl%2){
49
    case 0: PORTB |= (1<<KARTE1); break;
50
    case 1: PORTB |= (1<<KARTE2); break;
51
    default: break;
52
  }else{
53
    PORTB &= ~( (1<<KARTE2) | (1<<KARTE1) );
54
  }
55
}
Viel Spass damit
#4152873
Lesenswert?

Ingo Less schrieb:

> Edit:
> Ja sorry, das Decrement fehlt :(
>
>
1
>  if (OnTime) OnTime--;
2
>

Einen hab ich noch.
Ich hoff, ich hab mich da jetzt nicht vertan.

Wenn während der 5 Sekunden der Taster erneut betätigt wird, kann es 
sein, dass beide Karten angesteuert werden.

Obwohl: der TO hat ja nicht verraten, was in diesem Fall die korrekte 
Reaktion wäre.
Genauso wie er nicht verraten hat, ab wann die Zeit laufen soll. Ab 
niederdrücken oder ab loslassen. Kann man durch gedrückt halten des 
Tasters die 5 Sekunden verlängern oder nicht?
#4152964
Lesenswert?

Moin,
vielen Dank erst mal für die vielen Kommentare ! :)

Matthias Sch. schrieb:
> Starte hier:
> https://www.mikrocontroller.net/articles/AVR
> und mach dann mit dem AVR Tutorial weiter. Wenn du eine LED blinken
> lassen kannst, bist du in der Lage Ausgangspins zu steuern. Weiterhin
> brauchst du für dein Projekt eine Art Uhr, die beim AVR Timer genannt
> wird. Und du musst Eingangspins lesen können.

Ja habe mich auch schon eine Weile mit den Ganzen Grundlagen beschäftig. 
Da das alles für mich Neuland ist, finde ich das es sehr viele 
Informationen auf einmal sind.

Ingo Less schrieb:
> Ich hab da grad mal Bock drauf:#include <avr/io.h>
> #include <avr/interrupt.h>
>
> #define KARTE1    PB0
> #define KARTE2    PB1
> #define TASTER    PB2
>
> int main(void)
> {
>   // Timer
>   TCCR0A |= (1<<WGM00) | (1<<WGM01);    // CTC
>   OCR0A = 149;              // 9,6MHz / ((149+1) * 64) = 1KHz
>   TIMSK0 |= (1<<OCIE0A);          // Capture Interrupt
>   TCCR0B |= (1<<CS00) | (1<<CS01);    // Prescaler 64
>
>   // IOs
>   PORTB = 0;
>   DDRB |= (1<<KARTE1) | (1<<KARTE2);
>   PORTB |= (1<<TASTER);          // Pull-up enable
>
>   // global Interrupt enable
>   sei();
>
>
>     while(1){;
>         //Nothing to Do
>     }
> }
>
> /* 1kHz */
> ISR (TIM0_COMPA_vect)
> {
>   static uint16_t debounce = 0;
>   static uint16_t OnTime = 5000;
>   static uint8_t Kartenwahl = 0;
>
>   if (debounce) debounce--;
>
>   if (!(PINB & (1<<TASTER)) && !debounce){
>     debounce = 100;
>     OnTime = 5000;
>     Kartenwahl++;
>   }
>
>   if (OnTime){
>     switch (Kartenwahl%2){
>     case 0: PORTB |= (1<<KARTE1); break;
>     case 1: PORTB |= (1<<KARTE2); break;
>     default: break;
>   }else{
>     PORTB &= ~( (1<<KARTE2) | (1<<KARTE1) );
>   }
> }

Vielen dank! Könntest du eventuell die einzelnen Programmzeilen mal ein 
wenig erklären, was mit welchen Befehlen genau gemacht wird und wie nun 
mein gewünschter Ablauf entsteht ? Ich kann aus dem Programm nämlich 
nicht genau die Zusammenhänge untereinander deuten. Ich würde das 
Programm gerne verstehen wollen.

MFG
#4152981
Lesenswert?

Karl Heinz schrieb:
> Wenn während der 5 Sekunden der Taster erneut betätigt wird, kann es
> sein, dass beide Karten angesteuert werden.
>
> Obwohl: der TO hat ja nicht verraten, was in diesem Fall die korrekte
> Reaktion wäre.
> Genauso wie er nicht verraten hat, ab wann die Zeit laufen soll. Ab
> niederdrücken oder ab loslassen. Kann man durch gedrückt halten des
> Tasters die 5 Sekunden verlängern oder nicht?

Das Ansteuern beider Karten gleichzeitig, würde in meinem fall keinen 
Fehler und Fehlfunktion in meiner Schaltung hervorrufen.

Beim Auslösen des Schalters wäre eine steigende Flanke besser.


MFG
Gast #4153129
Lesenswert?

Hi
Steffen E. schrieb:
> Beim Auslösen des Schalters wäre eine steigende Flanke besser.

In der Regel ist ein Eingang mit einem internen Pullup Widerstand 
verschaltet. Das bedeutet für deine Schaltung, wenn du keinen externen 
PullDown verwenden willst, das dein Schalter/ Taster genau anders herum 
schaltet. Also, eine steigende Flanke bekommst du dann beim Loslassen.
 Gruß oldmax
#4153195
Lesenswert?

Steffen E. schrieb:

> Vielen dank! Könntest du eventuell die einzelnen Programmzeilen mal ein
> wenig erklären,

Das würde bedeuten, das Tutorial hier genau noch einmal hinzuschreiben.

> mein gewünschter Ablauf entsteht ? Ich kann aus dem Programm nämlich
> nicht genau die Zusammenhänge untereinander deuten. Ich würde das
> Programm gerne verstehen wollen.

Dann bleibt dir nichts anderes übrig als die Dinge zu lernen. Hier wird 
dir keiner eine 12 Seiten Abhandlung schreiben, die alles im Detail 
erläutert.
Arbeite das Tutorial durch, mach Übungen zu den einzelnen Themenkreisen. 
Das ist der Weg, wie man Dinge lernt.
Schriftsteller zu werden lernt man auch nicht dadurch, dass einem ein 
anderer Schriftsteller seinen Roman Wort für Wort auseinanderklaubt.

Ganz wichtig ist: Das Tutorial nur zu lesen ist zu wenig. Das ist wie 
beim Radfahren. Du kannst hunderte Bücher über radfahren lesen. Solange 
du dich nicht selbst in den Sattel setzt, wirst du dich nicht auf dem 
Rad halten können.

Soviel kann man aber sagen:
zentrales Element ist ein Timer, der durch seine Einstellung einen 
regelmässigen Basistakt (und damit eine definierte Zeitreferenz) 
erzeugt. In genau diesem Takt wird die ISR aufgerufen. Der Rest ist dann 
nur noch: Wenn ich 5 Sekunden benötige, und eine 'Uhr' zur Verfügung 
habe, die mir jede zb Zehntelsekunde einen Beep gibt, dann muss ich 50 
Beeps abzählen, bis 5 Sekunden beisammen sind. Die ISR ist so 
eingestellt, dass sie jede 1 Millisekunde feuert, also muss ich 5000 
derartige 'Feuerungen' abzählen (entweder von 0 bis 5000, oder von 5000 
runter bis 0) um eine Zeit von 5 Sekunden abzumessen.

zusätzlich zum Tutorial:
FAQ: Timer
Aber Timer ist schon etwas für fortgeschrittene Anfänger, auch wenn kaum 
ein Programm ohne sie auskommt. Mit einem Timer umgehen muss man können, 
weil sie praktisch überall vorkommen. Nur ist das (noch) kein Thema, 
wenn man bei 0 einsteigt. Da müssen zuerst andere Dinge verstanden 
worden sein.
#4153201
Lesenswert?

Karl Heinz schrieb:
> Wenn während der 5 Sekunden der Taster erneut betätigt wird, kann es
> sein, dass beide Karten angesteuert werden.
Ja das stimmt, das kann man ja aber abfangen wenn man will indem man 
einfach die Tasterabfrage blockiert so lange noch eine Karte aktiv is.
1
 if (!(PINB & (1<<TASTER)) && !debounce && !OnTime){
2
 ...
3
 }
Gast #4153231
Lesenswert?

Hi
Karl Heinz schrieb:
> Dann bleibt dir nichts anderes übrig als die Dinge zu lernen. Hier wird
> dir keiner eine 12 Seiten Abhandlung schreiben, die alles im Detail
> erläutert.

Doch Karl Heinz. Im von mir angesprochenem Beitrag der AVR-Praxis 
Gemeinde hab ich das mal gemacht. Nur lesen muss das jeder, der sich 
dafür interessiert, schon selber. Und jetzt noch mal einzelne Auszüge 
davon mundgerecht zu präsentieren, dazu hab ich natürlich keine Lust.
Gruß oldmax
#4153233
Lesenswert?

oldmax schrieb:
>> Dann bleibt dir nichts anderes übrig als die Dinge zu lernen. Hier wird
>> dir keiner eine 12 Seiten Abhandlung schreiben, die alles im Detail
>> erläutert.

oldmax schrieb:
> Doch Karl Heinz. Im von mir angesprochenem Beitrag der AVR-Praxis
> Gemeinde hab ich das mal gemacht.

Ich glaube Karl-Heinz meint, dass sich jetzt niemand hinsetzt und mein 
kleines Programm beschreibt!

Ich hätte natürlich jede Zeile kommentieren können, aber da war ich zu 
faul zu...
#4153241
Lesenswert?

Ingo Less schrieb:

> Ich hätte natürlich jede Zeile kommentieren können, aber da war ich zu
> faul zu...

Das ist auch nicht sinnvoll.
Denn Dinge wie
* Wie wird ein Bit gesetzt
* Wie wird es gelöscht"
* Wie fragt man einen Eingang ab
die müssen einfach im Schlaf sitzen, ehe man überhaupt daran denken 
kann, ein Real-World Programm zu schreiben.

Damit ist aber noch lange nicht die Logik, die Idee die im Programm 
steckt, beschrieben. Die Idee hab ich versucht kurz zu skizzieren. Damit 
und mit ein wenig spielen mit Papier und Bleistift und verfolgen wie 
sich die einzelnen Werte ändern, sollte es eigentlich möglich sein, zu 
verfolgen wie sich daraus die gewünschte Funktionalität ergibt. Rein 
durch hinsehen wird ein Anfänger die einzelnen Bestandteile und welche 
Idee sie verkörpern nicht identifizieren, das ist mir schon klar. Aber 
der beste Weg ist immer noch, sich da durchzu'quälen', auch wenn das 
jetzt hart klingt. Hilft aber nichts, da musste jeder mal durch. Und mit 
der Zeit wird man ja auch besser, weil man Dinge, bestimmte Konstrukte, 
wiedererkennt.
Ist wie beim Schachspielen. Die Regeln sind schnell erklärt, aber in 
einem realen Schachspiel steckt mehr als nur die Anwendung der Regeln. 
Als Anfänger kannst du einem Hr. Pfleger stundenlang zu hören, du wirst 
trotzdem nicht verstehen wovon er da redet, bzw. wie er darauf kommt. 
Erst nach einiger Spielpraxis erschliesst sich vieles davon.
#4153246
Lesenswert?

Karl Heinz schrieb:
> Das ist auch nicht sinnvoll.
Macht meiner Meinung hier auch keinen Sinn, da das Programm genau das 
verkörpert, was er wollte. Somit hat er seine Programmbeschreibung 
selber geschrieben. Nur das "Wo passiert was" muss er sich halt selber 
raus suchen. Ich denke aber, dass ist bei den paar Zeilen kein Ding der 
Unmöglichkeit.
Gast #4153275
Lesenswert?

Ich hab da grad mal Bock drauf: // Ich auch, Dank an Ingo Less
1
// Aus der C Bibliothek Funktionsdateien laden
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4

5
// Definition welcher Portpin zu welchen Anschluss gehören soll.
6
#define KARTE1    PB0
7
#define KARTE2    PB1
8
#define TASTER    PB2
9

10

11
// C Programm Hauptschleife
12
int main(void)
13
{
14
  // Timer Inbetriebsetzen hier auf 1khz stellen Wenn abgelaufen löst der Timer einen Interrupt aus.
15
  TCCR0A |= (1<<WGM00) | (1<<WGM01);    // CTC
16
  OCR0A = 149;              // 9,6MHz / ((149+1) * 64) = 1KHz //Vergleichsregister
17
  TIMSK0 |= (1<<OCIE0A);          // Capture Interrupt Vergleichsinterrupt einschalten
18
  TCCR0B |= (1<<CS00) | (1<<CS01);    // Prescaler 64 Vorteiler des Timers siehe Datenblatt vom Tiny
19
  
20
  // IOs  Ein und Ausgänge vorbereiten
21
  PORTB = 0; //Portausgänge alle auf 0 setzen
22
  DDRB |= (1<<KARTE1) | (1<<KARTE2); // 2 Portpinne als Ausgänge machen 
23
  PORTB |= (1<<TASTER);          // Pull-up enable Der Eingangspin mit einem Pullup Widerstand beschalten.
24
  
25
  // global Interrupt enable Freigabe der Interrupt Funktion allgemein
26
  sei();
27
  
28
  
29
    while(1){;  // Hauptschleife ist fertig Mach nichts mehr. Das Programm lebt jetzt nur noch vom Interrupt
30
        //Nothing to Do 
31
    }
32
}
33

34
/* 1kHz */
35
// Programmteil das bei einer Interrupt Auslösung abarbeitet wird.
36
ISR (TIM0_COMPA_vect)
37
{
38
  static uint16_t debounce = 0; // Variable debounce deklarieren 16bit ohne Vorzeichen und wird auf 0 gesetzt
39
  static uint16_t OnTime = 5000;// Variable OnTime 16bit ohne Vorzeichen wird auf 5000 gesetzt.
40
  static uint8_t Kartenwahl = 0;// Variable Kartenwahl 8bit ohne Vorzeichen wird auf 0 gesetzt.
41
  
42
  if (debounce) debounce--;
43
  
44
  if (!(PINB & (1<<TASTER)) && !debounce){ // Tasterabfrage wenn Eingangspin auf 1 ist dann
45
    debounce = 100;// Variable debounce auf 100 stellen
46
    OnTime = 5000;// OnTime auf 5000 stellen
47
    Kartenwahl++;// Zähler Kartenwahl um 1 addieren (Increment)
48
  }
49
  
50
  if (OnTime){// Wenn ONTime abgelaufen? (Bin selber Anfänger)
51
    switch (Kartenwahl%2){// switchanweisung  siehe Grundlagen
52
    case 0: PORTB |= (1<<KARTE1); break;// Wenn Kartenwahl 0 ist dann Portausgang für Karte1 setzen
53
    case 1: PORTB |= (1<<KARTE2); break;// Wenn Kartenwahl 1 ist dann Portausgang für Karte2 setzen
54
    default: break;// Breakanweiseung auch hier bitte die switch Grundlagen lesen
55
  }else{ // Falls weder 0 noch 1 ist dann Portausgänge der beiden Karten auf 0 setzen
56
    PORTB &= ~( (1<<KARTE2) | (1<<KARTE1) );
57
  }
58
}
Viel Spass damit // auch von mir
Ich schliesse mich meinen Vorschreibern an, bitte die Grundlagen 
durchackern. Hier gab es ja schon viele Links

Gruß Greg
#4160198
Lesenswert?

Steffen E. schrieb:
> Moin Leute,
> das Programm läuft wie es oben geschrieben wurde nicht wirklich.

Welche Version?
Hast du auch die nachträglichen Änderungen noch eingepflegt?

Zum Rest:
Eigentlich ist das Programm so einfach, dass man auch einem Anfänger 
zumuten kann zu analysieren, wie das ganze arbeitet.

Dreh und Angelpunkt ist die Erkentnis, dass die ISR-Funktion jede 1 
Millisekunde aufgerufen wird. Das funktioniert also wie ein Wecker, der 
alle x Zeiteinheiten läutet. Der Benutzer wacht auf, sieht sich um, 
entscheidet was er zu tun hat (anhand seiner Umgebung) und macht die 
entsprechenden Aktionen.

Mit dieser Vorgabe, einem Blatt Papier und Bleistift sollte es 
eigentlich nicht mehr schwer sein, die Funktionalität nachvollziehen zu 
können, bzw. zu ergründen, warum etwas nicht funktioniert.
#4160205
Lesenswert?

Ingo Less schrieb:
> Greg schrieb:
>> debounce = 100;// Variable debounce auf 100 stellen
> Ganau diese Art von Kommentar hilft garnicht.
> Hier hätte es heißen müssen "Entprellzeit 100ms".

Und um das klar zu stellen: Das ist nur ein willkürlich 
herausgegriffenes Beispiel für sinnlose Kommentierung.
Der Rest der Kommentierung (die nicht von Ingo stammen) ist vom genau 
gleichen Kaliber: sinnlos
Sorry Greg. Aber du hast dir eine Menge Arbeit für nichts gemacht.
#4160216
Lesenswert?

Steffen E. schrieb:
> das Programm läuft wie es oben geschrieben wurde nicht wirklich.
> Ausgangskarte 1 läuft immer dauerhaft und Ausgangskarte 2 geht an wenn
> man den Taster drückt und wenn man Ihn 5 Sekunden hält und wieder los
> lässt, geht Ausgangskarte 2 wieder aus aber auch nur dann.
Wie hast du deinen Taster angebunden? Wenn du alle Nachträge ins 
Programm eingepflegt hast, dann sollte es funktionieren. Sofern der 
Taster richtig angeschlossen ist.

Aber wie K.-H. schon schrieb. Das Programm ist überschaubar einfach. Es 
soll dich ja auch dazu ermuntern es zu verstehen. Copy&Paste 
funktioniert meist eh nicht auf Anhieb.
#4160265
Lesenswert?

Da ich hier einen Internen Pull-up Widerstand benutze, ist von PB2 auf 
den Taster und von dort auf 0V angeschlossen.

ich habe das Decrement noch eingefügt, bin mir aber auch nicht sicher ob 
das an der richtigen Stelle war. Sonst habe ich nichts mehr eingepflegt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
#define KARTE1    PB0
5
#define KARTE2    PB1
6
#define TASTER    PB2
7

8

9

10
int main(void)
11
{
12
// Timer
13
TCCR0A |= (1<<WGM00) | (1<<WGM01);    // CTC
14
OCR0A = 149;              // 9,6MHz / ((149+1) * 64) = 1KHz
15
TIMSK0 |= (1<<OCIE0A);          // Capture Interrupt
16
TCCR0B |= (1<<CS00) | (1<<CS01);    // Prescaler 64
17

18
// IOs
19
PORTB = 0;
20
DDRB |= (1<<KARTE1) | (1<<KARTE2);
21
PORTB |= (1<<TASTER);          // Pull-up enable
22

23
// global Interrupt enable
24
sei();
25

26

27
while(1){
28
//Nothing to Do
29
}
30
}
31

32
/* 1kHz */
33
ISR (TIM0_COMPA_vect)
34
{
35
static uint16_t debounce = 0;
36
static uint16_t OnTime = 5000;
37
static uint8_t Kartenwahl = 0;
38

39
if (debounce) debounce--;
40

41

42
if (!(PINB & (1<<TASTER)) && !debounce){
43
debounce = 100;
44
OnTime = 5000;
45
Kartenwahl++;
46
}
47
if (OnTime) OnTime--;
48

49
if (OnTime){
50
switch (Kartenwahl%2){
51
case 0: PORTB |= (1<<KARTE1); break;
52
case 1: PORTB |= (1<<KARTE2); break;
53
default: break;
54
}}else{
55
PORTB &= ~( (1<<KARTE2) | (1<<KARTE1) );
56
}
57
}
#4160291
Lesenswert?

Hast du eigentlich an den Fuses des AtTiny rumgemacht?

Denn wenn du da nichts getan hast, dann stimmt die Zeitberechnung im 
Programm nicht. Der Timer ist so eingerichtet, dass die Zeiten bei 
9.6Mhz Taktfrequenz stimmen. Hast du an den Fuses nichts gemacht, dann 
läuft der Tiny aber nicht mit 9.6Mhz sondern mit 1.2Mhz.

Also Folge davon sind alle Zeiten real dann 8 mal so lang. Aus deinen 5 
Sekunden werden ca. 40 Sekunden. Und die können laaaang sein, wenn man 
vor einem Gerät sitzt und darauf wartet, dass etwas passiert.

Ich hätte hier
1
    switch (Kartenwahl%2) {
2
      case 0: PORTB |= (1<<KARTE1);
3
              PORTB &= ~(1<<KARTE2);
4
              break;
5

6
      case 1: PORTB |= (1<<KARTE2);
7
              PORTB &= ~(1<<KARTE1);
8
              break;
9

10
      default: break;
11
    }
ja dafür gesorgt, dass die Ausgänge mit Sicherheit immer wechselseitig 
geschaltet sind.
#4160562
Lesenswert?

F. Fo schrieb:
> Ich habe das noch nie verwendet. Wie genau ist das?

100%.

Damit stellt man den Clock Prescaler ein. Mit dieser Funktion lässt sich 
der Takt auf 1, 1/2, 1/4 und 1/8 einstellen. Unabhängig von der 
Fuse-Voreinstellung.

Das ist alles auch nichts Neues und setzt lediglich ein paar Bits im 
CLKPR. Dieses Register muss aber in einer Timed Sequence beschrieben 
werden, ähnlich dem Watchdog. Das Timing nimmt einem die Funktion ab.

Die berühmt-berüchtigte Fuse macht lediglich die Startvorgabe auf 1/8 
oder 1. Also nicht "festverdrahtet" wie die Einstellung der Taktquelle.

mfg.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren