Forum: Mikrocontroller und Digitale Elektronik XPlained USART zu USB-Buchse


von David L. (david_l87)


Angehängte Dateien:

Lesenswert?

Hallo Jungs.

Ich beschäftige mich seit gestern zwangsweise mit dem UART meines 
Xplained-A1 Boards. Meine Idee war die Temperatur mit dem NTC auf dem 
Board zu messen. Da mir ein Display nicht zur Verfügung steht wollte ich 
die Temperatur auf dem PC anzeigen lassen.
Nun habe ich etwas gegoogelt und auch hier und da Infos oder auch Code 
zum initialisieren des UART gefunden. Leider funktionier es nicht und 
ich habe einige grundlegende Fragen.

- Kann ich überhaupt Daten über die USB-Schnittstelle des Boards 
auslesen? Wenn nicht dann klären sich die anderen Fragen. ^^


- Um es langsam anzugehen habe ich zu allererst einen Code genutzt den 
ich hier im Forum gefunden habe und wollte mit dessen Hilfe zunächst 
einfach ein 1Byte ausgeben lassen. 
Beitrag "UART-USB Gateway auf dem AVR Xplained A1"

In die main-Funktion habe ich dann lediglich noch

char test;
while(1)
{
    test = 0xFF;
    uart_put(test);
}

eingefügt.

Auch wenn ich das Programm ohne Probleme kompilieren kann, ist es nach 
dem flashen aufs Board nicht möglich Daten zu empfangen.
Habe ich es mir zu einfach gemacht, und muss noch mehr im Code ändern?


- Da der Code aus dem Forum nicht funktionierte wollte ich als nächstes 
ein fertiges Demoprojet aus ASF verwenden. Im ASF gibt es ein UART- 
Codebeispiel, in dem ziemlich am Anfang geschrieben steht:

 *   - Xplain evaluation kit
 *     USARTD0 on PORTD is used by default
 *     Change to USARTC0 to use the USB Virtual COM PORT of the Xplain
 *   - XMEGA A1 Xplained evaluation kit
 *     USARTC0 on PORTC is used. It is located on the J4 header

Das verwirrt mich etwas. Ich verstehe hier, dass UARTC0 das USB-Port auf 
dem Board nutzt. Zugleich ist UARTC0 am Pinheader J4 zu finden? Ist das 
richtig? Das würde ja bedeuten, dass die entsprechenden uC-Pins doppelt 
belegt sind, oder?

Unterm Strich funktionierte dieses "fertige" Beispiel auch nicht. Es 
soll "Hello AVR World" ausgeben. Ich habe es angehangen.

- Stimmt der Rest? Das Auslesen habe ich mit den Programmen TeraTerm und 
RS232 Data Logger probiert. Die Konfiguration (immer): 57kBaud, 8bit, no 
parity, stop bits 1, no flowctrl. Zum programmieren muss ich bei FLIP 
den COM9 wählen. Nach dem flashen muss das Board resetet werden, um in 
den Programmmodus zu kommen (zumindest war es bei anderen 
vorangegangenen Programmen so). Danach ist COM9 jedoch nicht mehr 
erreichbar. Auf den übrig gebliebenen COMs zeigt sich auch nichts.


Ich bin mir der Fehlersuche ziemlich unsicher. Leider habe ich im Moment 
keinen JTAG-Adapter zum Debuggen, sonst hätte man wenigstens mal gucken 
können ob es am Code oder an den anderen Sachen liegt.

Vielleicht hat das schon mal jemand gemacht und kann mir sagen wie es 
geht und welcher Datenlogger empfehlenswert ist.

Viele Grüße
David

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

David L. schrieb:
> Ich verstehe hier, dass UARTC0 das USB-Port auf
> dem Board nutzt. Zugleich ist UARTC0 am Pinheader J4 zu finden? Ist das
> richtig? Das würde ja bedeuten, dass die entsprechenden uC-Pins doppelt
> belegt sind, oder?

So isses. UARTC0 geht sowohl zum Boardcontroller als auch auf J4. Atmel 
Dokument AVR1924 enthält den Schaltplan zum A1-Xplained Board, hol dir 
das mal, wenn du es noch nicht hast.
AVR1927 enthält ein paar rudimentäre Hinweise zum Betrieb der UART über 
USB.
Stelle sicher, das du das USART so initialisierst:
#define USART_SERIAL_EXAMPLE             &USARTC0
#define USART_SERIAL_EXAMPLE_BAUDRATE    57600
#define USART_SERIAL_CHAR_LENGTH         USART_CHSIZE_8BIT_gc
#define USART_SERIAL_PARITY              USART_PMODE_DISABLED_gc
#define USART_SERIAL_STOP_BIT            false

Ich kann mich im Moment nicht genau erinnern, ob man nun SW0 beim 
Power-Up drücken muss, oder nicht - du solltest aber im Gerätemanager 
bei Windows dann unter COM Ports das Atmel Dings entdecken. Stelle auch 
da 57600, N, 8, 1 ein.

David L. schrieb:
> while(1)
> {
>     test = 0xFF;
>     uart_put(test);
> }

Lass dir da mal lieber ein druckbares Zeichen wie das grosse 'A' (0x41) 
ausgeben, nicht jedes Terminal druckt dir 0xFF aus.

: Bearbeitet durch User
von David L. (david_l87)


Lesenswert?

Die Initialisierungen stimmen überein und entsprechen auch denen im 
genannten Beispiel aus dem Forum. Auch im HW-Manager ist das Port 
dementsprechend inititalisiert.

Um ein Programm zu flashen muss ich beim Anstecken an das USB-Port die 
SW0 drücken. Wurde das Programm mit FLIP über COM9 geflasht, musste ich 
bisher immer reseten um in den Run-Modus zu kommen. Ich gehe also davon 
aus, dass das hier auch wieder so ist. Problem ist nur, dass ich nach 
dem Reset mit meinen Log-Programmen keine Verbindung zum Board über COM9 
herstellen kann. Vorm Reset, kann ich eine Verbindung herstellen - es 
werden aber keine Daten vom Board geschickt.

Hier nochmal mein kompletter Code zur Kontrolle:
1
#include <asf.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
#include <usart.h>
6
#include <stdio.h>
7
#include <string.h>
8
9
10
11
#define USART USARTC0
12
#define USART_SERIAL_EXAMPLE             &USARTC0
13
#define USART_SERIAL_EXAMPLE_BAUDRATE    57600
14
#define USART_SERIAL_CHAR_LENGTH         USART_CHSIZE_8BIT_gc
15
#define USART_SERIAL_PARITY              USART_PMODE_DISABLED_gc
16
#define USART_SERIAL_STOP_BIT            false
17
18
19
// USART options.
20
static usart_rs232_options_t USART_SERIAL_OPTIONS = {
21
  .baudrate = USART_SERIAL_EXAMPLE_BAUDRATE,
22
  .charlength = USART_SERIAL_CHAR_LENGTH,
23
  .paritytype = USART_SERIAL_PARITY,
24
  .stopbits = USART_SERIAL_STOP_BIT
25
};
26
27
// serial output
28
static void uart_put(char c) {
29
  while( (USART.STATUS & USART_DREIF_bm) == 0 ) {}
30
  // Now transmit the character
31
  USART.DATA = c;
32
}
33
//serial input
34
char conin(void) {
35
  while((USART.STATUS & USART_RXCIF_bm) == 0 ){};
36
  return USART.DATA;
37
}
38
39
char Zeichen;
40
41
42
    
43
int main (void)
44
{
45
46
  sysclk_enable_peripheral_clock(&USARTC0);
47
  sysclk_enable_module(SYSCLK_PORT_C, PR_USART0_bm);
48
  // ASF takes care of configuing the port pins
49
  usart_init_rs232(USART_SERIAL_EXAMPLE, &USART_SERIAL_OPTIONS);
50
  // more in main.......
51
52
  while(1)
53
  {
54
55
    Zeichen=0x41;
56
    uart_put(Zeichen);
57
58
    
59
  }
60
  return 0;
61
}

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Hmm, in meiner main.c include ich noch:
1
#include "conf_board.h"
2
#include "conf_clock.h"
3
#include "conf_usart_serial.h"
4
#include "usart.h"
und z.B. in der conf_board.h steht
1
#define CONF_BOARD_ENABLE_USARTC0
Ich hab schon länger nichts mehr mit ASF gemacht, aber es könnte helfen, 
das bei dir auch zu tun. Das setzt voraus, das du auch ASF im Projekt 
Ordner (Unterordner /src/asf) hast, was bei AVR Studio 6 eigentlich von 
alleine passieren sollte, sobald du das Board als Projektgrundlage 
angegeben hast.

von David L. (david_l87)


Lesenswert?

Ich probiere es mal. Was für ein LOg-Programm nutzt du?

von David L. (david_l87)


Lesenswert?

funzt leider auch nicht. ^^

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

David L. schrieb:
> Was für ein LOg-Programm nutzt du?

Was ist ein LOg-Programm? Falls du das Terminal auf der PC Seite meinst, 
gehts sowohl mit 'Hyperterminal' unter XP als auch 'HTerm' unter W7.

von David L. (david_l87)


Lesenswert?

Ein Programm zum Daten loggen... ^^

von jb (Gast)


Lesenswert?

>#define USART_SERIAL_EXAMPLE_BAUDRATE    57600

Da hab ich aber 9600 als Baudrate zwischen Xmega und At90UBS1287 im 
Kopf.
Eventuell läuft dir dann der USB-Buffer im AT über, weil du die Daten 
nicht schnell genug zum Xmega weiterschaufeln kannst, solltest du vom PC 
massiv Daten senden.

Gruß J

von David L. (david_l87)


Lesenswert?

ich möchte doch aber vom xmega zum pc senden.

Also. Auf Kampis Elektroecke gab es nochh ein etwas anderes 
Code-Beispiel von "Hallo Welt", was ich im Moment auf dem Board drauf 
habe. Er nutzt auch eine andere Möglichkeit der initialisierung, indem 
er die Register direkt anspricht.

Mit HTerm kann ich auch sekündlich etwas empfangen. Nun stellt es mir 
aber statt "Hallo Welt" irgendwelche Zeichen dar. ^^ In HTerm ist ASCII 
aktiviert und auch der HEXCode entspricht nicht den gewollten 
ASCII-Zeichen.
Eigentlich würde ich jetzt behaupten dass es am Code liegt, und 
irgendeine Typendeklaration oder Wandlung falsch ist. Aber ich sehe an 
sich nichts was falsch ist. Auch wenn ich einen ASCII Code direkt in 
eine Char schreibe und diese über die Ausgabefunktion in der TimerISR 
ausgeben lasse kommen nur wilde Zeichen. Ganz schöner FickFack. 
Hoffentlich geht es mit einem LCD und SPI einfacher. ^^


Hier der Code:
1
/*
2
 * Hallo_Welt.c
3
 *
4
 * USARTC0, Tx Pin -> PC3.
5
 * 9600 baud mit 2 MHz clock. BSCALE = 0
6
 * BSEL = ( 32000000 / (2^0 * 16*19200)) -1 = 12
7
 * Fbaud = 32000000 / (2^0 * 16 * (12+1))  = 9615 bits/sec
8
 *
9
 *
10
 * Created: 02.05.2012 21:36:29
11
 *  Author: Daniel
12
 */ 
13
14
#include <avr/io.h>
15
#include <avr/interrupt.h>
16
#include <string.h>
17
18
//Variablen
19
char lenght = 0x00;
20
char Counter = 0x00;
21
22
int main(void)
23
{
24
  Clock_init();  
25
  Int_init();
26
  UART_init();
27
  TimerC0_init();  
28
  
29
  TimerC0_Freq(0x85ED);  
30
  
31
    while(1)
32
    {
33
    }
34
}
35
36
void Clock_init(void)
37
{  
38
  OSC.CTRL |= OSC_RC32MEN_bm;                                              // Oszillator auf 32Mhz stellen
39
  while(!(OSC.STATUS & OSC_RC32MEN_bm));                                        // Warten bis der Oszillator bereit ist
40
  CCP = CCP_IOREG_gc;
41
  CLK.CTRL = CLK_SCLKSEL_RC32M_gc;                                          // Clock auf 32MHz stellen                                              
42
}
43
44
void Int_init(void)
45
{
46
  PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;                          // Interrupts (Highlevel, Mediumlevel und Lowlevel freigeben)
47
  sei();                                                        // Globale Interruptfreigabe
48
}
49
50
void UART_init(void)
51
{
52
  PORTC.DIR = 0xEF;  
53
  
54
  USARTC0.BAUDCTRLB = 0;                                                // BSCALE = 0 
55
  USARTC0.BAUDCTRLA = 0x67;                                                // Baudrate 19200 @ 41MHz
56
  USARTC0.CTRLB = USART_TXEN_bm | USART_RXEN_bm;                                    // RX+TX Enable CLK
57
  USARTC0.CTRLC = 0x03;                                                  // Async, no parity, 8 bit data, 1 stop bit
58
  USARTC0.CTRLA = 0;    
59
}
60
61
void TimerC0_init()
62
{
63
  TCC0.CTRLA = TC_CLKSEL_DIV1024_gc;                                          // Vorteiler einstellen
64
  TCC0.CTRLB = 0x00;                                                  // Timer in Normalmodus stellen
65
  TCC0.INTCTRLA = 0x03;                                                // Interrupt konfigurieren  
66
}
67
68
void TimerC0_Freq(int TTW)
69
{
70
  TCC0.PER = TTW;                                                    // Timer-Topwert(TTW) einstellen  
71
}
72
73
void Send_UART(char data[])
74
{
75
  lenght = strlen(data);
76
  
77
  while(Counter < lenght)
78
  {
79
    while (!(USARTC0.STATUS & USART_DREIF_bm));
80
    USARTC0.DATA = data[Counter];  
81
    Counter++;
82
  }
83
    
84
  Counter = 0x00;  
85
  while (!( USARTC0.STATUS & USART_DREIF_bm));
86
  USARTC0.DATA = 0x0A;  
87
  while (!( USARTC0.STATUS & USART_DREIF_bm));
88
  USARTC0.DATA = 0x0D;
89
}
90
91
ISR(TCC0_OVF_vect)
92
{
93
  TimerC0_Freq(0x85ED);  
94
  Send_UART("Hallo Welt!");
95
}

: Bearbeitet durch User
von jb (Gast)


Lesenswert?

>Nun stellt es mir
>aber statt "Hallo Welt" irgendwelche Zeichen dar. ^^

Dann steht die Verbindung schon mal physisch, jetzt brauchst du nur die 
passenden Einstellungen auf beiden Seiten und es funktioniert.-

Dann probiert man ein paar Einstellungen(also die Baudraten) am PC 
durch, bis man was "richtiges" empfängt. An Hand der Diskrepanz der 
Einstellung zu dem Ergebnis kann man dann auf das Problem schließen. 
Meistens fuse/falsche Clock-Einstellungen.

Gruß Jonas

von jb (Gast)


Lesenswert?

Natürlich physikalisch :D

von David L. (david_l87)


Lesenswert?

Es ist sehr sehr kurios. Manchmal gehts, manchmal nicht und das bei 
gleichen Einstellungen. Im Moment geht wieder mal gar nichts ^^ Ich 
probier mal ein bissl weiter rum.

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.