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 #1491400
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 #1491441
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 #1491463
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 #1491998
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 #1492044
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
}
#1492116
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 #1492163
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 #1492403
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 #1497748
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 #1497754
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 #1497766
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 #1498494
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
#1498502
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 #1498704
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;
}
#1498710
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren