Forum: Mikrocontroller und Digitale Elektronik Programmneustart nach uart_getc


von gben (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

du hast keien ISR für die aktivieren Interupts geschrieben. Damit wird 
ein reset gemacht.

von Peter K. (peterka2000)


Lesenswert?

Wie kommst du darauf dass das Programm immer neu startet? Ins Auge 
sticht mir, das nach der While-Schleife ein return fehlt, einige 
Compiler scheinen damit glaube Probleme zu haben.

von Peter II (Gast)


Lesenswert?

Peter K. schrieb:
> Ins Auge
> sticht mir, das nach der While-Schleife ein return fehlt, einige
> Compiler scheinen damit glaube Probleme zu haben.

nein habe sie bestimmt nicht.

Es fehlen einfach die ISRs.

von Justus S. (jussa)


Lesenswert?

Peter II schrieb:
> Es fehlen einfach die ISRs.

ich sehe aber nirgends ein sei()...

von Peter II (Gast)


Lesenswert?

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)

von Justus S. (jussa)


Lesenswert?

Peter K. schrieb:
> Wie kommst du darauf dass das Programm immer neu startet?

wahrscheinlich weil er immer "programmstart" geschickt bekommt

von spess53 (Gast)


Lesenswert?

Hi

>> Es fehlen einfach die ISRs.

>ich sehe aber nirgends ein sei()...

Das dürfte auch nicht das komplette Programm sein.

MfG Spess

von gben (Gast)


Lesenswert?

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ß

von Peter II (Gast)


Lesenswert?

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.

von Justus S. (jussa)


Lesenswert?

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...

von Justus S. (jussa)


Lesenswert?

Peter II schrieb:
> dort steht das du
> interupts einschaltet, das machst du überhaupt nicht.

na ja, den Receive/Transmit-Interrupt aktiviert er ja schon aber eben 
die Interrupts allgemein nicht...das Kommentar passt also eigentlich 
schon...

von gben (Gast)


Lesenswert?

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ß

von amateur (Gast)


Lesenswert?

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"

von Justus S. (jussa)


Lesenswert?

Justus Skorps schrieb:
> na ja, den Receive/Transmit-Interrupt aktiviert er ja schon aber eben
> die Interrupts allgemein nicht...das Kommentar passt also eigentlich
> schon...

grmpf, war natürlich Quatsch

von Justus S. (jussa)


Lesenswert?

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...

von Karl H. (kbuchegg)


Lesenswert?

Hast du an den Fusebits gespielt und dabei den Watchdog eingeschaltet?

von gben (Gast)


Lesenswert?

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.

von Justus S. (jussa)


Lesenswert?


von gben (Gast)


Lesenswert?

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

von avrele (Gast)


Lesenswert?

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.

von Justus S. (jussa)


Lesenswert?

avrele schrieb:
> So ein Quatsch .
> Er benutzt doch gar keine Interrupts fürs Empfangen ist doch
> ausgeblendet.
> Er pollt den uart in der While schleife.

das ist doch schon längst geklärt...

von Karl H. (kbuchegg)


Lesenswert?

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

von gben (Gast)


Lesenswert?

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..

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.