mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C Programmierung struktur, pointrer


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe hier kleine logische Verständnisprobleme:


Hier wird eine Struktur definiert mit dem Namen Zugriff.
Ich stelle mir ds so vor:
int x = (int test, char test_2) Zugriff
Also eine Variable Zugriff von Typ(int test, char test)
typedef struct  
{
    int test;
   char test_2;

} Zugriff; 

Hier wird eine Variable definiert (com_var_1), die auf Struktur Zugriff verweist.
Also hat diese Variable alle in Stuct definierte Datentypen?

 Zugriff com_var_1;

In main() wird die funktion aufgerufen mit der Adresse der Variable 
com_var_1.
Also habe ich die Funktion mit den Adressen von Werten int test, char 
test_2 aufgerufen?
In com_var_1

int main (void) 
{
  funktion_mit_pcd_werten_fuehlen(&com_var_1);
}

In dieser Funktion befühle ich die Struktur Zugriff mit Werten, die ich 
mit der Pointervariable *pointer an die Struktur übergeben.
 funktion_mit_pcd_werten_fuehlen(COM_TYP *pointer)
{
  (*pointer).baudrate = 9600;
  (*pointer).dataBits = 8;
  (*pointer).stopBits =  2;
  (*pointer).parity   =1;
  (*pointer).PCD_adress = 77;
}
Das Resultat:
funktion_mit_pcd_werten_fuehlen(&com_var_1) holt sich die 
Werte(Adressen) aus der Struktur.
funktion_mit_pcd_werten_fuehlen(COM_TYP *pointer) befühlt diese mit 
konkreten Werten.

Ist das so richtig?

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ist das so richtig?

Ja, wobei der Typ des Arguments com_var_1 aber COM_TYP * und nicht
Zugriff * sein muss.

Außerdem:
  (*pointer).baudrate = 9600;

schreibt man üblicherweise so:
  pointer->baudrate = 9600;

Das ist zwar semantisch das Gleiche, aber etwas übersichtlicher und
weniger Tipparbeit.

> funktion_mit_pcd_werten_fuehlen(COM_TYP *pointer) befühlt diese mit
> konkreten Werten.

Ich habe das Gefüll, du solltest noch ein klein wenig an deiner
Rechtschreibung feilen ;-)

Autor: Tuffke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

> Hier wird eine Variable definiert (com_var_1), die auf Struktur Zugriff 
verweist.
> Also hat diese Variable alle in Stuct definierte Datentypen?
--> Na ja! Also Typedef definiert keine wirklichen Speicherbereich so 
wie es Variablen tun. In erster Linie ist ein struct nur eine Art 
Schablone, wie die Speicherbereiche einer Variable logisch zugeordnet 
werden.

> Zugriff com_var_1;
--> Erst hiermit wird wirklich Speicher reserviert. An der Adresse von 
der Variablen com_var_1 findest Du eine Struktur der Form "Zugriff", 
sprich, erst 4 Byte (?) die test repräsentieren, gefolgt von 1 Byte das 
test_2 darstellt.


> In main() wird die funktion aufgerufen mit der Adresse der Variable com_var_1.
> Also habe ich die Funktion mit den Adressen von Werten int test, char test_2 
aufgerufen?
--> Nein, es ist so wie Du davor geschrieben hast. Du rufst die Funktion 
mit der Adresse von com_var_1 auf. Der Kompiler "weiß" jedoch, dass 
diese Variable den Typ Zugriff ist und daher kann man darin 
(*pointer).test verwenden. Der Kompiler übersetzt dann wie folgt:
(*pointer).test  --> Speicheradresse = Basisadresse von com_var_1 (z.B. [003] )
(*pointer).test2 --> Speicheradresse = Basisadresse von com_var_1 + Größe von Test ( z.B. [007])


> funktion_mit_pcd_werten_fuehlen(COM_TYP *pointer)
> {
>   (*pointer).baudrate = 9600;
>   (*pointer).dataBits = 8;
>   (*pointer).stopBits =  2;
>   (*pointer).parity   =1;
>   (*pointer).PCD_adress = 77;
> }

Ok, Dein struct heißt dann eigentlich COM_TYP, oder? ;-)
Der Typ in der Variablen in main() als auch hier in dieser Funktion 
sollte der Selbe sein - damit das funktioniert.
Also gehört dann eher sowas dazu:
typedef struct  
{
 int  baudrate;
 char dataBits;
 char stopBits;
 char parity;
 char PCD_adress;
} COM_TYP; 

Gruß Tuffke

P.S.: Es heißt befüLLen nicht befüHLen ... wobei das andere eigentlich 
auch eine schöne Vorstellung ist ... :-D

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, konstruktive Kritik ist zur Kenntniss genommen!:)

Im nächsten Schritt will ich UART mit Daten füttern:

  baudrate = 9600;
  dataBits = 8;
  stopBits =  2;
  parity   = 1;

main()
Aufruf der Funktion mit der Adresse von com_var_1, diese verweist auf 
die Struktur mit Daten.

uart0_init(&com_var_1);


Die Funktion bekommt konkrete Werte (z.B dataBits = 8)
int uart0_init( COM_TYP *pointer )
{ 
  unsigned char dataBits;
  unsigned char stopBits;
  unsigned char parity;
  unsigned long int baudrate;
        unsigned char Temp;
   
Abfrage: Wie viele dataBits, laut Definition 8
  ........

       if (dataBits == 8)
    Temp |= 0x03;
  else if (dataBits ==  7)
    Temp |= 0x02;
  else
    return(1);

  .......

Register U0LCR erhält 8 dataBits
  U0LCR  = Temp;


Leider liefert die Funktione int uart0_init( COM_TYP *pointer ) keine 
richtigen Werte an die IF-Abfragen.
Wenn ich in der Funktion die Variablen Fest definiere z.B. :unsigned 
char dataBits=8;
Dann werden die Register richtig gesetzt, Also es liegt nicht an den 
Abfragen.


Hilfe.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die tolle Erkläreung.
Ja min struct-Type heißt COM_TYP

Diese Werte brauch ich eigenlich in der Funktin nicht zu deklarieren
  unsigned char dataBits;
  unsigned char stopBits;
  unsigned char parity;
  unsigned long int baudrate;
 


diese müssen doch durch COM_TYP *pointer an die Funktion übergeben 
werden
int uart0_init( COM_TYP *pointer )

Das passiert aber nicht, der Compiler meldet:
Blinky.c(52): error:  #20: identifier "dataBits" is undefined
Also erhält er die Werte nicht.

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:
> Danke, konstruktive Kritik ist zur Kenntniss genommen!:)
>
> Im nächsten Schritt will ich UART mit Daten füttern:
>
>   baudrate = 9600;
>   dataBits = 8;
>   stopBits =  2;
>   parity   = 1;
>
> main()
> Aufruf der Funktion mit der Adresse von com_var_1, diese verweist auf
> die Struktur mit Daten.
>
>
>
uart0_init(&com_var_1);
>
>
> Die Funktion bekommt konkrete Werte (z.B dataBits = 8)
>
> int uart0_init( COM_TYP *pointer )
> {
>   unsigned char dataBits;
>   unsigned char stopBits;
>   unsigned char parity;
>   unsigned long int baudrate;
>         unsigned char Temp;

Hast du das hier nur zum Test deklariert?

> 
> Abfrage: Wie viele dataBits, laut Definition 8
>   ........
> 
>        if (dataBits == 8)
>     Temp |= 0x03;
>   else if (dataBits ==  7)
>     Temp |= 0x02;
>   else
>     return(1);
> 
ich würde daraus erstmal ein switch-case machen ist übersichtlicher:

switch(dataBits)
{
case 8:
Temp |= 0x03;
break;
case 7:
break;
Temp |= 0x02;
default:
break;
}
>   .......
> 
> Register U0LCR erhält 8 dataBits
>   U0LCR  = Temp;
> 
>
>

Mhm... also deine Datenstruktur die du übergibst muss natürlich 
initialisiert sein. Also in dataBits muss konkret auch ein vernünftiger 
Wert stehen.

Ansonsten sollte es keinen Unterschied machen, ob du die Werte lokal 
definierst und dann zuweist oder global definierst und dann zuweist.


> Leider liefert die Funktione int uart0_init( COM_TYP *pointer ) keine
> richtigen Werte an die IF-Abfragen.

Siehe oben.

> Wenn ich in der Funktion die Variablen Fest definiere z.B. :unsigned
> char dataBits=8;
> Dann werden die Register richtig gesetzt, Also es liegt nicht an den
> Abfragen.

Richtig, der Fehler muss als bei der Übergabe deiner globalen 
Datenstruktur an deine lokale Variable liegen.

Warum legst du eigentlich noch eine lokale Variable an? Du hast wohl 
zuviel Stack oder wie? ;)

Gruß

>
> Hilfe.

Autor: Sergey S. (Firma: ARM LPC2134, uVision3, in C) (serik00)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So Leute das ist mein kompletter Quellcode.

Der Funktion(int uart0_init(COM_TYP *pointer))
müssen diese Werte übergeben werden:

   pointer->baudrate = 9600;
   pointer->dataBits = 8;
   pointer->stopBits =  1;
   pointer->parity   =   0;
   pointer->PCD_adress = 77;


funktion_mit_pcd_werten_fuellen(COM_TYP *pointer)
 {
   pointer->baudrate = 9600;
   pointer->dataBits = 8;
   pointer->stopBits =  1;
   pointer->parity   =   0;
   pointer->PCD_adress = 77;
 }

Wie läuft die Übergabe.
Bin bemühter Anfänger.
Vielen Dank im Voraus.

#include <stdio.h>                         /* standard I/O .h-file */
#include <LPC213x.H>                       /* LPC213x definitions  */

 typedef struct  
{
   unsigned long int baudrate;
  unsigned char dataBits;
  unsigned char stopBits;
  unsigned char parity;
  unsigned char PCD_adress;
} COM_TYP; 

 COM_TYP com_var_1;
/******************************************************************************/
 void init_serial (void)  
{               
  IODIR1  =   0x03000000;          /* LEDs P1.24,P1.23 defined as Outputs  */          
     PINSEL0  =  0x00050005;      /*Enable TxD1,TxD0,RxD1,RxD0*/
  IODIR0  =  0x10400410;      /*OUT: RTS0_P0.4, RTS1_P0.14, COM1_P0.22, COM0_P0.28*/
  IOCLR0  =  0x10400010;      /*LOW auf 0 COM1,0 = 0(RS485), RTS0=0(Sender)*/
  IOSET0  =  0x00000400;      /*HIGH auf 1 RTS1=1(Empfänger),P0.10*/                           
}
/******************************************************************************/
void init_uart1(void)
{
  U1LCR    =  0x83;    /*8 bits, 1 stopbit, no Parity, enable DLAB*/
  U1DLM    =  0x01;    /*9600 Baud Rate, 55.296.000 PCLK*/
  U1DLL    =  0x68;    /*360dez=0x0168*/
  U1LCR    =  0x03;    /*disable DLAB*/
  U1FCR    =  0x01;    /*enable UART1-FIFO*/ 
}
/******************************************************************************/
funktion_mit_pcd_werten_fuellen(COM_TYP *pointer)
 {
   pointer->baudrate = 9600;
   pointer->dataBits = 8;
   pointer->stopBits =  1;
   pointer->parity =   0;
   pointer->PCD_adress = 77;
 }
/******************************************************************************/
int uart0_init(COM_TYP *pointer)
{ 
  unsigned char ucTemp;

  ucTemp = 0;
  // Word Lenght Select
  if (dataBits == 8)
    ucTemp |= 0x03;
  else if (dataBits ==  7)
    ucTemp |= 0x02;
  else
    return(1);

  // Stop Bit Select
  if (stopBits == 1 )
    ucTemp |= 0x00;
  else if ( stopBits == 2 )
    ucTemp |= 0x04;
  else
    return(1);

  // Parity Enable
   if (parity == 0)    //disable
     ucTemp |= 0x00;
  else if (parity == 1)  //enable
    ucTemp |= 0x04;
  else
    return(1);

  //Parity Select
  if (parity == 'o')
    ucTemp |= 0x00;
  else if (parity == 'e')
    ucTemp |= 0x10;
  else if (parity == 1)
    ucTemp |= 0x20;
  else if (parity == 0)
    ucTemp |= 0x30;
  else
    return(1);

  // Devisor Latch Access Bit(DLAB) enable
  ucTemp |= 0x80; 
  U0LCR  =  ucTemp;    /*8 bits, 1 stopbit, no Parity, enable DLAB*/

  // Baudrate Select  
  switch ( baudrate )
  {
    case 4800:  
      U0DLM    =  0x02;    /*4800 Baud Rate, 55.296.000 PCLK*/
      U0DLL    =  0xD0;    /*720dez=0x02Do*/
      break; 
    case 9600:  
      U0DLM    =  0x01;    /*9600 Baud Rate, 55.296.000 PCLK*/
      U0DLL    =  0x68;    /*360dez=0x0168*/
      break; 
    case 19200:  
      U0DLM    =  0x00;    /*19200 Baud Rate, 55.296.000 PCLK*/
      U0DLL    =  0x64;    /*180dez=0x0064*/
      break; 
    case 38400:  
      U0DLM    =  0x00;    /*38400 Baud Rate, 55.296.000 PCLK*/
      U0DLL    =  0x5A;    /*90dez=0x005A*/
      break; 
    case 76800:  
      U0DLM    =  0x00;    /*9600 Baud Rate, 55.296.000 PCLK*/
      U0DLL    =  0x68;    /*45dez=0x003D*/
      break; 
    default:
      //return(ERR_COM_INIT_LINE_SETTINGS);
      break;
      
  }

  // Devisor Latch Access Bit(DLAB) disable
  ucTemp = 0;
  ucTemp |= 0x00;
  U0LCR    =  ucTemp;
  
  //FIFO UART enable    
  U0FCR    =  0x01;
  return 1;    
}
/******************************************************************************/
void sendchar (void)  {                 /* Write character to Serial Port    */
  while (!(U0LSR & 0x20));
  (U0THR = 0x89);
  (U0THR = 0x89);
  (U0THR = 0x89);
  (U0THR = 0x89);
  (U0THR = 0x89);
  (U0THR = 0x89);
  (U0THR = 0x89);
  (U0THR = 0x89);
}
/******************************************************************************/
int receivechar (void)  {                     /* Read character from Serial Port   */

  while (!(U1LSR & 0x01));

  return (U1RBR);
}
/******************************************************************************/

int main (void) 
{
 
  init_serial();                   /* Initialize Serial Interface   */
  funktion_mit_pcd_werten_fuellen(&com_var_1);
  init_uart1();
  uart0_init(&com_var_1);
  do 
  {                               /* Loop forever */
  {
   sendchar ();
  }
  }  while(1);
}

Autor: Sergey S. (Firma: ARM LPC2134, uVision3, in C) (serik00)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab das Problem endllich gelöst und zwar der Zugriff auf die Variablen 
muss so erfolgen:
pointer->Variable


  ucTemp = 0;
  // Word Lenght Select
  if (pointer->dataBits == 8)
    ucTemp |= 0x03;
  else if (pointer->dataBits ==  7)
    ucTemp |= 0x02;
  else
    return(1);

  // Stop Bit Select
  if (pointer->stopBits == 1 )
    ucTemp |= 0x00;
  else if ( pointer->stopBits == 2 )
    ucTemp |= 0x04;
  else
    return(1);

  // Parity Enable
   if (pointer->parity == 0)    //disable
     ucTemp |= 0x00;
  else if (pointer->parity == 1)  //enable
    ucTemp |= 0x04;
  else
    return(1);

  //Parity Select
  if (pointer->parity == 'o')
    ucTemp |= 0x00;
  else if (pointer->parity == 'e')
    ucTemp |= 0x10;
  else if (pointer->parity == 1)
    ucTemp |= 0x20;
  else if (pointer->parity == 0)
    ucTemp |= 0x30;
  else

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eugen Spaß schrieb:
> Hab das Problem endllich gelöst und zwar der Zugriff auf die Variablen
> muss so erfolgen:
> pointer->Variable

Richtig. Aus dem ersten Codeschnippsel kam nicht heraus was du 
tatsächlich falsch gemacht hast.

Noch eine kleine Anmerkung:
Mehrere returns innerhalb einer Funktion sind unschön und eine 
potentielle Fehlerquelle. Gut, in dieser kleinen Funktion vielleicht 
noch nicht, aber wenn man den Stil beibehält, fängt man sich früher oder 
später Probleme ein.

Besser:
sich oben eine return Variable definieren. Diese dann im 
Funktionsverlauf setzen (dort wo du direkt dein return gemacht hättest) 
und dann am Ende EIN return.

Gruß

PS: Ist es Absicht, dass du bei parity und stop bit die gleichen Bits 
setzt?!

>
>
>   ucTemp = 0;
>   // Word Lenght Select
>   if (pointer->dataBits == 8)
>     ucTemp |= 0x03;
>   else if (pointer->dataBits ==  7)
>     ucTemp |= 0x02;
>   else
>     return(1);
>
>   // Stop Bit Select
>   if (pointer->stopBits == 1 )
>     ucTemp |= 0x00;
>   else if ( pointer->stopBits == 2 )
>     ucTemp |= 0x04;
>   else
>     return(1);
>
>   // Parity Enable
>    if (pointer->parity == 0)    //disable
>      ucTemp |= 0x00;
>   else if (pointer->parity == 1)  //enable
>     ucTemp |= 0x04;
>   else
>     return(1);
>
>   //Parity Select
>   if (pointer->parity == 'o')
>     ucTemp |= 0x00;
>   else if (pointer->parity == 'e')
>     ucTemp |= 0x10;
>   else if (pointer->parity == 1)
>     ucTemp |= 0x20;
>   else if (pointer->parity == 0)
>     ucTemp |= 0x30;
>   else

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.