Forum: Mikrocontroller und Digitale Elektronik Funktion will nicht - Port_Init


von Moinsen (Gast)


Lesenswert?

Mit folgender Funktion, versuche ich mit den übergebenen Parameter in 
meiner Main, nur bestimmte Ports als Output zu deklarieren.


void PortOut_init(unsigned char port, unsigned char von, unsigned char 
bis){

  unsigned char ports_out = 0;

  for (int i=von; i <= bis; i++)
  {
    ports_out += pow(2, i);
  }


  switch (port)
  {  case 'B':  DDRB = ports_out;
          PORTB &= ~ports_out;
          break;
    case 'C':  DDRC = ports_out;
          PORTC &= ~ports_out;
          break;
    case 'D':  DDRD = ports_out
          PORTD &= ~ports_out;
          break;
    default:  break;
  }

}



der main Aufruf ist wie folgt:

PortOut_init('C', 2, 5);

Also, nur die Ports PORTC2 - PORTC5 sollen als Output dienen.

Jedoch kommt der folgende Build-Fehler:


Error called object 'ports_out' is not a function or function pointer



Warum will er ports_out als funktion oder pointer deklariert haben, wenn 
ich doch einfach nur den Wert übergeben will.

Sprich ... Die Ports von PORTC von 2 bis 5 sollen als Output deklariert 
werden, also Register DDRC: 0b00111100 ... entspricht 0x3C entspricht 
dem Wert 60. und Register PORTC (Angeschlossene LED's aus) entspricht 
0xff

von Stefan E. (sternst)


Lesenswert?

Moinsen schrieb:
> Warum will er ports_out als funktion oder pointer deklariert haben, wenn
> ich doch einfach nur den Wert übergeben will.

Weil du ein Semikolon vergessen hast.

von Moinsen (Gast)


Lesenswert?

WOW ... was ein depp ich bin ... danke ... vielen dank.

von Moinsen (Gast)


Lesenswert?

wie kommt's das meine for-schleife auf den Wert 56 kommt und nicht wie 
erwartet 60? ... Hierdurch wir der eine Output nicht deklariert.

von Moinsen (Gast)


Lesenswert?

unsigned char ports_out = 0;

  for (int i=von; i <= bis; i++)
  {
    ports_out += pow(2, i);
  }


hierbei: von = 2 ... bis = 5

also:

2^2 + 2^3 + 2^4 + 2^5 = 60...

aber der kommt auf den wert 56. ... hab ich da ein Denkfehler?

von Anders Rum (Gast)


Lesenswert?

Eine Floating Point Library Funktion zu verwenden um
Bits zu erzeugen ist pervers. Ich sehen den Fehler auch
nicht, aber würde es so machen:
1
#include <stdio.h>
2
3
int main() 
4
{
5
  unsigned char von = 2;
6
  unsigned char bis = 5;
7
  unsigned char bit = 1<<von;
8
  unsigned char ports_out = 0;
9
10
  for (int i=von; i<=bis; i++)
11
  {
12
    ports_out += bit;
13
    printf ("ports_out = %i \n", ports_out);
14
    bit <<= 1;
15
  }
16
}

von Moinsen (Gast)


Lesenswert?

Anders Rum schrieb:
> Eine Floating Point Library Funktion zu verwenden um
> Bits zu erzeugen ist pervers. Ich sehen den Fehler auch
> nicht, aber würde es so machen:
> #include <stdio.h>
>
> int main()
> {
>   unsigned char von = 2;
>   unsigned char bis = 5;
>   unsigned char bit = 1<<von;
>   unsigned char ports_out = 0;
>
>   for (int i=von; i<=bis; i++)
>   {
>     ports_out += bit;
>     printf ("ports_out = %i \n", ports_out);
>     bit <<= 1;
>   }
> }


Das funktioniert wunderbar.

Das mit dem Schieben von Bits sitzt noch nicht ganz. Muss mir diese 
Technik aneignen. Hilf mir ma, ich versuche es ma zu erklären und du 
schaust ob ich richtig liege.


mit " unsigned char ports_bit = 1<<von; " ... deklarierst du, welches 
Bit bei ports_bit gesetzt wird mittels übergebenen Wert "von".

mittels " ports_bit <<= 1; " schiebst du jeweils die Bits setzend links 
durch.

Okay ... soweit alles gut.

Aber durch die Deklaration von den Ports, wie bspweise "PORTC |= 
(1<<PORTC0);" bin ich der überzeugung dass immer eine Oder Verknüpfung 
verwendet werden soll. Also in dem Sinne: unsigned char ports_bit |= 
(1<<von); ...

Ist hierbei die Überlegung falsch?

von Anders Rum (Gast)


Lesenswert?

Moinsen schrieb:
> Ist hierbei die Überlegung falsch?

Funktioniert auch, aber hier ist die Addition einfacher
und übersichtlicher. Ich darf addieren solange nur ein Bit
in der Variable gesetzt ist.

von Rolf M. (rmagnus)


Lesenswert?

Moinsen schrieb:
> mit " unsigned char ports_bit = 1<<von; " ... deklarierst du, welches
> Bit bei ports_bit gesetzt wird mittels übergebenen Wert "von".

Einfach gesagt: Er nimmt eine 1 (also einen Integer, bei dem genau ein 
Bit, nämlich das unterste gesetzt ist) und schiebt sie um "von" Bits 
nach links. Also in einzelnen Bits geschrieben:

Man nehme die 1:
00000001

und schiebe sie um 2 Bits nach links:
00000100

> mittels " ports_bit <<= 1; " schiebst du jeweils die Bits setzend links
> durch.

Es werden bei jedem Schleifendurchlauf alle Bits in der Variable um ein 
Bit nach links geschoben. Da in der Variable nur eine einzige 1 
vorkommt, läuft die quasi durch, also:

00001000
00010000
00100000

Und was passiert jetzt, wenn ich diese vier Werte addiere?

00000100 +
00001000 +
00010000 +
00100000 =
--------
00111100 = 60⏨

> Aber durch die Deklaration von den Ports, wie bspweise "PORTC |=
> (1<<PORTC0);" bin ich der überzeugung dass immer eine Oder Verknüpfung
> verwendet werden soll.

Wenn du die gewünschten Bits setzen, aber alle anderen unverändert 
lassen willst, ja.

> Also in dem Sinne: unsigned char ports_bit |=
> (1<<von); ...

+= hat in diesem speziellen Fall das gleiche Ergebnis, aber üblicher 
ist, die ODER-Operation zu verwenden.

von Moinsen (Gast)


Lesenswert?

Bedanke mich für die ausführliche Erklärung.

Diesem Ausdruck bezüglich:

unsigned char ports_bit |=(1<<von);


Liefert mir aber das Atmel-Studio folgenden Fehler:


Error  expected '=', ',', ';', 'asm' or '__attribute__' before '|=' 
token


Also ist dieser Befehl doch nur den Registern vorbehalten?

von Anders Rum (Gast)


Lesenswert?

unsigned char ports_bit = (1<<von);
------------------------!----------

von Einer K. (Gast)


Lesenswert?

Moinsen schrieb:
> Also ist dieser Befehl doch nur den Registern vorbehalten?

Bitte nur im Schritttempo denken.

von Rolf M. (rmagnus)


Lesenswert?

Moinsen schrieb:
> Also ist dieser Befehl doch nur den Registern vorbehalten?

Nein, aber er ist bereits existierenden Variablen vorbehalten. Worauf 
soll die ODER-Verknüpfung denn angewendet werden wenn gleichzeitig die 
Variable auf der linken Seite erst erzeugt wird?

von jz23 (Gast)


Lesenswert?

Ein bisschen irritierend finde ich die Fehlermeldung allerdings schon. 
Schließlich könnte man ja wirklich wollen, dass einfach der letzte 
Speicherinhalt mit dem Ausdruck Oder-Verknüpft wird. Auch wenn mir jetzt 
dafür kein wirkliches Szenario einfällt...

von Moinsen (Gast)


Lesenswert?

liegt vllt daran, dass ich ports_bit nicht vorher die "0" zugewiesen 
habe und dieser irgend ein Wert annimmt.

von Einer K. (Gast)


Lesenswert?

Moinsen schrieb:
> liegt vllt daran, dass ich ports_bit nicht vorher die "0"
> zugewiesen
> habe und dieser irgend ein Wert annimmt.

Jain!

Es liegt daran, dass die Variable, welche du verändern willst, zu dem 
Zeitpunkt noch nicht fertig definiert ist. Du kannst sie erst nach 
abgeschlossener Definition lesend verwenden.

von Rolf M. (rmagnus)


Lesenswert?

jz23 schrieb:
> Ein bisschen irritierend finde ich die Fehlermeldung allerdings schon.

Es gibt einen fundamentalen Unterschied zwischen
1
name = wert;
und
1
typ name = wert;

auch wenn es sehr ähnlich aussieht. Ersteres ist eine Zuweisung, 
zweiteres eine Definition einer neuen Variable mit Initialisierung. 
Ersteres gibt es als Variationen auch mit den ganzen logischen und 
aritmetischen Operationen, letzteres nicht, weil die Variable wie schon 
gesagt da erst zu existieren beginnt und keinen voherigen Wert hat, mit 
dem man den Wert rechts verknüpfen könnte. Es gibt keinen sinnvollen 
Grund, eine "ODER-Initialisierung" zu definieren, da sie legal nicht 
nutzbar wäre.

> Schließlich könnte man ja wirklich wollen, dass einfach der letzte
> Speicherinhalt mit dem Ausdruck Oder-Verknüpft wird.

Es gäbe einen Weg:
1
int x = x | 5;
aber es gibt einfach keine sinnvolle Anwendung dafür, und das Verhalten 
ist undefiniert.

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.