Programmneustart nach uart_getc

Gast #3261883
Hi ich habe folgendes Problem und bin mit meinem Latein am Ende:

Wenn ich ein paar Zeichen über die serielle Schnittstelle einlese und 
mir wieder ausgeben lassen will, dann startet das Programm einfach von 
vorn.

Hier ist mein kleines Echo Programm, die Zeichen werden über ein 
Terminal am PC eingelesen und angezeigt.

Verwendeter Controller: ATmega48A bei 8MHz
1
#define F_CPU 8000000
2
#define BAUD 9600
3

4
#include <avr/io.h>
5
#include <avr/sleep.h>
6
#include <util/delay.h>
7
#include "uart.h"
8

9
int main(void)
10
{  
11
  uart_init();
12
  uart_puts("programmstart\n");
13
  
14
    while(1)
15
    {
16
    uart_putc(uart_getc());
17
    }
18
}

uart.h:
1
void uart_init(void);
2
void uart_putc(char);
3
void uart_puts(char *);
4
unsigned char uart_getc(void);

uart.c:
1
#include "uart.h"
2
#include <avr/io.h>
3

4
void uart_init(){
5
  //baud configured to 9600
6
  int ubrr = 51;
7
  
8
  UBRR0H = (unsigned char)(ubrr >> 8);
9
  UBRR0L = (unsigned char)ubrr;
10
  
11
  //receiving, transmitting and rxinterrupt enabled
12
  UCSR0B = (1 << RXEN0) | (1 << TXEN0); //| (1 << RXCIE0);
13
  
14
  //uart config for 8N1
15
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
16
  
17
  //flush receive buffer
18
  UDR0;  
19
}
20

21
void uart_putc(char c){
22
  while(!(UCSR0A & (1 << UDRE0)));
23
  
24
  UDR0 = c;
25
}
26

27
void uart_puts(char *s){
28
  while(*s){
29
    uart_putc(*s);
30
    s++;
31
  }
32
}  
33

34
unsigned char uart_getc(){
35
  while (!(UCSR0A & (1<<RXC0)));
36
  return UDR0;
37
}

Wie kommt es das mein Programm immer neustatet?

Gruß gben
Gast
Justus Skorps schrieb:
> Peter II schrieb:
>> Es fehlen einfach die ISRs.
>
> ich sehe aber nirgends ein sei()...

stimmt auch wieder, dann wirklich erstmal die frage woran er merkt das 
er neu startet.

(am nicht vorhanden return liegt es aber auf keinen Fall)
Gast
Doch das ist das ganze Programm

Ich bekommste nach dem eingeben von Zeichen in meinem Terminal ganz 
normal das Zeichen zurück so wie es sein soll, dann allerdings kommt im 
anschluss sofort: "programmstart\n" also der String der nach der 
Initialisierung ausgegeben wird. Meine Vermutung begründe ich damit, 
dass ich ja in der Endlosschleife sein muss, wenn ich das Zeichen zurück 
bekomme.

Wie meintet Ihr das mit den Interrupt Routinen? Wieso muss man diese 
zwingend setzen?

Ich habe anfangs das ganze mit ISR versucht bis mir der Fehler mit dem 
Neustart auffiel und dann habe ich das ganze erstmal wieder abgebaut.

Mein Ziel war es:
über das Interrupt die Info zu bekommen das jetzt Zeichen auf der 
Seriellen Schnittstelle vorhanden sind, dann unterbreche ich das 
Interrupt mit cli und lade die besitmmte länge an Zeichen mit einem 
Timeout, damit sich das Programm nicth aufhängt.

Aber soweit bin ich garnicht gekommen, ich habe wiegesagt recht früh in 
meiner Phase das Problem mit dem sagen wir mal vermeintlichen Neustart.

Danke für eure Hilfe :)

Gruß
Gast
gben schrieb:
> Wie meintet Ihr das mit den Interrupt Routinen? Wieso muss man diese
> zwingend setzen?


wenn du die interupts aktiviert dann ja.

//receiving, transmitting and rxinterrupt enabled
UCSR0B = (1 << RXEN0) | (1 << TXEN0); //| (1 << RXCIE0);

Ich habe mich von den Kommentor blenden lassen, dort steht das du 
interupts einschaltet, das machst du überhaupt nicht.

Schönes beispiel wie kommentare mehr Probleme verursachen als sie lösen.
gben schrieb:
> Wie meintet Ihr das mit den Interrupt Routinen? Wieso muss man diese
> zwingend setzen?

das wäre so gewesen, wenn du die Interrupts mit sei aktiviert 
hättest...ein Interrupt ohne zugehörige Routine führt nämlich zu einem 
Reset...


und
gben schrieb:
> dann unterbreche ich das
> Interrupt mit cli
vergisst du lieber sehr schnell wieder...
Gast
Justus Skorps schrieb:
>> dann unterbreche ich das
>> Interrupt mit cli
> vergisst du lieber sehr schnell wieder...

Wieso soll ich die Idee verwerfen? oder kann ich einfach die 
nachfolgenden Zeichen problemlos abfangen wenn ich in der ISR bin ohne 
das dann automatisch das ganze von vorn beginnt?


also ich habe jetzt einfach mal ein return am Ende hinzugefügt, seit dem 
geht das senden der Zeichen problemlos, allerdings zeigt er mir keine 
Nachricht mit Programmstart mehr an.

Gruß
Gast
Werden die Unterbrechungen aktiviert, so werden sie auch beim Empfang 
eines Zeichens aufgerufen.

Per default steht aber im Interruptvektor Reset.

Bildhaft: Pro empfangenem Zeichen ein: "programmstart\n"
gben schrieb:
> Wieso soll ich die Idee verwerfen? oder kann ich einfach die
> nachfolgenden Zeichen problemlos abfangen wenn ich in der ISR bin ohne
> das dann automatisch das ganze von vorn beginnt?

in einer Interrupt-Routine werden die Interrupts eh gesperrt, da pfuscht 
man nicht rein...
Gast
Habe mal die Fuses auslesen lassen:

SELFPRGEN = [ ]
RSTDISBL = [ ]
DWEN = [ ]
SPIEN = [X]
WDTON = [ ]
EESAVE = [ ]
BODLEVEL = DISABLED
CKDIV8 = [ ]
CKOUT = [ ]
SUT_CKSEL = INTRCOSC_8MHZ_6CK_14CK_65MS_DEFAULT

EXTENDED = 0xFF (valid)
HIGH = 0xDF (valid)
LOW = 0xE2 (valid)


Watchdog ist nicht aktiv aber jetzt schein alles zu funktionieren. Seit 
dem ich das return drin habe, habe ich auch keine Probleme

Danke für eure Hilfe

Justus Skorps schrieb:
> in einer Interrupt-Routine werden die Interrupts eh gesperrt, da pfuscht
> man nicht rein...

Wusste ich bisher nicht vielen Dank auch dafür.
Gast
Mir ist noch ein Problem aufgefallen.. und zwar funktioniert mein 
Programm nur solange der ISP Stecker auf der Platine ist... ist das 
normal?? Habe ich da irgendwas falsch eingestellt?

Ich benutze das MKII und das AVR Studio 6
Gast
Peter II schrieb:
> du hast keien ISR für die aktivieren Interupts geschrieben. Damit
> wird
> ein reset gemacht.

So ein Quatsch .
Er benutzt doch gar keine Interrupts fürs Empfangen ist doch 
ausgeblendet.
Er pollt den uart in der While schleife.
gben schrieb:
> Mir ist noch ein Problem aufgefallen.. und zwar funktioniert mein
> Programm nur solange der ISP Stecker auf der Platine ist... ist das
> normal?? Habe ich da irgendwas falsch eingestellt?

Wie siehst deine µC-Platine aus?
Schaltplan? Aufbau? Stromversorgung?

Ich wette, wir werden wieder mal sehen
* keine Blockkondensatoren
* fehlender Widerstand am Reset
Gast
Das ist eine bereits fertige Platine die mit einer etwas veralteten 
Software bereits funktioniert ohne weitere Probleme. Daher wundert es 
mich ich ohne das MKII keine Ausgabe auf meiner Seriellen Schnittstelle 
bekomme..

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.