Forum: Mikrocontroller und Digitale Elektronik sbit macro & Wertzuweisung über Berechnung


von Steffen Graap (Gast)


Lesenswert?

Hallo

Ich benutze folgende macros um auf die Portpins eine ATmega2560 
zuzugreifen:

struct bits {
UINT8 b0:1;
UINT8 b1:1;
UINT8 b2:1;
UINT8 b3:1;
UINT8 b4:1;
UINT8 b5:1;
UINT8 b6:1;
UINT8 b7:1;
} __attribute__((_packed_));

#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)

#define MOSI_QT      SBIT( PORTF, 2 )

allerdings möchte ich den Wert nicht fest zuweisen (MOSI_QT = 1) sondern 
durch eine Berechnung übergeben. Das ganze sieht zur Zeit so aus:

MOSI_QT = (u32QT_Outbyte >> (u8TIM0_StepCounter >> 1)) & 0x01

dabei wird aber folgender Fehler ausgegeben:

called object 'u32QT_Outbyte >> (u8TIM0_StepCounter >> 1) & 1u' is not a 
function

Das ganze wird in einem Interrupt ausgeführt, der alle 150 
Prozessortakte ausgeführt werden soll. Für eine kurze Lösung wäre ich 
dankbar.

Gruß Steffen

von Peter D. (peda)


Lesenswert?

Steffen Graap wrote:

> MOSI_QT = (u32QT_Outbyte >> (u8TIM0_StepCounter >> 1)) & 0x01
>
> dabei wird aber folgender Fehler ausgegeben:


Du hast das ; vergessen.
1
MOSI_QT = (u32QT_Outbyte >> (u8TIM0_StepCounter >> 1)) & 0x01;
und schon wird er anstandslos übersetzt.

Variables Schieben ist natürlich kein Brüller bezüglich Laufzeit. Wenn 
da bis zu 31 mal geschoben wird, dauerts ~250 Zyklen.

Hast dann also noch -100 Zyklen für das Main. Leider gibt es keine 
Befehle mit negativer Zyklusdauer.


Peter

von Falk B. (falk)


Lesenswert?

@  Steffen Graap (Gast)

>Ich benutze folgende macros um auf die Portpins eine ATmega2560
>zuzugreifen:

>allerdings möchte ich den Wert nicht fest zuweisen (MOSI_QT = 1) sondern
>durch eine Berechnung übergeben. Das ganze sieht zur Zeit so aus:

Viel zu akademisch und aufwänfdig. Nimm ein switch, das ist zehnmal 
schneller.

1
  switch (bit_pos) {
2
    case 0: SBIT (PORTF, 0); break;
3
    case 1: SBIT (PORTF, 1); break;
4
    case 2: SBIT (PORTF, 2); break;
5
    case 3: SBIT (PORTF, 3); break;
6
    case 4: SBIT (PORTF, 4); break;
7
    case 5: SBIT (PORTF, 5); break;
8
    case 6: SBIT (PORTF, 6); break;
9
    case 7: SBIT (PORTF, 7); break;
10
  }

>Das ganze wird in einem Interrupt ausgeführt, der alle 150
>Prozessortakte ausgeführt werden soll. Für eine kurze Lösung wäre ich
>dankbar.

Wozu dann die variable Bitposition? Da kann man auch über ein "variable 
Konstante" lösen, sprich ein define.

MFG
Falk

von Steffen Graap (Gast)


Lesenswert?

@ Peter

Hast recht, nachdem ich das ";" gesetzt habe gabs keine Fehlermeldung, 
aber die Laufzeit bleibt natürlich. Ich werd mal versuchen das schieben 
pro Interruptaufruf auf einen Schritt zu reduzieren.


@ Falk

es geht nicht darum unterschiedlichen Portpins die Information zukommen 
zu lassen, sondern einem Portpin die einzelnen Bits von u32QT_Outbyte 
nacheinander zu übergeben. (Software-SPI)

Gruß Steffen

von Steffen Graap (Gast)


Lesenswert?

@ Falk

wie bekommt man den Quellcodeschnipsel farbig in Posting?

Steffen

von Johannes M. (johnny-m)


Lesenswert?

Steffen Graap wrote:
> wie bekommt man den Quellcodeschnipsel farbig in Posting?
Schau einfach mal in dem "Antwort schreiben"-Kasten direkt unter den 
"Wichtigen Regeln" unter der Überschrift "Formatierung"...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Steffen Graap wrote:

> Ich werd mal versuchen das schieben
> pro Interruptaufruf auf einen Schritt zu reduzieren.

Das sollte für ein Software-SPI ziemlich optimalen Code bringen.
Du extrahierst jeweils das Bit, was du gerade brauchst, danach
schiebst du einmal, fert'sch.

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.