Forum: Mikrocontroller und Digitale Elektronik String-Array löschen


von Patric K. (widder84)


Lesenswert?

Hallo zusammen.

via RS232 Schnittstelle will ich im Terminalprogramm eine Eingabe 
fortlaufend wieder ausgeben, solange bis der Bediener die Enter Taste 
betätigt.
Dies funktioniert beim ersten mal einwandfrei!
Doch bei einer zweiten eingabe funktioniert es nicht mehr!
Wenn ich die Array's, input und serienr,  komplett löschen könnte, würde 
es sicher funktionieren!!
aber wie geht dies??
Vielen Dank im voraus für eure Hilfe!!

Hier mein Codeauschnitt:

//Variablen definieren
uint8_t input[1];
uint8_t serienr[4];


//Codeausschnitt
zahler2=0;
do
{
 USART_Receive();
 USART_Transmit(input);
 serienr[zaehler2]=input[0];
 zaehler2++;
}while(serienr[zaehler2-1]!=13);

//Meine Unterprogramme
//Ausgabe RS232
//----------------------------------------------------------------
void USART_Transmit( uint8_t output[100] )
{
  for(int a=0;a<strlen(output);a++)
    {
      while ( !( UCSR1A & (1<<UDRE1)) );
      UDR1 = output[a];
    }
}

//Eingabe RS232
//----------------------------------------------------------------
void USART_Receive(void)
{
  while ( !(UCSR1A & (1<<RXC1)) );
  input[0]=UDR1;
}

von Huch (Gast)


Lesenswert?

Karl heinz! Kommst mal?

von g457 (Gast)


Lesenswert?

Die Funtion
1
void Seriennummernpufferwiederlöschendamiterbeimnächstenmalwiederleerist();
wäre noch interessant, vorzugsweise nicht nur als Ausschnitt. Falls es 
die noch gar nicht gibt könnte memset() helfen, vielleicht auch ein 
serienr[x] = 0. Oder eine Glaskugel die den Rest des Codes herzaubert 
:-)

HTH

von Detlev T. (detlevt)


Lesenswert?

Was heißt hier Code"ausschnitt"?

Mir fehlt hier die übliche Endlosschleife. wenn die do-while-Schleife 
beendet wird, landet das Programm im Nirvana.

von Floh (Gast)


Lesenswert?

bitte lauffähigen Code als ganzes im Anhang posten, dann kann man dein 
Programm auch ordentlich untersuchen.
:-)

von Patric K. (widder84)


Lesenswert?

Ist eben ein grosses Programm!!!


/*Libery**********************************************************
----------------------------------------------------------------*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

/*Defines*********************************************************
----------------------------------------------------------------*/

#define SCHALTER1  ((~(PINA))&0xFF)  //Taster einlesen aktiv =1
#define SCHALTER2  (~(PINC))      //Taster einlesen aktiv =0
#define Temp_sens  (SCHALTER2 & 0x20)
#define Mot_an    (~(SCHALTER2) & 0x80)

/*Globale Variablen***********************************************
----------------------------------------------------------------*/

volatile static uint8_t _DelayTime=0;
uint8_t input[0];
uint8_t serienr[4];
uint8_t auswertung[20];
uint8_t clear[20]=("\033[2J\033[1;1H");
int auswahl=1;
int alle=0;


/*Funktionen******************************************************
----------------------------------------------------------------*/

//Delay
//----------------------------------------------------------------
void delay_ms(uint16_t ms)
{

  uint16_t cnt;
  while(ms>0)
  {
    cnt=82;
    while(cnt-->0)
    {
      _DelayTime++;
    }
    ms--;
  }
}

//Baudrate RS232
//----------------------------------------------------------------
void USART_Init( unsigned int ubrr)
{
  UBRR1H = (unsigned char)(ubrr>>8);
  UBRR1L = (unsigned char)ubrr;
  UCSR1B = (1<<RXEN1)|(1<<TXEN1);
  UCSR1C = 0x06;
}

//Analog initialisieren
//----------------------------------------------------------------
uint16_t ADC_Init(uint8_t pin)
{
  uint16_t ADC_temp1, ADC_temp2;

  ADMUX = (1<<REFS0);        //AVCC mit externen Kondensator an AREF
  ADMUX &= (0xE0);        //Bei Register ADMUX alle MUXBit löschen MUX4 
bis MUX0
  ADMUX |= (pin&0x1F);      //MUX4 bis MUX0 setzen (aus Variable pin)
  ADCSRB &= 0xDF;          //MUX5 löschen
  ADCSRB |= ((pin&0x20)<<MUX5);  //MUX5 setzen aus Variable pin

  ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));  //Prescaler auf 128 
setzen
  ADCSRA |= (1<<ADEN);              //ADC enable
  ADCSRA |= (1<<ADSC);      //Start Messung
  while (!(ADCSRA & ADIF));

  ADC_temp1 = ADCL;
  ADC_temp2 = ADCH;
  ADC_temp2 = (ADC_temp2<<8) + ADC_temp1;

  return ADC_temp2;
}

//Ausgabe RS232
//----------------------------------------------------------------
void USART_Transmit( uint8_t output[100] )
{
  for(int a=0;a<strlen(output);a++)
    {
      while ( !( UCSR1A & (1<<UDRE1)) );
      UDR1 = output[a];
    }
}

//Eingabe RS232
//----------------------------------------------------------------
void USART_Receive(void)
{
  while ( !(UCSR1A & (1<<RXC1)) );
  input[0]=UDR1;
}

//Summer
//----------------------------------------------------------------

void SUMMER_Beep( unsigned int sum)
{
  for(int a=0;a<700;a++)
  {
    PORTD=0x01;
    delay_ms(sum);
    PORTD=0x00;
    delay_ms(sum);
  }
}

//YES or No
//----------------------------------------------------------------
void YES_No( unsigned int test)
{
  if (alle==1)
  {
    do
    {
      USART_Transmit("\r\n Test Ok? Mit Taste 'y' bestätigen oder mit 
'n' verneinen.");
      USART_Receive();
    }while (input[0] != 'y' && input[0] !='n' && input[0]!=27);


    if (input[0]=='y')
    {
      auswertung[test]='y';
    }
    else
    {
      auswertung[test]='n';
    }
  }
}

//Start
//----------------------------------------------------------------

void START_Test(void)
{
  alle=0;
  PORTC=0;
  PORTL=0;
  PORTB=0;
  SUMMER_Beep (7);
  USART_Transmit(clear);
  USART_Transmit(" -----------------------\r\n");
  USART_Transmit(" 1.Alle Tests in Folge\r\n");
  USART_Transmit(" 2.Ist ein AM2AMP angeschlossen\r\n");
  USART_Transmit(" 3.Strommessung Phase U und V\r\n");
  USART_Transmit(" 4.Temperaturfühler\r\n");
  USART_Transmit(" 5.Positive Halbwelle\r\n");
  USART_Transmit(" 6.Negative Halbwelle\r\n");
  USART_Transmit(" 7.Fehlermeldung1\r\n");
  USART_Transmit(" 8.Fehlermeldung2\r\n");
  USART_Receive();
  for(int b=49;b<=56;b++)
  {
    if (input[0]==b)
    {
      auswahl=b-47;
    }
    else
    {
      if (input[0]==27)
      {
        auswahl=11;
      }
    }
  }
}


/*Hauptfunktion***************************************************
----------------------------------------------------------------*/

int main(void)
{

//Voreinstellungen
//----------------------------------------------------------------

  DDRL=0xFF;
  DDRB=0xFF;
  DDRC=0x55;
  DDRJ=0xFF;
  DDRA=0x00;
  PORTA=0xFF;
  DDRD=0x03;
  PORTB=0x00;
  PORTL=0x00;
  ICR1 = 1000;
  ICR5 = 1000;      //Input-Capture einstellen

  USART_Init (51);


  SUMMER_Beep (3);


  int mask=0;
  int pwm=0;
  int zaehler1=0;
  int zaehler2=0;
  uint16_t temp_aus=0;
  uint16_t temp_ein=0;
  uint16_t temp=0;
  uint32_t temp0=0;

   char Wert[100];
  char Temp[10];
  uint8_t Var_Test = 0xAA;

//Programm
//----------------------------------------------------------------

  while(1)
  {
    switch(auswahl)
    {
      case 1:  START_Test();
          break;

      case 2:  USART_Transmit(clear);
          USART_Transmit("\r\n Alle Tests in Folge:\r\n");
          USART_Transmit("\r\n Bitte geben Sie die Serienummer des AM2 
ein und bestätige Sie mit Enter\r\n ");
          zaehler2=0;
          do
          {
            USART_Receive();
            USART_Transmit(input);
            serienr[zaehler2]=input[0];
            zaehler2++;
          }while(serienr[zaehler2-1]!=13);
          USART_Transmit("\r\n\r\n Serienummer: ");
          USART_Transmit(serienr);
          USART_Transmit("\r\n Weiter mit einer beliebiger Taste\r\n");
          USART_Receive();
          alle=1;
          if (!(input[0]==27))
          {
            auswahl++;
          }
          else
          {
            auswahl=1;
          }
          break;

      case 3:  USART_Transmit(clear);
          USART_Transmit("\r\n 2.Ist ein AM2AMP angeschlossen\r\n");
          PORTC=0x00;
          delay_ms(20);
          if (!Mot_an)
          {
            PORTC=0x40;
            delay_ms(20);
            if (Mot_an)
            {
              USART_Transmit("\r\n Ein AM2AMP ist angeschlossen\r\n");
              auswertung[0]='y';
            }
            else
            {
              USART_Transmit("\r\n Keine Verbindung zu AM2AMP\r\n");
              auswertung[0]='n';
            }
          }
          else
          {
            USART_Transmit("\r\n Keine Verbindung zu AM2AMP\r\n");
            auswertung[0]='n';
          }
          USART_Transmit("\r\n Weiter mit einer beliebigen Taste");
          USART_Receive();
          if (alle==1 & !(input[0]==27))
          {
            auswahl++;
          }
          else
          {
            auswahl=1;
          }
          break;

      case 4:  USART_Transmit(clear);
          USART_Transmit("\r\n 3.Strommessung Phase U und V\r\n");
          USART_Transmit(" Strom bei U\r\n");
          USART_Transmit("\r\n Wert mit einer beliebiger Taste 
aktualisieren. Mit ESC beenden.\n\r");
          USART_Transmit(" Wert muss mit Ampèremeter der Speisung um +/- 
10% übereinstimmen.\n\r");
          USART_Transmit(" Mit Schalter 1 zusätzliche Last zuschalten. 
Wert muss weiterhin übereinstimmen!\n\r");
          PORTB=0x20;
          delay_ms(20);
          do
          {
            sprintf(Wert, " Wert %d mA    \r", (ADC_Init(0x00)*10));
            USART_Transmit(Wert);
            USART_Receive();
          }while(input[0] != 27);
          YES_No(1);
          if(input[0] != 27 | alle!=1)
          {
            PORTB=0x00;
            USART_Transmit(clear);
            USART_Transmit("\r\n 3.Strommessung Phase U und V\r\n");
            USART_Transmit(" Strom bei V\r\n");
            USART_Transmit("\r\n Wert mit einer beliebiger Taste 
aktualisieren. Mit ESC beenden.\n\r");
            USART_Transmit(" Wert muss mit Ampèremeter der Speisung um 
+/- 10% übereinstimmen.\n\r");
            USART_Transmit(" Mit Schalter 2 zusätzliche Last zuschalten. 
Wert muss weiterhin übereinstimmen!\n\r");
            PORTB=0x40;
            delay_ms(20);
            do
            {
              sprintf(Wert, " Wert %d mA    \r", (ADC_Init(0x01)*10));
              USART_Transmit(Wert);
              USART_Receive();
            }while(input[0] != 27);
            YES_No(2);
            PORTB=0x00;
            if(input[0] != 27 | alle!=1)
            {
              USART_Transmit("\r\n Weiter mit einer beliebigen Taste");
              USART_Receive();
            }
          }
          if (alle==1 & !(input[0]==27))
          {
            auswahl++;
          }
          else
          {
            auswahl=1;
          }
          break;

      case 5:  temp_ein = 0;
          temp_aus = 0;
          temp = 0;
          PORTC = 0x00;
          USART_Transmit(clear);
          USART_Transmit("\r\n 4.Temperaturfühler\r\n");
          USART_Transmit("\r\n Wert mit einer beliebiger Taste 
aktualisieren. Mit ESC beenden.\n\r");
          USART_Transmit("\r\n Mit einem Heissluftföhn den 
Temperaturfühler erhitzen.\r\n");
          USART_Transmit(" Temparaturdifferenz max. +/- 10%.\r\n\r\n");
          delay_ms(20);
          do
          {
            zaehler1=0;
            while(Temp_sens && zaehler1!=1000)
            {
              zaehler1++;
            }
            zaehler1==0;
            while(!(Temp_sens) && zaehler1!=1000)
            {
              zaehler1++;
            }
            while(Temp_sens)
            {
              temp_ein++;
            }
            if(zaehler1<1000)
            {
              do
              {
                  temp_aus++;
              }while(!(Temp_sens));
              temp0 =((uint32_t)temp_ein * (uint32_t)10000);
              temp0 /=((uint32_t)temp_ein + (uint32_t)temp_aus);
              temp0 -= (uint32_t)3200;
              temp = (uint16_t)temp0/(uint16_t)47;
              sprintf(Temp, "\r\nTempaus: %d Tempein: %d Temperatur: 
%d", temp_aus, temp_ein, temp);
              //USART_Transmit(Temp);
              sprintf(Temp, " Temperatur: %d°C 
\r",temp);
              USART_Transmit(Temp);
              zaehler1=0;
              USART_Receive();
            }
            else
            {
              USART_Transmit(" Kein oder defekter Temperaturfühler\r");
              USART_Receive();
            }
          }while(input[0] != 27);
          YES_No(3);
          if (alle==1 & !(input[0]==27))
          {
            auswahl++;
          }
          else
          {
            auswahl=1;
          }
          break;

      case 6:  USART_Transmit(clear);
          USART_Transmit("\r\n Test5\r\n");
          if((TCCR1A == 0x00)&&(TCCR1B == 0x00))
          {
            TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1)|(1<<WGM11);
            TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);
          }


          do
          {
            USART_Transmit("\r\n LED U+ muss immer wie schwächer und 
dann immer wie stärker leuchten");
            delay_ms(20);
            for (pwm=0;pwm<1000;pwm++)
            {
              OCR1A = pwm;
              delay_ms(50);
            }
            for (pwm=1000;pwm>0;pwm--)
            {
              OCR1A = pwm;
              delay_ms(50);
            }
            USART_Transmit("\r\n Mit einer beliebiger Taste Wiederholen 
oder mit ESC beenden\r\n");
            USART_Receive();
            PORTB = 0x00;
          }while(input[0] != 27);

          do
          {
            USART_Transmit("\r\n LED V+ muss immer wie schwächer und 
dann immer wie stärker leuchten");
            delay_ms(20);
            for (pwm=0;pwm<1000;pwm++)
            {
              OCR1B = pwm;
              delay_ms(50);
            }
            for (pwm=1000;pwm>0;pwm--)
            {
              OCR1B = pwm;
              delay_ms(50);
            }
            USART_Transmit("\r\n Mit einer beliebiger Taste Wiederholen 
oder mit ESC beenden\r\n");
            USART_Receive();
            PORTB = 0x00;
          }while(input[0] != 27);

          do
          {
            USART_Transmit("\r\n LED W+ muss immer wie schwächer und 
dann immer wie stärker leuchten");
            delay_ms(20);
            for (pwm=0;pwm<1000;pwm++)
            {
              OCR1C = pwm;
              delay_ms(50);
            }
            for (pwm=1000;pwm>0;pwm--)
            {
              OCR1C = pwm;
              delay_ms(50);
            }
            PORTB = 0x00;
            USART_Transmit("\r\n Mit einer beliebiger Taste Wiederholen 
oder mit ESC beenden\r\n");
            USART_Receive();
          }while(input[0] != 27);
          USART_Transmit("\r\nTest 5 Ende\r\n");
          delay_ms(20);
          TCCR1A &= ~((1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1)|(1<<WGM11));
          TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS10));
          TCNT1 = 0;                            //Timer Counter1 auf 
Null setzen.
          PORTB =0x00;

          if (alle==1 & !(input[0]==27))
          {
            auswahl++;
          }
          else
          {
            auswahl=1;
          }
          break;

      case 7:  USART_Transmit(clear);
          USART_Transmit("\r\n Test6\r\n");
          if((TCCR5A == 0x00)&&(TCCR5B == 0x00))
          {
            TCCR5A = (1<<COM5A1)|(1<<COM5B1)|(1<<COM5C1)|(1<<WGM51);
            TCCR5B = (1<<WGM53)|(1<<WGM52)|(1<<CS50);
          }


          do
          {
            USART_Transmit("\r\n LED U- muss immer wie schwächer und 
dann immer wie stärker leuchten");
            delay_ms(20);
            for (pwm=0;pwm<1000;pwm++)
            {
              OCR5A = pwm;
              delay_ms(50);
            }
            for (pwm=1000;pwm>0;pwm--)
            {
              OCR5A = pwm;
              delay_ms(50);
            }
            USART_Transmit("\r\n Mit einer beliebiger Taste Wiederholen 
oder mit ESC beenden\r\n");
            USART_Receive();
            PORTL = 0x00;
          }while(input[0] != 27);

          do
          {
            USART_Transmit("\r\n LED V- muss immer wie schwächer und 
dann immer wie stärker leuchten");
            delay_ms(20);
            for (pwm=0;pwm<1000;pwm++)
            {
              OCR5B = pwm;
              delay_ms(50);
            }
            for (pwm=1000;pwm>0;pwm--)
            {
              OCR5B = pwm;
              delay_ms(50);
            }
            USART_Transmit("\r\n Mit einer beliebiger Taste Wiederholen 
oder mit ESC beenden\r\n");
            USART_Receive();
            PORTL = 0x00;
          }while(input[0] != 27);

          do
          {
            USART_Transmit("\r\n LED W- muss immer wie schwächer und 
dann immer wie stärker leuchten");
            delay_ms(20);
            for (pwm=0;pwm<1000;pwm++)
            {
              OCR5C = pwm;
              delay_ms(50);
            }
            for (pwm=1000;pwm>0;pwm--)
            {
              OCR5C = pwm;
              delay_ms(50);
            }
            PORTL = 0x00;
            USART_Transmit("\r\n Mit einer beliebiger Taste Wiederholen 
oder mit ESC beenden\r\n");
            USART_Receive();
          }while(input[0] != 27);
          USART_Transmit("\r\nTest 6 Ende\r\n");
          delay_ms(20);
          TCCR5A &= ~((1<<COM5A1)|(1<<COM5B1)|(1<<COM5C1)|(1<<WGM51));
          TCCR5B &= ~((1<<WGM53)|(1<<WGM52)|(1<<CS50));
          TCNT5 = 0;                            //Timer Counter1 auf 
Null setzen.
          PORTL =0x00;

          if (alle==1 & !(input[0]==27))
          {
            auswahl++;
          }
          else
          {
            auswahl=1;
          }
          break;

      case 8:  USART_Transmit(clear);
          USART_Transmit("\r\n Test7\r\n");
          USART_Receive();
          if (alle==1 & !(input[0]==27))
          {
            auswahl++;
          }
          else
          {
            auswahl=1;
          }
          break;


      case 9:  USART_Transmit(clear);
          USART_Transmit("\r\n Test8\r\n");
          USART_Receive();
          auswahl=1;
          alle=0;
          break;


      case 11:USART_Transmit(clear);
          USART_Transmit("\r\n Test wurde beendet\r\n");
          SUMMER_Beep (15);
          while(1);
          break;
    }
  }

  return 0;
}

von Huch (Gast)


Lesenswert?

Das ist ärgerlich. Wirklich. Kannst Du bitte mal lesen was an Hinweisen 
hier steht? Das wäre wirklich sehr zuvorkommend.

> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Als Angemeldeter kannst Du Deinen letzten Beitrag noch schnell 
editieren.

von Patric K. (widder84)


Lesenswert?

Der Beitrag kann nicht bearbeitet werden. Eigene Beiträge können bis 
maximal 15 Minuten nach dem Absenden bearbeitet werden, und nur wenn 
noch keine Antworten eingetroffen sind.

sorry!!!

von Huch (Gast)


Lesenswert?

Auch Sorry.

Ich denke das das Problem erstmal durch den Stil ziemlich verdeckt ist.

Diese starke und undurchsichtige Verflechtung von Eingabeauswertung mit 
Auswahl und Zuständen macht es schwierig zu sehen was mit den Eingaben 
und Ausgaben geschieht.


Ich würde das nochmal entwerfen:

Eine Hauptschleife die einfach nur Eingabe liest und wieder rausgibt.

Dann eine Auswertung (meinetwegen in einem Switch) die dann eine 
Zustandsmaschine ansteuert. Darin wiederum Sub-Zustandsmaschinen, die 
die Schleifen und sowas nachbilden.

So findet sich da keiner zurecht, würde ich meinen.

von Peter D. (peda)


Lesenswert?

Nachdem mein Zeigefinger qualmt vom Scrollen.

Schreib ne Funktion, die von der UART einliest, bis "Enter" erkannt wird 
und dieses einfach durch 0 ersetzt.
Dann übergib diesen String der Auswertefunktion.
Und schon ist der alte String wie von Geisterhand verschwunden.


Peter

von Andreas B, (Gast)


Lesenswert?

Patric K. schrieb:
> Hier mein Codeauschnitt:
>
> //Variablen definieren
> uint8_t input[1];
> uint8_t serienr[4];

Also erst mal ist hier input ein Array mit der Länge 1. Da passt nur ein 
Zeichen rein. Wenn das dazu dann noch ein C String mit Nulltermination 
darstellen soll, passt da nur ein leerer String rein (sprich, nur das 
Nullbyte).

>
> //Codeausschnitt
> zahler2=0;
> do
> {
>  USART_Receive();
>  USART_Transmit(input);
>  serienr[zaehler2]=input[0];
>  zaehler2++;
> }while(serienr[zaehler2-1]!=13);
> >
> //Meine Unterprogramme
> //Ausgabe RS232
> //----------------------------------------------------------------
> void USART_Transmit( uint8_t output[100] )

Besser mal "uint8_t *output", da die Funktion ja nicht auf eine feste 
Arraylänge ausgerichtet sein muss.

> {
>   for(int a=0;a<strlen(output);a++)
>     {
>       while ( !( UCSR1A & (1<<UDRE1)) );
>       UDR1 = output[a];
>     }
> }

Und mit der Definition von input oben kann strlen() ja nur 0 ergeben, 
sonst hast du da schon einen Buffer Overflow gehabt.


Im vollständigen Programm, aus dem das ja angeblich ein Auszug war, wird 
es noch schlimmer: Da hat input eine Länge von 0, also kann gar nichts 
darin gespeichert werden, noch nicht einmal ein leerer String.

Streng nach C sind Arrays mit der Länge 0 auch gar nicht erlaubt. Das 
ist eine gcc-Erweiterung und macht nur als das letzte Element eines 
structs Sinn (ebenso wie die Arrays ganz ohne Länge aus C99).

Tipp: Mach die USART_Transmit Funktion so, dass sie ein Zeichen ausgibt 
(Argument uint8_t), und eine weitere Funktion 
USART_Transmit_String(uint8_t*) oder so, die dann die Schleife 
implementiert und für jedes Zeichen USART_Transmit aufruft. Dann 
verhaspelt man sich mit der Logik dahinter auch nicht so leicht.

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.