www.mikrocontroller.net

Forum: Compiler & IDEs wieder einmal "undifined reference"


Autor: Josef Kkk (zumlin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen.
Ich weiß jetzt schon, dass es mein Fehelr ist, aber ich finde ihn 
einfach nicht. Ich versuche hier mal alles wichtige zu posten. Also:

Ich bekomme folgende Fehlermeldung:
../main.c:321: undefined reference to `_crc16_update'

in Zeile 321 steht jedoch:
320  ISR(USART0_TX_vect) //Transmit Routine
321  {
323  if ((tx_index >= BUFFER_SIZE) || (tx_index >= tx_buffer[PKT_LEN]))

...nichts
Schon mal komisch. Also suche in main.c die Funktion "_crc16_update". 
Das bringt mich zu Zeile 181:
crc = _crc16_update(crc, rx_buffer[i]);

Die Funktion kommt aus der util/crc16.h
Diese wird etwas komisch in mein Programm eingebunden. main.c bindet
#include "bus.h" ein.
bus.c bindet
#include <avr/crc16.h> ein.
avr/crc16.h sieht so aus:
/* $Id: crc16.h,v 1.10 2005/11/05 22:23:15 joerg_wunsch Exp $ */

#ifndef _AVR_CRC16_H_
#define _AVR_CRC16_H_

#include <util/crc16.h>


#endif /* _AVR_CRC16_H_ */

die util/crc16.h sieht so aus:
/* $Id: crc16.h,v 1.2.2.1 2006/04/19 20:35:54 joerg_wunsch Exp $ */

#ifndef _UTIL_CRC16_H_
#define _UTIL_CRC16_H_

#include <stdint.h>

/** \defgroup util_crc <util/crc16.h>: CRC Computations
    \code#include <util/crc16.h>\endcode

    This header file provides a optimized inline functions for calculating
    cyclic redundancy checks (CRC) using common polynomials.

    \par References:

    \par

    See the Dallas Semiconductor app note 27 for 8051 assembler example and
    general CRC optimization suggestions. The table on the last page of the
    app note is the key to understanding these implementations.

    \par

    Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e
    Embedded \e Systems \e Programming. This may be difficult to find, but it
    explains CRC's in very clear and concise terms. Well worth the effort to
    obtain a copy.

    A typical application would look like:

    \code
    // Dallas iButton test vector.
    uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };

    int
    checkcrc(void)
    {
  uint8_t crc = 0, i;

  for (i = 0; i < sizeof serno / sizeof serno[0]; i++)
      crc = _crc_ibutton_update(crc, serno[i]);

  return crc; // must be 0
    }
    \endcode
*/

/** \ingroup util_crc
    Optimized CRC-16 calculation.

    Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)<br>
    Initial value: 0xffff

    This CRC is normally used in disk-drive controllers.

    The following is the equivalent functionality written in C.

    \code
    uint16_t
    crc16_update(uint16_t crc, uint8_t a)
    {
  int i;

  crc ^= a;
  for (i = 0; i < 8; ++i)
  {
      if (crc & 1)
    crc = (crc >> 1) ^ 0xA001;
      else
    crc = (crc >> 1);
  }

  return crc;
    }

    \endcode */

static __inline__ uint16_t
_crc16_update(uint16_t crc, uint8_t a)
{

  int i;

  crc ^= a;
  for( i = 0; i < 8; ++i )
  {
      if( crc & 1 )
    crc = (crc>>1) ^ 0xA001;
      else
    crc = (crc>>1);
  }

  return crc;
}

/** \ingroup util_crc
    Optimized CRC-XMODEM calculation.

    Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)<br>
    Initial value: 0x0

    This is the CRC used by the Xmodem-CRC protocol.

    The following is the equivalent functionality written in C.

    \code
    uint16_t
    crc_xmodem_update (uint16_t crc, uint8_t data)
    {
        int i;

        crc = crc ^ ((uint16_t)data << 8);
        for (i=0; i<8; i++)
        {
            if (crc & 0x8000)
                crc = (crc << 1) ^ 0x1021;
            else
                crc <<= 1;
        }

        return crc;
    }
    \endcode */

static __inline__ uint16_t
_crc_xmodem_update(uint16_t __crc, uint8_t __data)
{
    uint16_t __ret;             /* %B0:%A0 (alias for __crc) */
    uint8_t __tmp1;             /* %1 */
    uint8_t __tmp2;             /* %2 */
                                /* %3  __data */

    __asm__ __volatile__ (
        "eor    %B0,%3"          "\n\t" /* crc.hi ^ data */
        "mov    __tmp_reg__,%B0" "\n\t"
        "swap   __tmp_reg__"     "\n\t" /* swap(crc.hi ^ data) */

        /* Calculate the ret.lo of the CRC. */
        "mov    %1,__tmp_reg__"  "\n\t"
        "andi   %1,0x0f"         "\n\t"
        "eor    %1,%B0"          "\n\t"
        "mov    %2,%B0"          "\n\t"
        "eor    %2,__tmp_reg__"  "\n\t"
        "lsl    %2"              "\n\t"
        "andi   %2,0xe0"         "\n\t"
        "eor    %1,%2"           "\n\t" /* __tmp1 is now ret.lo. */

        /* Calculate the ret.hi of the CRC. */
        "mov    %2,__tmp_reg__"  "\n\t"
        "eor    %2,%B0"          "\n\t"
        "andi   %2,0xf0"         "\n\t"
        "lsr    %2"              "\n\t"
        "mov    __tmp_reg__,%B0" "\n\t"
        "lsl    __tmp_reg__"     "\n\t"
        "rol    %2"              "\n\t"
        "lsr    %B0"             "\n\t"
        "lsr    %B0"             "\n\t"
        "lsr    %B0"             "\n\t"
        "andi   %B0,0x1f"        "\n\t"
        "eor    %B0,%2"          "\n\t"
        "eor    %B0,%A0"         "\n\t" /* ret.hi is now ready. */
        "mov    %A0,%1"          "\n\t" /* ret.lo is now ready. */
        : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2)
        : "r" (__data), "0" (__crc)
        : "r0"
    );
    return __ret;
}

/** \ingroup util_crc
    Optimized CRC-CCITT calculation.

    Polynomial: x^16 + x^12 + x^5 + 1 (0x8408)<br>
    Initial value: 0xffff

    This is the CRC used by PPP and IrDA.

    See RFC1171 (PPP protocol) and IrDA IrLAP 1.1

    \note Although the CCITT polynomial is the same as that used by the Xmodem
    protocol, they are quite different. The difference is in how the bits are
    shifted through the alorgithm. Xmodem shifts the MSB of the CRC and the
    input first, while CCITT shifts the LSB of the CRC and the input first.

    The following is the equivalent functionality written in C.

    \code
    uint16_t
    crc_ccitt_update (uint16_t crc, uint8_t data)
    {
        data ^= lo8 (crc);
        data ^= data << 4;

        return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4) 
                ^ ((uint16_t)data << 3));
    }
    \endcode */

static __inline__ uint16_t
_crc_ccitt_update (uint16_t __crc, uint8_t __data)
{
    uint16_t __ret;

    __asm__ __volatile__ (
        "eor    %A0,%1"          "\n\t"

        "mov    __tmp_reg__,%A0" "\n\t"
        "swap   %A0"             "\n\t"
        "andi   %A0,0xf0"        "\n\t"
        "eor    %A0,__tmp_reg__" "\n\t"

        "mov    __tmp_reg__,%B0" "\n\t"

        "mov    %B0,%A0"         "\n\t"

        "swap   %A0"             "\n\t"
        "andi   %A0,0x0f"        "\n\t"
        "eor    __tmp_reg__,%A0" "\n\t"

        "lsr    %A0"             "\n\t"
        "eor    %B0,%A0"         "\n\t"

        "eor    %A0,%B0"         "\n\t"
        "lsl    %A0"             "\n\t"
        "lsl    %A0"             "\n\t"
        "lsl    %A0"             "\n\t"
        "eor    %A0,__tmp_reg__"

        : "=d" (__ret)
        : "r" (__data), "0" (__crc)
        : "r0"
    );
    return __ret;
}

/** \ingroup util_crc
    Optimized Dallas (now Maxim) iButton 8-bit CRC calculation.

    Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)<br>
    Initial value: 0x0

    See http://www.maxim-ic.com/appnotes.cfm/appnote_number/27

    The following is the equivalent functionality written in C.

    \code
    uint8_t
    _crc_ibutton_update(uint8_t crc, uint8_t data)
    {
  uint8_t i;

  crc = crc ^ data;
  for (i = 0; i < 8; i++)
  {
      if (crc & 0x01)
          crc = (crc >> 1) ^ 0x8C;
      else
          crc >>= 1;
  }

  return crc;
    }
    \endcode
*/

static __inline__ uint8_t
_crc_ibutton_update(uint8_t __crc, uint8_t __data)
{
  uint8_t __i, __pattern;
  __asm__ __volatile__ (
    "  eor  %0, %4" "\n\t"
    "  ldi  %1, 8" "\n\t"
    "  ldi  %2, 0x8C" "\n\t"
    "1:  bst  %0, 0" "\n\t"
    "  lsr  %0" "\n\t"
    "  brtc  2f" "\n\t"
    "  eor  %0, %2" "\n\t"
    "2:  dec  %1" "\n\t"
    "  brne  1b" "\n\t"
    : "=r" (__crc), "=d" (__i), "=d" (__pattern)
    : "0" (__crc), "r" (__data));
  return __crc;
}

#endif /* _UTIL_CRC16_H_ */

Wo leigt der Fehler? Ist alles zwar etwas  verschachtelt, weil ich das 
meiste nicht selber geschrieben habe, aber funktionieren sollte das 
meiner Meinung nach schon. Meine Meinung ist aber offensichtlich falsch 
:)
Wo liegt mein Fehler?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das ein Tippfehler:

> #include "bus.h" ein.
> bus.c bindet
> #include <avr/crc16.h> ein.

Hast du wirklich ein bus.c  oder sollte das in der mittleren
Zeile bus.h heissen?


Solch verzwickten Header-Schachtelfehler komme ich sehr oft
mit folgender Strategie auf die Schliche:

Ich baue gezielt einen Fehler in ein Header File ein und sehe
nach, ob der Compiler den auch wirklich meldet.

zb.:
Würde ich mal in bus.h einen Fehler einbauen. Einfach
irgendwas in der Form
...
xyzui
#include <avr/crc16.h>
...

Kommt der Fehler, dann weis ich, dass diese Codestelle auch wirklich
eingebunden wurde und nicht durch irgendwelche #ifdef oder dgl.
rausgefallen ist. Kommt er nicht, dann verschiebe ich den Fehler
nach vorne bzw. ausserhalb des Header Files, bis ich ihn sehe.
Siehst du den Fehler im Compiler, dann wuerde ich ihn mal in die
crc16.h heineinverschieben und dann geht das Spielchen von vorne
los.

Und so taste ich mich an die Codestelle ran, die dafür sorgt
dass ein Header aus irgendeinem Grund nicht eingebunden wird.
Das ganze Vorgehen klingt sehr primitiv. Ist es auch. Geht aber
in der Praxis sehr schnell.

Autor: Josef Kkk (zumlin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verdammt. Danke. :)
Das war der Fehler.

Jetzt bekomm ich aber
gcc plug-in: Error: Object file not found on expected location 
C:\AVR\RS485\default\rs485.elf

Hier mal die "Build" Ausgabe. Alles darin ist leider nicht auf meinem 
Mist gewachsen. :)
Build started 24.11.2007 at 18:46:49
avr-gcc.exe -mmcu=atmega128 -Wl,-Map=rs485.map bus.o main.o uart0.o   -L"C:\Programme\AVRlib"  -lm -lc  -o rs485.elf
main.o: In function `ArbBitSend':
../bus.c:29: multiple definition of `priority'
bus.o:../bus.c:29: first defined here
main.o: In function `ArbBitSend':
../bus.c:29: multiple definition of `loneliness'
bus.o:../bus.c:29: first defined here
main.o: In function `ArbBitSend':
../bus.c:29: multiple definition of `mrbus_activity'
bus.o:../bus.c:29: first defined here
main.o: In function `ArbBitSend':
../bus.c:29: multiple definition of `rx_index'
bus.o:../bus.c:29: first defined here
main.o: In function `ArbBitSend':
../bus.c:31: multiple definition of `tx_index'
bus.o:../bus.c:31: first defined here
main.o: In function `ArbBitSend':
../bus.c:29: multiple definition of `ArbBitSend'
bus.o:../bus.c:29: first defined here
main.o: In function `xmit_packet':
../bus.c:66: multiple definition of `xmit_packet'
bus.o:../bus.c:66: first defined here
make: *** [rs485.elf] Error 1
Build succeeded with 0 Warnings...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja. Das wirst du wohl korrigieren müssen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Josef Kkk wrote:
> Verdammt. Danke. :)
> Das war der Fehler.

Was. Das mit dem bus.c/bus.h?

Du wirst doch nicht. Oder doch?
Du hast da aber jetzt nicht wirklich ein
#include "bus.c"
daraus gemacht?

http://www.mikrocontroller.net/articles/FAQ#Ich_ha...

Autor: Josef Kkk (zumlin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:)
Nur wie? Ich flipp noch aus mit dem Zeugs.
in bus.c wird keine der Variablen erzeugt die werden ja in der bus.h 
erzeugt, und die scahut soweit ganz gut aus.

hier mal die bus.h
#ifndef BUS_H
#define BUS_H

#define BUFFER_SIZE  0x14   // 20 bytes

#define UART_BAUD_RATE      9600    
#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1)

// AVR type-specific stuff


#define RS485PORT PORTE
#define RS485DDR DDRE
#define RS485TXEN 2 //(=PE2)
#define TX 1
#define RX 0
#define SER_CONT_REG UCSR0B
#define SER_STAT_REG UCSR0A
#define UART_RXMASK 0x01   // ??
#define UARTPORT PINE    // ?? 
#define RC_ERR_MASK 0x0C  // ??
#define CHR9 UCSZ2
#define OR DOR
#define UBRR UBRRL
#define UDR UDR0




/* Packet component defines */
#define PKT_SRC   0
#define PKT_DEST  1
#define PKT_LEN   2
#define PKT_CRC_L 3
#define PKT_CRC_H 4
#define PKT_TYPE  5


// for programming CVs
#define PKT_CV 6
#define PKT_VALUE 7


/* Status Masks */
#define RX_PKT_READY 0x01
#define TX_PKT_READY 0x80
#define TX_BUF_ACTIVE 0x20


/*timing defines for 16MHz
#define __10_MS 0x9C
#define __20_US 0x28
#define __2_MS 0x1E
#define __10_US 0x14
#define __100_US 0xC8
*/

//general timig defines
#define __10_MS (10*(F_CPU/1024)/1000)
#define __2_MS (2*(F_CPU/1024)/1000)
#define __20_US (20*(F_CPU/8)/1000000)
#define __10_US (10*(F_CPU/8)/1000000)
#define __100_US (100*(F_CPU/8)/1000000)

unsigned char dev_addr;
unsigned short crc16_value;

unsigned char rx_buffer[BUFFER_SIZE];
unsigned char rx_input_buffer[BUFFER_SIZE];
unsigned char tx_buffer[BUFFER_SIZE];
unsigned char tx_index=0;
unsigned char rx_index=0;
unsigned char state;
unsigned char mrbus_activity=0;
unsigned char loneliness=6;
unsigned char priority=6;

unsigned char ArbBitSend(unsigned char bit);
unsigned char xmit_packet(void);


#endif

und hier auch noch die bus.c wenn ich eh schon so viel zeugs sinnlos 
poste :(
#include "bus.h"
#include <avr/io.h>
#include <stdlib.h>
#include <stdint.h>
#include "global.h"
#include <avr/interrupt.h>
#include <avr/crc16.h>


unsigned char ArbBitSend(unsigned char bit)
{
  char slice;
  char tmp=0;

  if (bit)
  {
    //TX is already 0 (mark)
    cbi(RS485PORT, RS485TXEN);
  } else {
    sbi(RS485PORT, RS485TXEN);
  }

  for (slice=0; slice<10; slice++)
  {
    if (slice > 2)
    {
      if (UARTPORT & UART_RXMASK) tmp=1;
      if (tmp ^ bit)
      {
        cbi(RS485PORT, RS485TXEN);
        sbi(SER_CONT_REG, RXEN);
        sbi(SER_CONT_REG, RXCIE);
        sei();
        return(1);
      }
      
    }
    // delay_us(20);
    TCNT0 = 0x00;
    while (TCNT0 < __20_US);
  }

  return(0);
}


unsigned char xmit_packet(void)
{
  unsigned char status;
  unsigned char address;
  unsigned char i;
  
  address = tx_buffer[PKT_SRC];
  
  if (state & TX_BUF_ACTIVE) return(1);
  cbi(SER_CONT_REG, UDRIE);
  
  // First calculate CRC16
  crc16_value=0x0000;
  
  for(i=0;i<tx_buffer[PKT_LEN];i++)
  {
    if ((i != PKT_CRC_H) && (i != PKT_CRC_L))
    {
      crc16_value = _crc16_update(crc16_value, tx_buffer[i]);
    }
  }
  tx_buffer[PKT_CRC_L] = crc16_value & 0xFF;
  tx_buffer[PKT_CRC_H] = crc16_value >> 8;  
    
  mrbus_activity=0;
  
  /* Begin of arbitration sequence */
  TCNT1H = 0x00;
  TCNT1L = 0x00;  
  while (TCNT1L < __2_MS);
  
  if (mrbus_activity) return(1);
  
  status = ((loneliness+priority)*10) + (address & 0x0F); 
  
  RS485PORT&= ~((1 << 0) | (1 << 1) | (1 << 2));      // ersetzt 0x00;
  // Clear driver enable
  // set xmit pin low
  
  cbi(RS485DDR, RX); // Set as input
  
  cbi(SER_CONT_REG, TXEN);
  cbi(SER_CONT_REG, RXEN);  // Serial Port disable
  
  
  for (i=0; i<20; i++)
  {
    // delay_us(20);
    TCNT0 = 0x00;
    while(TCNT0 < __20_US);
    if (0 == (UARTPORT & UART_RXMASK))
    {
      sbi(SER_CONT_REG, RXEN);
      sbi(SER_CONT_REG, RXCIE);
      sei();
      return(1);
    }
  }

  /* Now, wait calculated time from above */
  for (i=0; i<status; i++)
  {
    // delay_us(10);
    TCNT0 = 0x00;
    while(TCNT0 < __10_US);
    if (0 == (UARTPORT & UART_RXMASK))
    {
      sbi(SER_CONT_REG, RXEN);
      sbi(SER_CONT_REG, RXCIE);
      sei();
      return(1);
    }
  }
  
  /* Arbitration Sequence - 4800 bps */
  /* Start Bit */
  if (ArbBitSend(0)) return(1);

  for (i=0; i<8; i++)
  {
    status = ArbBitSend(address & 0x01);
    address = address >> 1;

    if (status == 1) return(1);
  }  

  /* Stop Bits */
  if (ArbBitSend(1)) return(1);
  if (ArbBitSend(1)) return(1);

  sbi(SER_CONT_REG, RXEN);
  sbi(SER_CONT_REG, TXEN);
  sbi(RS485PORT, RS485TXEN);
  
  tx_index=0;
  
  return(0); // Control over bus is assumed
}

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn main.c und bus.c die bus.h einbinden, sieht die bus.h nicht so gut 
aus. Du musst schon dafür sorgen, dass die Variablendefinition nicht 
mehrfach vorgenommen wird. Z.B.

--bus.h---
#include <inttypes.h>
#ifdef BUS_MODULE
  uint32_t xyz;
#else
  extern uint32_t xyz;
#endif 

--bus.c---
#define BUS_MODULE
#include "bus.h" 


--main.c---
#include "bus.h" 

Autor: Josef Kkk (zumlin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
main.c bindet aber die bus.c ein nicht bus.h.
Sollte das nicht dann funktionieren?

PS: schön langsam glaub ich steige ich auf ein einfacheres Protokoll für 
rs485 um. :)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.
Man soll keine C-Dateien in C-Dateien includen.

Genügt das?

Du sollst <util/crc16.h> in main.c includen (oder ein Headerfile,
was diese Datei bereits included).  Wenn du in main.c die Funktion
_crc16_ccitt_update() benutzt, musst du sie auch deklariert (und
im vorliegenden Falle infolge des Inlining sogar definiert) haben.

Autor: Josef Kkk (zumlin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok. Hab ich gemacht. Das Problem mit dem neu definieren von Variablen 
hab ich aber noch immer.

wenn ich also in main.c und bus.c die bus.h einfügen will, würde ich, um 
eine redefinitinon zu vermeiden folgendes machen.

bus.h:

#ifndef _BUS_H
#define _BUS_H

#define F_CPU 1234567890
#endif

Also so wie ich das oben auch versucht habe. Leider bekomme ich aber 
immer noch die Fehlermedlungen wie oben gepostet. Was geth da schief?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In eine .h-Datei gehört keine Varaiblen-Deklaration.
In eine .h-Datei gehört keine Varaiblen-Deklaration.
In eine .h-Datei gehört keine Varaiblen-Deklaration.
In eine .h-Datei gehört keine Varaiblen-Deklaration.
In eine .h-Datei gehört keine Varaiblen-Deklaration.
In eine .h-Datei gehört keine Varaiblen-Deklaration.
In eine .h-Datei gehört keine Varaiblen-Deklaration.
In eine .h-Datei gehört keine Varaiblen-Deklaration.


in bla.h gehört:
extern int var1;

in bla.c gehört
int var1;

#define F_CPU gehört entweder in main.c nach GANZ oben, oder besser noch 
per -DF_CPU xxxxxx in die Compilerflags.

Oliver

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aiaiaiaiai

VARIABLE :-)

Oliver

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver wrote:
> In eine .h-Datei gehört keine Varaiblen-Deklaration.

s/Deklaration/Definition/g

Ansonsten: Zustimmung.

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.