Uart-Programm testen

Gast #1491134
Lesenswert?
• ▲
▼
Hallo,

ich arbeite mich gerade in die UART Programmierung mit C ein. 
Anscheinend kann man das mit AVRStudio nicht wirklich simulieren.

Habe gelesen dass man das mit dem Terminalprogramm HTerm testen kann. 
Braucht man dazu eine Hardware oder kann man das auch nur mit Firmware 
testen.

MfG
Gast
Lesenswert?
• ▲
▼
Habe es versucht zu testen. Irgendwie empfange ich einen Blödsinn. Es 
schreibt nur Quadrate hin.

Eingestellt in hterm habe ich Baud=9600, Data=8 und Stop=2 und 
Parity=None

Der uC ist ein at90
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
int main (void){
5

6

7
UBRR1= (6>>8); //9600, 1MHZ
8
UBRR1= 6;
9
UCSR1B= (1<<RXEN1) | (1<<TXEN1);
10
UCSR1C= (1<<USBS1) | (3<<UCSZ10);
11

12
while(1)
13
{
14
while(!(UCSR1A & (1<<UDRE1)))
15
;
16
UDR1= 'x';
17
}
18

19
}

MfG
Gast
Lesenswert?
• ▲
▼
Hi

>Fuses kenne ich nicht, muss ich mir zuerst mal anschauen.

?????????????

>Habe es mit 1MHZ und 8MHZ probiert. Eins hätte ja funktionieren müssen aber
>beide funktionieren nicht.

Wie kannst du das gemacht haben, ohne die Einstellungen des Controllers 
zu kennen?

MfG Spess
Gast
Lesenswert?
• ▲
▼
Hi

>Habe in hterm jetzt paar mal Connect und Disconnect gedrückt. Manchmal
>kommen Quadrate und manchmal kommen 'x'.

>Finde ich komisch, was kann das sein.

Beim internen RC-Oszillator durchaus möglich.

MfG Spess
Gast
Lesenswert?
• ▲
▼
Hallo,

habe in den Code diese zwei Zeilen eingefügt. Es zeigt mir aber Fehler 
an. Vermutlich fehlen mir die Headerdateien.

Wie kann ich jetzt die richtigen Headerdateien finden.
1
CLKSEL0= 0x04;  // SUT-ext.Osz=00; Enable ext. Osz
2
CLKSEL1= 0x0C;  //EXCKSEL[3..0]=1100

MfG
Gast
Lesenswert?
• ▲
▼
Ich glaube ich habe den Fehler gefunden. Im Datenblatt steht CLKSEL aber 
es gehört CKSEL.

Habe es getestet es kommt aber trotzdem wieder ein Blödsinn raus.

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
int main (void){
5

6

7
CKSEL0= 0x04;  // SUT-ext.Osz=00; Enable ext. Osz
8
CKSEL1= 0x0C;  //EXCKSEL[3..0]=1100
9

10
UBRR1= (51>>8); //9600, 8MHZ
11
UBRR1= 51;
12
UCSR1B= (1<<RXEN1) | (1<<TXEN1);
13
UCSR1C= (1<<USBS1) | (3<<UCSZ10);
14

15
while(1)
16
{
17
while(!(UCSR1A & (1<<UDRE1)))
18
;
19
UDR1= 'x';
20
}
21

22
}
Lesenswert?
• ▲
▼
astalavista schrieb:
> Den C-Code schreibe ich in AVR-Studio aber Flashen tu ich mit einem
> eigenen Programm für die Hardware.

Welches eigene Programm?
Du gibt es doch sicher einen Menüpunkt "Fuses" oder so ähnlich.

(Hast du den Prozessor gekauft, oder war der bei deiner Hardware dabei 
und welche Hardware ist das.

Mann versteh doch: Du musst die Fuses auf eine bestimmte Stellung 
einstellen. Das ist aber oftmals etwas diffizil wenn man das das erste 
mal macht. Also wollen wir rauskriegen, ob es überhaupt notwendig ist 
oder ob die Fuses in deiner Hardware ev. schon umgestellt wurden. Wenn 
sie noch nicht umgestellt wurden, dann kommt es auf den Brennprogramm 
an, wie das geht. Aber dazu musst du Info rausrücken und dich nicht in 
leeren Flosekeln wie 'eigenes Brennprogramm' verlieren.

Und noch was: Wenn du das in deinem Programm gefunden hast, lies auf 
jeden Fall zuerst die aktuelle Einstellung vom µC aus!
Moderator (Firma: Titel) Persönliche Seite
Lesenswert?
• ▲
▼
> Manchmal kommen Quadrate und manchmal kommen 'x'.
Mach mal eine längere Pause (>1ms) zwischen zwei Zeichen. Es gibt 
durchaus Bitmuster, die passen korrekt in einen Frame und sind dabei 
immer um ein paar Bits versetzt.

Nehmen wir das x (=0x78) : 01111000
Davor dann ein Start- und danach ein Stopbit.
Das ergibt 0 01111000 1
Und das jetzt mal als nimmer endenden Datenstrom:
0011110001001111000100111100010011110001001111000100111100010011110001.. 
.
Wenn jetzt der Empfänger spätern mal dazukommt, dann sieht er evtl. 
sowas:
      0001001111000100111100010011110001001111000100111100010011110001...
Und daraus wird dann
0 00100111 1
00100111 = 0x27 = '
Gast
Lesenswert?
• ▲
▼
Danke das war das Problem. Setze ich keine Pause kommen manchmal die 
richtigen und manchmal die falschen Zeichen. Setze ich eine Pause von 20 
ms dann kommen meist die richtigen Zeichen, hin und wieder drängen sich 
trotzdem paar Sonderzeichen hinein.

Was kann da das Problem sein.
Gast
Lesenswert?
• ▲
▼
Hallo,

ich habe bisschen Probleme mit dem Empfangen von Zeichen. Wenn ich von 
hterm ein Zeichen schicke wird es in "zeichen" gespeichert. Es sollte 
auch gleich wieder EIN Zeichen an hterm wieder zurück schicken.

Das Problem ist jetzt, es wird nicht ein Zeichen geschickt sondern es 
werden andauernd Zeichen geschickt. Ich hätte aber gerne dass nur das 
EINE Zeichen welches geschickt wurde auch wider zurück geschickt wird.
1
ISR (USART1_TX_vect) 
2
{
3
   
4
  while(!(UCSR1A & (1<<UDRE1)))
5
  ;
6
  UDR1= zeichen;
7
        //UCSR1A= (1<<UDRE1);
8
}
9

10

11
ISR (USART1_RX_vect) 
12
{
13

14
  while ( !(UCSR1A & (1<<RXC1)) )
15
  ;
16
  zeichen = UDR1;
17

18

19
  while(!(UCSR1A & (1<<UDRE1)))
20
  ;
21
  UDR1= zeichen;
22
}

MfG
Gast
Lesenswert?
• ▲
▼
>Das Problem ist jetzt, es wird nicht ein Zeichen geschickt sondern es
>werden andauernd Zeichen geschickt. Ich hätte aber gerne dass nur das
>EINE Zeichen welches geschickt wurde auch wider zurück geschickt wird.

Dann schalte den TX Interrupt ab. Der kommt immer wenn ein
Zeichen gesendet wurde. Und da du dort immer wieder in UDR schreibst
ist das so ne Endlosgeschichte.
Gast
Lesenswert?
• ▲
▼
Hi

>ISR (USART1_RX_vect)
>{
>  while ( !(UCSR1A & (1<<RXC1)) )  <- Blödsinn

weil der Interrupt genau bei der Bedingung ausgelöst wird.

>ISR (USART1_TX_vect)
>{
> while(!(UCSR1A & (1<<UDRE1))) <- Blödsinn
> UDR1= zeichen;                <- Damit

schiebst nach jedem gesendeten Zeichen eins hinterher.

MfG Spess
Gast
Lesenswert?
• ▲
▼
Hallo,

Das ist mir noch unklar. Mit "zeichen=UDR1" schicke ich ein Zeichen vom 
PC zum uC.
Somit befindet sich ein Zeichen im Puffer und deshalb wird ISR-TX 
ausgelöst.

Dadurch wird ja das eine Zeichen wieder zurück geschickt zum PC. Der 
Puffer sollte ja wieder leer sein. Da ich aber kein Zeichen mehr vom PC 
zum uc schicke, schiebe ich kein Zeichen nach jedem gesendeten 
hinterher.
1
ISR (USART1_TX_vect) 
2
{
3
  UDR1= zeichen;
4
}
5

6

7
ISR (USART1_RX_vect) 
8
{
9
  zeichen = UDR1;
10

11
  while(!(UCSR1A & (1<<UDRE1)))
12
  ;
13
  UDR1= zeichen;
14
}

MfG
Lesenswert?
• ▲
▼
Dieser Interrupt

ISR (USART1_TX_vect)
{
  UDR1= zeichen;
}


wird ausgelöst, sobald die USART das Zeichen vollständig abgeschickt 
hat.
Als Folge davon schickst du wieder ein Zeichen weg, das natürlich auch 
irgendwann vollständig weggeschickt wurde, was dazu führt dass der 
Interrupt schon wieder ausgelöst wird (denn es wurde ja ein Zeichen 
abgeschickt) was wiederrum dazu führt, dass du das nächste Zeichen 
rausschickst, was wiederrum zum Interrupt führt woraufhin ... ad 
nauseam.
Gast
Lesenswert?
• ▲
▼
Achso, danke.

D.h. stoppen kann ich den ISR-TX wieder mit
1
  while ( !(UCSR1A & (1<<RXC1)) )
2
  ;
3

4
  zeichen = UDR1;

Bei diesem Interrupt schickt er mir zuerst ein a,b,b,b,b....
Sollte es nicht a,b,c,d,.... sein?

ISR (USART1_TX_vect)
{
  UDR1= zeichen+1;
}
Lesenswert?
• ▲
▼
Der ganze Ansatz mit 'Zeichen schicken sobald ein TX Interrupt auftritt' 
ist in deinem Fall Schrott.
Du veruschst das Problem an der falschen Stelle zu beheben.
1
ISR (USART1_TX_vect) 
2
{
3
  // nichts. Ist noch völlig uninteressant, wann ein Zeichen rausgegangen ist
4
}
5

6
ISR (USART1_RX_vect) 
7
{
8
// Ist unnötig
9
// Der Interrupt wurde aufgerufen WEIL ein Zeichen empfangen wurde
10
// an dieser Stelle braucht daher nicht getestet werden.
11
// Es ist Faktum, dass ein Zeichen da ist!
12
//
13
//  while ( !(UCSR1A & (1<<RXC1)) )
14
//  ;
15
  zeichen = UDR1;
16

17

18
  while(!(UCSR1A & (1<<UDRE1)))
19
    ;
20
  UDR1= zeichen;
21
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 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.