Forum: Mikrocontroller und Digitale Elektronik Telefon-Wählscheibe mit Attiny13 Ausgang auf low setzen


von Jörg S. (joschi1711)


Lesenswert?

Hallo Leute,
Ich habe folgenden Code von einem Bekannten bekommen und habe nun das 
Problem, das der Ausgang an Pin3 ein High-Signal liefert und bei 
richtiger Zahlenfolge auf low schaltet, ich das aber genau umgedreht 
brauche, sprich Pin3 auf low bei richtiger Zahlenfolge kurz auf High 
schaltet.
Ich hoffe, hier kann mir einer helfen, da ich nicht der 
Programmierfreund bin und ich das ganze auch nur sehr selten benötige.
1
//----------------------------------------------------------------------
2
// Titel       : Auswertung Waehlscheibe
3
//----------------------------------------------------------------------
4
// Funktion    : Erfassung wenn Wahlvorgang beendet mit Interrupt an PORTD2 (INT0)
5
//----------------------------------------------------------------------
6
7
//----------------------------------------------------------------------
8
#define   F_CPU 1000000  
9
#include <inttypes.h>
10
#include <avr/io.h>
11
#include <avr/interrupt.h>
12
#include <avr/wdt.h>
13
#include <avr/sleep.h>
14
15
//------------------------------------------------------------------------------------------------------
16
//--------------------globale Variablen-----------------------------------------------------------------
17
volatile int Timerzaehler_neu = 0;
18
volatile int Timerzaehler_alt = 0;
19
volatile int Timerzaehler_neu_2 = 0;
20
volatile int Timerzaehler_alt_2 = 0;
21
volatile int Sleepzaehler = 0;
22
volatile char Scheibe_in_Bewegung = 0;
23
volatile char Drehung_beendet = 0;
24
volatile char Ziffer;                  // im aktuellen Wahlvorgang gewählte Ziffer
25
char aktuelle_Stelle;                  // Stelle der Ziffer, die gerade gewählt wird
26
char richtige_Nummer[6]={2, 5, 3, 6, 9, 7 };      // vorgegebene Nummer
27
char Stellen = 6;                    // Stellen der vorgegebenen Nummer
28
char richtig_gewaehlt;                  // richtig gewaehlt ?
29
30
//----------------------------------------------------------------------
31
void initialisieren(void)        
32
{
33
  DDRB = 0b00011000;                      // PORTB.3 und 4 = Ausgang
34
  PORTB = 0b11100111;                     // PULL-UP  für Eingänge
35
36
  MCUCR = 0b00000000;
37
  ACSR = 0b10000000;            // Comperator deaktivieren  
38
39
  TCCR0B = 0b00000011;          // Timer mit Teiler 64 aktivieren  
40
  TIMSK0 |= (1<<TOIE0);          // Overflowinterrupt erlauben
41
  sei();                  // globale Interrupts aktivieren  
42
43
  PORTB = PORTB | 0b00011000;
44
45
  Scheibe_in_Bewegung = 0;  
46
  Drehung_beendet = 0;  
47
  Ziffer = 0;
48
  aktuelle_Stelle = 0;
49
  richtig_gewaehlt = 0;
50
  Sleepzaehler = 0;   
51
52
}
53
54
//-----------------------------------------------------------------------------------------------------
55
//---------------------------Interruptroutine für Int0 zum Aufwecken-----------------------------------
56
ISR (INT0_vect)                
57
{
58
59
}
60
61
//--------------------------------------------------------------------------------------------------------
62
//-----------------Interruptroutine für Timer0------------------------------------------------------------
63
ISR (TIM0_OVF_vect)            
64
{
65
66
  ++Sleepzaehler;    
67
  //----------------Taster für Ziffern entprellen und gewählte Ziffer erfassen--------------------------
68
  ++Timerzaehler_neu;
69
  if (PINB&0b00000010)            
70
  {
71
    if (Timerzaehler_neu - Timerzaehler_alt > 2) 
72
      ++Ziffer;
73
    Timerzaehler_neu = 0;
74
    Timerzaehler_alt = 0;
75
  }
76
77
  //-----Taster für Betätigung der Wählscheibe entprellen, und Rücklauf in Ausgangsstellung erfassen----
78
  ++Timerzaehler_neu_2;
79
  if (!(PINB&0b000000001))            
80
  {
81
    if (Timerzaehler_neu_2 - Timerzaehler_alt_2 > 2) 
82
      if (Scheibe_in_Bewegung == 0)
83
      {
84
        Scheibe_in_Bewegung = 1;
85
      }
86
    Timerzaehler_neu_2 = 0;
87
    Timerzaehler_alt_2 = 0;
88
  }
89
  else
90
  {
91
    if (Scheibe_in_Bewegung == 1)
92
    {
93
      Scheibe_in_Bewegung = 0;
94
      Drehung_beendet = 1;  
95
    }
96
  }
97
98
}
99
100
//------------------------------------------------------------------------------------------------------
101
//-----------------Hauptprogramm------------------------------------------------------------------------
102
main()
103
{
104
  waitMs(500);  
105
  initialisieren();   
106
  do
107
  {
108
109
    if (Sleepzaehler == 10000)//-----------------------------------------nach ca. 3 Minuten abschalten
110
    {
111
112
      //PORTB = 0b11110111;  
113
      Sleepzaehler = 0;    
114
      GIMSK |= (1 << INT0);
115
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
116
      sleep_enable();
117
      sei(); 
118
      sleep_cpu();
119
      sleep_disable();
120
      GIMSK &= ~(1 << INT0);  
121
    }
122
123
    if (Drehung_beendet == 1)//-----------------------------------wenn Drehung der Wählscheibe beendet
124
    {
125
      ++aktuelle_Stelle;//-----------------------------------zählen zum wie vielten mal das passiert  
126
      if (Ziffer == richtige_Nummer[aktuelle_Stelle - 1])//--gewählte Ziffer mit Vorgabe vergleichen
127
      {
128
        ++richtig_gewaehlt;//----------------------------------wenn richtige Ziffer gewählt zählen
129
      }
130
131
      if (aktuelle_Stelle == Stellen)//--------------------wenn vorgegebene Stellenzahl erreicht ist
132
      {
133
134
        if (richtig_gewaehlt == Stellen)//-------------------prüfen, ob alle Ziffern richtig waren
135
        {
136
137
          PORTB = 0b11101111;//------------------------------------wenn ja, Sprachmodul auslösen
138
        }
139
140
      else
141
        {
142
          //PORTB = 0b11110111;//-------------------------------------wenn nein, andere Reaktion   
143
        }
144
145
        waitMs(1000);//----------------------------------kurz warten und Ausgangszustand herstellen  
146
        initialisieren();   
147
      }
148
149
      Drehung_beendet = 0;
150
      Ziffer = 0;      
151
    }
152
153
  }
154
  while (true);                    // Mainloop
155
}
156
//------------------------------------------------------------------------

von olaf (Gast)


Lesenswert?

...ein anruf bei dem bekannten wäre warscheinlich schneller gewesen, 
aber naja....wenn du es negiert haben möchtest,so brauchst du nur alle 
werte von dem entsprechenden pin negieren.....dazu braucht man weder 
programmiererfahrung noch besonders viel mathematische kenntnis,eben nur 
etwas lust zum probieren...
wenn es dir deine schaltung wert ist, so schau mal die werte des pins 
an...
dein stichwort lautet:  PORTB = PORTB | 0b00011000;

von Jörg S. (joschi1711)


Lesenswert?

Danke für den Denkanstoß ^^
hilft mir aber nicht wirklich, und den Verfasser des Codes ereiche ich 
nicht.
Also weiter suchen.
Mit Bascom hätte ich da wohl eine Chance aber hierbei eher nicht.

von Albrecht H. (alieninside)


Lesenswert?

Du hast drei Zeilen in deinem Programm an denen was mit PORTB gemacht 
wird.


Die erste Zeile dient nur der Initialisierung und kann so bleiben:
PORTB = 0b11100111;                     // PULL-UP  für Eingänge


Die zweite Zeile setzt Bit3 und Bit4 auf high, die musst du ändern:
PORTB = PORTB | 0b00011000;

wird zu->
PORTB &= ~( (1<<PB3) | (1<<PB4) ); //Bit3 und Bit4 auf low setzen


Die dritte Zeile setzt Bit4 auf low,die musst du ebenfalls ändern:
PORTB = 0b11101111;//------------------------------------wenn ja, 
Sprachmodul auslösen

wird zu->
PORTB |= (1<<PB3) | (1<<PB4);

Das würde dann Bit3 und Bit4 auf high setzen und falls es wirklich nur 
Bit3 sein soll, dann eben nur:

PORTB |= (1<<PB3); //setzt Bit3 auf high


Informationen dazu:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ausg.C3.A4nge

von Werner (Gast)


Lesenswert?

Jörg Schumann schrieb:
> ... da ich nicht der Programmierfreund bin und ich das ganze auch
> nur sehr selten benötige.

Du brauchst auch kein Programmierfreund zu sein, um die Polarität der 
Ausgabe zu ändern. Was versteht du denn an dem Programm nicht, zumal 
Olaf dir schon den entscheidenden Hinweis gegeben hat.

Wenn du Autofahren willst, brauchst du auch ein paar elementare 
Grundkenntnisse und einen Führerschein, egal ob du das selten oder oft 
tust.

von Jörg S. (joschi1711)


Lesenswert?

Danke für die ausführliche Erklährung, werde es gleich probieren.
Da hab ich schon wieder nen kleinen Schritt dazugelernt...
hab halt immer bissel Angst, einfach alles durch Probieren zu erlernen 
und irgendwas zu zerschießen...

von Karl H. (kbuchegg)


Lesenswert?

Jörg Schumann schrieb:
> Danke für die ausführliche Erklährung, werde es gleich probieren.
> Da hab ich schon wieder nen kleinen Schritt dazugelernt...
> hab halt immer bissel Angst, einfach alles durch Probieren zu erlernen
> und irgendwas zu zerschießen...

Drum hebt man sich auch das Original auf und wenn man mit seinen 
Änderungen das Programm unbrauchbar gemacht hat, hat man dann eine 
Version auf die man wieder zurück kann.

von olaf (Gast)


Lesenswert?

....es ist bestimmt nicht so das dir keiner helfen will, vielmehr haben 
wir alle familie und möchten nicht für andere die arbeit machen,auf 
welche sie selber keine lust haben.
wenn du an der materie echtes interesse hast und du hilfe beim erlernen 
brauchst,so werden dir bestimmt viele zu seite stehen, aber dein beitrag 
kommt eben anders rüber!?
probier ruhig mal etwas rum,der lerneffekt ist manchmal 
verblüffend,kaputt machst du schon nichts ;-)
wenn es noch irgendwo hapert,oder du erfolg hast,dann melde dich 
nochmal...

von Jörg S. (joschi1711)


Lesenswert?

Danke nochmals @ alieninside für die Erklährung und den Link, den ich 
mir mal genauer ansehen werde, falls ich mir weiter zutrauhe mich weiter 
damit zu beschäftigen.
Man bekommt halt immer gleich von einigen Leuten nen Dämpfer als 
blutiger Anfänger ^^.

von olaf (Gast)


Lesenswert?

ich dachte du wolltest etwas lernen und nicht rumheulen....es sieht aber 
immer noch nicht danach aus, deswegen ist mir meine zeit zu schade...

der böse olaf hält sich jetzt raus, es findet sich bestimmt noch 
jemand,der dir das denken abnimmt ;-)

von Herr M. (herrmueller)


Lesenswert?

Ein Transistor am Ausgang könnte auch negieren, ganz ohne 
Programmierkenntnisse.

von Jörg S. (joschi1711)


Lesenswert?

@Olaf
Danke für die Komplimente...
auf das Niveau lasse ich mich aber nicht herab hier solche Sprüche zu 
komentieren, aus dem Alter bin ich raus.

von Jörg S. (joschi1711)


Lesenswert?

So liebe Leute, muss hier nochmal ne Frage stellen.
aus mir unerklährlichen Gründen mag der Attiny nach den 3 Minuten aus 
dem Schlaf nicht mehr erwachen...
woran kann das liegen?
Hier nochmal der Code.
Pin 5 schaltet bei Betätigung auf Masse Pin 6 liegt auf Masse und wird 
unterbrochen beim Zählen.
Ich hoffe da kann mir nochmal einer helfen.

1
//----------------------------------------------------------------------
2
// Titel       : Auswertung Waehlscheibe
3
//----------------------------------------------------------------------
4
// Funktion    : Erfassung wenn Wahlvorgang beendet mit Interrupt an PORTD2 (INT0)
5
//----------------------------------------------------------------------
6
7
//----------------------------------------------------------------------
8
#define   F_CPU 1000000  
9
#include <inttypes.h>
10
#include <avr/io.h>
11
#include <avr/interrupt.h>
12
#include <avr/wdt.h>
13
#include <avr/sleep.h>
14
15
//------------------------------------------------------------------------------------------------------
16
//--------------------globale Variablen-----------------------------------------------------------------
17
volatile int Timerzaehler_neu = 0;
18
volatile int Timerzaehler_alt = 0;
19
volatile int Timerzaehler_neu_2 = 0;
20
volatile int Timerzaehler_alt_2 = 0;
21
volatile int Sleepzaehler = 0;
22
volatile char Scheibe_in_Bewegung = 0;
23
volatile char Drehung_beendet = 0;
24
volatile char Ziffer;                  // im aktuellen Wahlvorgang gewählte Ziffer
25
char aktuelle_Stelle;                  // Stelle der Ziffer, die gerade gewählt wird
26
char richtige_Nummer[6]={2, 5, 3, 6, 9, 7 };      // vorgegebene Nummer
27
char Stellen = 6;                    // Stellen der vorgegebenen Nummer
28
char richtig_gewaehlt;                  // richtig gewaehlt ?
29
30
//----------------------------------------------------------------------
31
void initialisieren(void)        
32
{
33
  DDRB = 0b00011000;                      // PORTB.3 und 4 = Ausgang
34
  PORTB = 0b11100111;                     // PULL-UP  für Eingänge
35
36
  MCUCR = 0b00000000;
37
  ACSR = 0b10000000;            // Comperator deaktivieren  
38
39
  TCCR0B = 0b00000011;          // Timer mit Teiler 64 aktivieren  
40
  TIMSK0 |= (1<<TOIE0);          // Overflowinterrupt erlauben
41
  sei();                  // globale Interrupts aktivieren  
42
43
  PORTB &= ~( (1<<PB3) | (1<<PB4) ); //PIN3 und PIN4 auf low setzen
44
45
  Scheibe_in_Bewegung = 0;  
46
  Drehung_beendet = 0;  
47
  Ziffer = 0;
48
  aktuelle_Stelle = 0;
49
  richtig_gewaehlt = 0;
50
  Sleepzaehler = 0;   
51
52
}
53
54
//-----------------------------------------------------------------------------------------------------
55
//---------------------------Interruptroutine für Int0 zum Aufwecken-----------------------------------
56
ISR (INT0_vect)                
57
{
58
59
}
60
61
//--------------------------------------------------------------------------------------------------------
62
//-----------------Interruptroutine für Timer0------------------------------------------------------------
63
ISR (TIM0_OVF_vect)            
64
{
65
66
  ++Sleepzaehler;    
67
  //----------------Taster für Ziffern entprellen und gewählte Ziffer erfassen--------------------------
68
  ++Timerzaehler_neu;
69
  if (PINB&0b00000010)            
70
  {
71
    if (Timerzaehler_neu - Timerzaehler_alt > 2) 
72
      ++Ziffer;
73
    Timerzaehler_neu = 0;
74
    Timerzaehler_alt = 0;
75
  }
76
77
  //-----Taster für Betätigung der Wählscheibe entprellen, und Rücklauf in Ausgangsstellung erfassen----
78
  ++Timerzaehler_neu_2;
79
  if (!(PINB&0b000000001))            
80
  {
81
    if (Timerzaehler_neu_2 - Timerzaehler_alt_2 > 2) 
82
      if (Scheibe_in_Bewegung == 0)
83
      {
84
        Scheibe_in_Bewegung = 1;
85
      }
86
    Timerzaehler_neu_2 = 0;
87
    Timerzaehler_alt_2 = 0;
88
  }
89
  else
90
  {
91
    if (Scheibe_in_Bewegung == 1)
92
    {
93
      Scheibe_in_Bewegung = 0;
94
      Drehung_beendet = 1;  
95
    }
96
  }
97
98
}
99
100
//------------------------------------------------------------------------------------------------------
101
//-----------------Hauptprogramm------------------------------------------------------------------------
102
main()
103
{
104
  waitMs(500);  
105
  initialisieren();   
106
  do
107
  {
108
109
    if (Sleepzaehler == 10000)//-----------------------------------------nach ca. 3 Minuten abschalten
110
    {
111
112
      //PORTB = 0b11110111;  
113
      Sleepzaehler = 0;    
114
      GIMSK |= (1 << INT0);
115
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
116
      sleep_enable();
117
      sei(); 
118
      sleep_cpu();
119
      sleep_disable();
120
      GIMSK &= ~(1 << INT0);  
121
    }
122
123
    if (Drehung_beendet == 1)//-----------------------------------wenn Drehung der Wählscheibe beendet
124
    {
125
      ++aktuelle_Stelle;//-----------------------------------zählen zum wie vielten mal das passiert  
126
      if (Ziffer == richtige_Nummer[aktuelle_Stelle - 1])//--gewählte Ziffer mit Vorgabe vergleichen
127
      {
128
        ++richtig_gewaehlt;//----------------------------------wenn richtige Ziffer gewählt zählen
129
      }
130
131
      if (aktuelle_Stelle == Stellen)//--------------------wenn vorgegebene Stellenzahl erreicht ist
132
      {
133
134
        if (richtig_gewaehlt == Stellen)//-------------------prüfen, ob alle Ziffern richtig waren
135
        {
136
137
          PORTB |= (1<<PB3) | (1<<PB4);//------------------------------------wenn ja, PIN3 und PIN4 auf HIGH
138
        }
139
140
      else
141
        {
142
          //PORTB = 0b11110111;//-------------------------------------wenn nein, andere Reaktion   
143
        }
144
145
        waitMs(1000);//----------------------------------kurz warten und Ausgangszustand herstellen  
146
        initialisieren();   
147
      }
148
149
      Drehung_beendet = 0;
150
      Ziffer = 0;      
151
    }
152
153
  }
154
  while (true);                    // Mainloop
155
}
156
//------------------------------------------------------------------------

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.