ATMega328p und Multiplexer

Gast #3498754
Lesenswert?

Hallo, ich arbeite grade mit einem Arduino auf ATMega328p Basis.
Ich will zur Zeit lernen ein wenig maschinennaher zu programmieren. In 
meinem Anwendungsfall habe ich einen 3 zu 8 Multiplexer. Daran sind 6 
Taster geklemmt.
Ich habe zunächst über die Arudino Library-Funktionen die Pins PD8, PD9 
und PC0 als Ausgänge und den Pin PC1 als Eingang deklariert.
Die drei Ausgänge steuern den Multiplexer, der PC1 soll die Info 
abgreifen.

Folgende Belegung:
s0 - PD8
s1 - PD9
s0 - PC0

Das ganze habe ich in eine Funktion gegossen. Interessant ist für meinen 
Fall nur der Case 2.
1
uint8_t readPin(uint8_t mode, uint8_t pin) {
2
  switch(mode) {
3
  case 0:
4
    return digitalRead(pin);
5
  case 1:
6
    digitalWrite(s[0], bitRead(pin, 0));
7
    digitalWrite(s[1], bitRead(pin, 1));
8
    digitalWrite(s[2], bitRead(pin, 2));
9
    return digitalRead(z1);
10
  case 2:
11
    //binary of pin
12
    uint8_t bitS2 = (1 & (pin >> 2));
13
    uint8_t bitS1 = (1 & (pin >> 1));
14
    uint8_t bitS0 = (1 & pin);    
15
    
16
    PORTB &= ~((1<<0) | (1<<1)); //reset first 2 bits
17
    PORTB |= (bitS0 | (bitS1<<1)); //set first 2 bits
18
    
19
    PORTC &= ~(1<<0); //reset bit
20
    PORTC |= bitS2; //set bit
21

22
    //return just 0 or 1
23
    return ((PINC & _BV(1)) >> 1);
24
  }
25
}
Wenn ich über die Funktion zum Testen nur einen Knopf überwache und mir 
über die serielle Schnittstelle das Ergebnis anzeigen lasse, kriege ich 
scheinbar richtige Ergebnisse. Ich kann sehen, wann ich den Knopf drücke 
und wann nicht.

Wenn ich die Funktion aber für alle sechs Knöpfe durchgehend abfrage, 
passieren komische Sachen. Wenn ich beispielsweise den Knopf an Pin 0 
des Multiplexers drücke, wird mir angezeigt, dass alle Knöpfe außer dem 
an Pin 2 betätigt wurden.
An Pin 2 und Pin 3 scheint alles ok. Pin 5 wird garnicht erkannt.

Kann mir da wer helfen? In Case 1 sieht man übrigens ein Lösung über 
Arduino Funktionen. Die läuft auch super. Das ist aber nicht mein Ziel.
Wie setze ich also für einen vorgegebenen Pin meine Registereinträge so, 
dass ich anschließend den Multiplexer richtig auslesen kann?
Gast #3498900
Lesenswert?

Servus Thomas,

Taster hängen an PORT D, deinen Zugriff machst du auf PORT B.

Lass doch die Arduinofunktionen einfach mal weg, schau dir das 
AVR-Tutorial an.

DDRx = ... setzt die Richtung deines Pins

PINx = ... liest deinen Pin

PORTx = ... setzt deinen Pin

Beste Grüße
public
Gast #3499820
Lesenswert?

Thomas schrieb:
> Kann mir da wer helfen?

Wie schnell läuft dein µC und welche Grenzfrequenz hat deine 
Signalübertragung? Häng mal ein paar NOPs dazwischen, damit die Signale 
einschwingen können.
Die Digitalread() und -write() sind schließlich wahrscheinlich einen 
Faktor 20 langsamer als der Code im Case 2.
Gast #3499953
Lesenswert?

Die internen PullUp Widerstände sind gesetzt. Dadurch funktioniert das 
ganze auch mit dem anderen Code.
Der uC läuft mit 8 Mhz. Der serielle Übertragung läuft mit 9600 Baud. 
Ich habe allerdings schon mit einigen Warteschleifen gearbeitet und da 
kam auch leider kein besseres Ergebnis bei heraus.

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