kürze dein Programm doch bitte mal auf die minimalste Version zurück, in der sich der Fehler gerade noch zeigen lässt - alles andere an Codezeilen löschen.
kürze dein Programm doch bitte mal auf die minimalste Version zurück, in der sich der Fehler gerade noch zeigen lässt - alles andere an Codezeilen löschen.
Hallo HaWe,
ich habe mich gleich ans Werk gemacht und den Code gekürzt das verhalten ist noch 1:1 das gleiche.
Schon mal vielen Dank, dass du dir den Quellcode an siehst und mir hilfst.
Wenn ich wüsste was hier bei der Lib an BAUD steht, könnte ich die ganze Lib auch noch ausbauenCode:#define MCU atmega8 #define F_CPU 2000000UL #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <inttypes.h> #include <stdlib.h> #include <stdio.h> #include "USART_RS232_H_file.h" /* include USART library */ #define BT_EN_REGISTER DDRC #define BT_EN_PORT PORTC #define BT_EN_PIN PC0 #define LED_REGISTER DDRC #define LED_PORT PORTC #define LED_RED_PIN PC5 #define LED_GREEN_PIN PC4 #define LED_BLUE_PIN PC3 //Data from App long pl_valid_time_sec = 0; uint8_t uart_getc(void){ while (!(UCSRA & (1<<RXC))){} // warten bis Zeichen verfuegbar return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben } void uart_gets( char* Buffer, uint32_t MaxLen){ uint8_t NextChar; uint32_t StringLen = 0; NextChar = uart_getc(); // Warte auf und empfange das nächste Zeichen while( NextChar != '\n' && StringLen < MaxLen - 1 ) { // Sammle solange Zeichen, bis: entweder das String Ende Zeichen kam oder das aufnehmende Array voll ist *Buffer++ = NextChar; StringLen++; NextChar = uart_getc(); } *Buffer = '\0'; // Noch ein '\0' anhängen um einen Standard C-String daraus zu machen } void get_BTData(char mode){ char uart_buffer[512]; for(int i=0; i<4; i++){ LED_PORT ^= (1 << LED_BLUE_PIN); _delay_ms(500); } USART_Init(9600); /* initialize USART with 9600 baud rate */ LED_PORT |= (1<<LED_BLUE_PIN); uart_gets(uart_buffer,512); char spl_buffer[512]; spl_buffer[0] = '1'; spl_buffer[1] = '2'; spl_buffer[1] = '\0'; pl_valid_time_sec = atol(spl_buffer); _delay_ms(5000); LED_PORT &= ~(1<<LED_BLUE_PIN); } int main(void){ // Direction Registers DDRB = 0x00; // B as input DDRC = 0x00; // D as Input DDRD = 0x00; // D as Input // Set Output Registers BT_EN_REGISTER |= (1 << BT_EN_PIN); // Bluetooth PWR Controll LED_REGISTER |= (1 << LED_RED_PIN); // LED as output LED_REGISTER |= (1 << LED_GREEN_PIN); // LED as output LED_REGISTER |= (1 << LED_BLUE_PIN); // LED as output // Ports to LOW (GND no Pullup) PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; for (int i=0; i < 4; i++){ LED_PORT ^= (1 << LED_GREEN_PIN); _delay_ms(500); } get_BTData('I'); // INIT MODE while(1){ LED_PORT ^= (1 << LED_RED_PIN); _delay_ms(500); } }
Der ATMEGA läuft bei 2Mhz
Code:void USART_Init(unsigned long BAUDRATE) /* USART initialize function */ { UCSRB |= (1 << RXEN) | (1 << TXEN); /* Enable USART transmitter and receiver */ UCSRC |= (1 << URSEL)| (1 << UCSZ0) | (1 << UCSZ1); /* Write USCRC for 8 bit data and 1 stop bit */ UBRRL = BAUD_PRESCALE; /* Load UBRRL with lower 8 bit of prescale value */ UBRRH = (BAUD_PRESCALE >> 8); /* Load UBRRH with upper 8 bit of prescale value */ }
UART und LED-Code auch mal rauslöschen. wenn atol eine runtime-Exception auslöst, müsste es davon unabhängig sein.
Stattdessen könntest du Zeichen aus UART auch durch const cstrings testweise ersetzen.
http://www.cplusplus.com/reference/cstdlib/atol/On success, the function returns the converted integral number as a long int value.
If no valid conversion could be performed, a zero value is returned.
If the converted value would be out of the range of representable values by a long int, it causes undefined behavior. See strtol for a more robust cross-platform alternative when this is a possibility.
Geändert von HaWe (06.04.2020 um 21:57 Uhr)
Ich habe jetzt
uint8_t uart_getc(void){
void uart_gets( char* Buffer, uint32_t MaxLen){
Auskommentiert und den Aufruf USART_Init(9600); uart_gets(uart_buffer,512);
jetzt bleibt die Blaue LED an. -> Also ok.
Die Led brauche ich damit ich mit bekomme was das Programm tut.
Wenn ich den Init wieder aktiviere geht es auch noch beim uart_gets(uart_buffer,512); habe ich wieder den Fehler.
das deutet für mich darauf hin, dass der UART-buffer aus uart_getc() oder uart_gets() einen ungültigen Wert liefern könnte, der eine Exception auslöst. Ich verstehe hier aber deinen Code zugegebenermaßen nicht.
Kannst du diesen UART-Wert auslesen, anzeigen (Display?) und checken, bevor du ihn an atol übergibst?
Geändert von HaWe (06.04.2020 um 22:06 Uhr)
Aber ich gebe ja atol inzwischen schon einen fixen String und nichts mehr aus den UART Buffer.
also passiert der Fehler gar nicht in atol? Sondern in uart_getc() oder uart_gets() ? Oder wie oder was?
Genau das versuche ich gerade heraus zu finden.
Leider ist das ganze UART Thema für mich auch Neuland.
- - - Aktualisiert - - -
Ich hab schön langsam eine Ahnung, ich glaub ich hab mehr RAM verbraucht als der ATMEL hat und
sobald ich dann irgendwo im RAM schreibe wo ich nicht sein sollte macht es boom
Wenn ich nämlich wie jetzt hier den buffer auf 512 setze geht es noch bei 1024 gibt es undefiniertes verhalten.
Und das Datenblatt bestätigt das wohl gerade
– 1KByte Internal SRAMdaran dachte ich wohl nicht.
Klingt das für euch Logisch?
Code:#define MCU atmega8 #define F_CPU 2000000UL //-U lfuse:w:0xe2:m -U hfuse:w:0xd9:m #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <inttypes.h> #include <stdlib.h> #include <stdio.h> #define BT_EN_REGISTER DDRC #define BT_EN_PORT PORTC #define BT_EN_PIN PC0 #define LED_REGISTER DDRC #define LED_PORT PORTC #define LED_RED_PIN PC5 #define LED_GREEN_PIN PC4 #define LED_BLUE_PIN PC3 // BAUDRATE #define BAUD_PRESCALE (((F_CPU / (9600 * 16UL))) - 1) /* Define prescale value */ //Data from App long pl_valid_time_sec = 0; void USART_SendString(char *str){ int i=0; while (str[i]!=0){ UDR = str[i]; /* Write data to be transmitting in UDR */ while (!(UCSRA & (1<<UDRE))); /* Wait until data transmit and buffer get empty */ i++; } } void get_BTData(){ // INIT USART UCSRB |= (1 << RXEN) | (1 << TXEN); /* Enable USART transmitter and receiver */ UCSRC |= (1 << URSEL)| (1 << UCSZ0) | (1 << UCSZ1); /* Write USCRC for 8 bit data and 1 stop bit */ UBRRL = BAUD_PRESCALE; /* Load UBRRL with lower 8 bit of prescale value */ UBRRH = (BAUD_PRESCALE >> 8); /* Load UBRRH with upper 8 bit of prescale value */ LED_PORT |= (1<<LED_BLUE_PIN); int i=0; uint8_t c = '\0'; uint8_t uart_buffer[1024]; while( i < 512){ while (!(UCSRA & (1<<RXC))){} c = UDR; if ( c == '\n' ){ break; } uart_buffer[i] = c; i++; } uart_buffer[i]='\0'; USART_SendString("TEST"); USART_SendString(uart_buffer); char spl_buffer[12]; spl_buffer[0] = '1'; spl_buffer[1] = '2'; spl_buffer[1] = '\0'; pl_valid_time_sec = atol(spl_buffer); _delay_ms(5000); LED_PORT &= ~(1<<LED_BLUE_PIN); } int main(void){ // Direction Registers DDRB = 0x00; // B as input DDRC = 0x00; // D as Input DDRD = 0x00; // D as Input // Set Output Registers BT_EN_REGISTER |= (1 << BT_EN_PIN); // Bluetooth PWR Controll LED_REGISTER |= (1 << LED_RED_PIN); // LED as output LED_REGISTER |= (1 << LED_GREEN_PIN); // LED as output LED_REGISTER |= (1 << LED_BLUE_PIN); // LED as output // Ports to LOW (GND no Pullup) PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; for (int i=0; i < 4; i++){ LED_PORT ^= (1 << LED_GREEN_PIN); _delay_ms(500); } get_BTData(); // INIT MODE while(1){ LED_PORT ^= (1 << LED_RED_PIN); _delay_ms(500); } }
Morgen Tux,
Dein Buffer (uint8_t uart_buffer[1024]befindet sich innerhalb "void get_BTData()".
Das Problem gab es hier schon in verschiedenen Fällen, dass so etwas dann Probleme bereitet (Stapelspeicher).
Eventuell bringts Dir was, "uint8_t uart_buffer[1024];" global anzulegen, also außerhalb jeder Funktion, das könnte das Problem beseitigen.
MfG
Lesezeichen