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; }
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
Was heißt hier Code"ausschnitt"? Mir fehlt hier die übliche Endlosschleife. wenn die do-while-Schleife beendet wird, landet das Programm im Nirvana.
bitte lauffähigen Code als ganzes im Anhang posten, dann kann man dein Programm auch ordentlich untersuchen. :-)
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; }
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.
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!!!
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.