Forum: Mikrocontroller und Digitale Elektronik Bitmanipulationsproblem


von TM F. (p_richner)


Lesenswert?

Hallo zusammen

Ich habe eine Soft-SPI-Datenleitung, bei der ich das Eingangssignal(8 
Bit) auslesen möchte. Das Signal wird korrekt zum uC übertragen, jedoch 
weiss ich nicht, was ich in der Auswertung falsch mache, dass ich das 
Signal nicht richtig lese.

Datenpin ist auf PC1.
Clock auf PC0(der funktioniert)

Der Code:
1
// Switch Data pin to input
2
    DDRC &= ~(1<<SPI_SOFT_DATA);
3
4
    unsigned char data_buffer;
5
    
6
    // Receive the data byte
7
    for(loop = 0, mask = 0x80, data_buffer=0;loop<8;loop++,mask = mask >> 1;)
8
    {
9
        SPI_SOFT_CLK_HIGH();
10
        // If data input is high, set bit
11
        if(PORTC & 0x02)
12
            data_buffer |=  mask;
13
14
        SPI_SOFT_CLK_LOW();    
15
    }
16
    SPI_CSX_HIGH();
17
    // Switch Data pin to output
18
    DDRC |= (1<<SPI_SOFT_DATA);
19
    return data_buffer;

Ich hoffe, ihr könnt mir helfen, den Knoten zu lösen.

MfG

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du solltest vor dem Durchlaufen Deiner Schleife sicherstellen, daß 
"data_buffer" mit 0 initialisiert ist. Da das eine automatische Variable 
zu sein scheint (d.h. sie liegt auf dem Stack), ist sie das nämlich 
nicht, und Du mischst Deine Nutzdaten mit dem "Rauschen", das da schon 
in der Variablen drinsteht.

von TM F. (p_richner)


Lesenswert?

Das habe ich gemacht, ergibt jedoch keine Änderung.

von Der Gast (Gast)


Lesenswert?

Welcher Prozessor ?
PORTC wirklich Register für Input ?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Der Gast schrieb:
> PORTC wirklich Register für Input ?
Mit hinreichender Wahrscheinlichkeit sollte es das PINC Register sein...

von KU (Gast)


Lesenswert?

TM F. schrieb:
> Ich hoffe, ihr könnt mir helfen, den Knoten zu lösen.

Vielleicht bist du zu schnell beim lesen - du sagst ja nicht welcher 
Baustein mit SPI das ist. Näheres steht im Datenblatt bzgl. des Timings.

Deine For-Schleife ist schrecklich unübersichtlich so.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

KU schrieb:
> du sagst ja nicht welcher Baustein mit SPI das ist.
Das kann jeder sein. Es ist ein Software-SPI...

> Deine For-Schleife ist schrecklich unübersichtlich so.
Und der letzte Strichpunkt ist unnötig ;-)
Ich hätte sie so geschrieben:
1
    for (loop=0, mask=0x80, data_buffer=0;   loop<8;   loop++, mask=mask>>1)

von Stefan F. (Gast)


Lesenswert?

Ja, du musst PINC lesen.
Ich finde, du solltest auch eine gewisse Zeit abwarten, zwischen dem 
Takt und dem Einlesen des Pins.

Vorschlag, um deine for-Schleife besser lesbar zu machen:
1
    uint8_t data_buffer=0;
2
    for(int i=0; i<8; i++)
3
    {
4
        SPI_SOFT_CLK_HIGH();
5
        _delay_us(1);
6
        data_buffer <<= 1;
7
        if(PINC & 0x02)
8
        {
9
            data_buffer+=1;
10
        }
11
        SPI_SOFT_CLK_LOW();    
12
    }

Aber das ist letztendlich Geschmackssache.

von TM F. (p_richner)


Lesenswert?

Lothar M. schrieb:
> Mit hinreichender Wahrscheinlichkeit sollte es das PINC Register sein...

Mit der änderung von PORTC zu PINC funktioniert es.

Habe mich mal wieder selber gelinkt.

Stefan U. schrieb:
> Ich finde, du solltest auch eine gewisse Zeit abwarten, zwischen dem
> Takt und dem Einlesen des Pins.

Das Datenbit wird schon bei der fallenden Flanke des Clocks geschrieben, 
deshalb ist es nichts zeitkritisches.

Danke für die Antworten

von Thomas E. (picalic)


Lesenswert?

Stefan U. schrieb:
> uint8_t data_buffer=0;

die Initialisierung kann man sich hier auch noch sparen, da am Schluss 
sowieso alle 8 Datenbits 'rausgeschoben worden sind.

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.