Forum: Mikrocontroller und Digitale Elektronik ATMega328p und Multiplexer


von Thomas (Gast)


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?

: Bearbeitet durch User
von public (Gast)


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

von public (Gast)


Lesenswert?

Hallo nochmal,

ich meinte das AVR-GCC-Tutorial.

Beste Grüße
public

von Thomas (Gast)


Lesenswert?

Ah Verzeihung. Das war mein Fehler. Die Steuerpins hängen natürlich an 
Port B. Das passt schon soweit.

von Wolfgang (Gast)


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.

von Hubert G. (hubertg)


Lesenswert?

Werden bei "digitalRead" automatisch die PullUp aktiviert?
Oder hast du diese hardwaremäßig vorgesehen?

von Wolfgang (Gast)


Lesenswert?

Hubert G. schrieb:
> Werden bei "digitalRead" automatisch die PullUp aktiviert?

Die werden vom Arduino-Code bei der Initialisierung der Pins als 
digitalen Eingänge wahlweise aktiviert.

von Hubert G. (hubertg)


Lesenswert?

Wolfgang schrieb:
> Die werden vom Arduino-Code bei der Initialisierung der Pins als
> digitalen Eingänge wahlweise aktiviert.

Wie sieht dieses Wahlweise aus?
Im Code vom ersten Beitrag kann ich nichts erkennen.

von Thomas (Gast)


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.

von Jobst M. (jobstens-de)


Lesenswert?

Thomas schrieb:
> Die internen PullUp Widerstände sind gesetzt. Dadurch funktioniert das
> ganze auch mit dem anderen Code.

???
Und weil die in dem anderen Code aktiviert werden, werden die auch in 
diesem Code aktiviert?


Gruß

Jobst

von public (Gast)


Lesenswert?

Mach doch einfach mal das AVR-GCC-Tutorial, da steht alles drin... vom 
Urschleim bis zum Interrupt...

Beste Grüße
Mutti

von Hubert G. (hubertg)


Lesenswert?

Thomas schrieb:
> Die internen PullUp Widerstände sind gesetzt. Dadurch funktioniert das
> ganze auch mit dem anderen Code.

Mich würde eben interessieren wo und wie die PullUp im Arduino-Code 
gesetzt werden.

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.