Forum: Mikrocontroller und Digitale Elektronik Self Powered USB mit Atmega32


von Thomas K. (tkrieger)


Angehängte Dateien:

Lesenswert?

Hallo,

habe zur Zeit vor mich ein wenig mit USB zu beschäftigen. Mein Ziel ist 
es ein Atmega32 so zu beschalten und zu programmieren, das Daten mit ca. 
1MBit/s mit dem PC ausgetauscht werden können.

Als Software soll dazu die AVR USB Implementierung von obdev.at genutzt 
werden:

http://www.obdev.at/products/avrusb/index.html

Bei obdev.at sind allerdings nur Beispielschaltungen zu Devices die 
ihren Strom aus dem USB Bus ziehen. Daher wollte ich fragen, ob ein 
Anschluss nach dem angehängten Plan Sinn macht. Ich selbst bin noch 
recht am Anfang was Elektronik angeht.

Die Frage ist kann ich V_bus so "in der Luft" stehen lassen?
Reicht es die GND Leitungen der externen Spannungsversorgung mit dem USB 
GND zu verbinden, das die D+ und D- Signale ordentlich übermittelt 
werden?

Für Hinweise wäre ich sehr Dankbar!

Gruß

Thomas

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Keiner "zwingt" dich Strom aus dem USB Bus zu beziehen, nur GND sollte 
halt verbunden sein dann klappt das schon :)

von Thomas K. (tkrieger)


Angehängte Dateien:

Lesenswert?

Hab mir nochmal das Metaboard in dem Projekt angeschaut und den 
Kondensator und den 1k5 Ohm Widerstand an die Vcc Leitung des Atmega 
gebunden.

Werd es jetzt mal zusammenlöten und einen Versuch starten. Vielen Dank!

Gruß

Thomas

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Viel Glück! Berichte mal ob es geklappt hat!

von crazy horse (Gast)


Lesenswert?

und wenn du die Vcc/Gnd-Symbole auch an jedem Bauteil benutzt, welches 
an Vcc/gnd liegt, werden die Schaltpläne nicht ganz so wirr...

von Christian F. (Gast)


Lesenswert?

Die Spannungsversorgung usw. muss erst beim Layout komplett verbunden 
werden :-P
Mit den VCC/GND-Symbolen werden imaginäre Leitungen gezogen und dein 
Schaltplan sieht um einiges übersichtlicher aus  :)

von 3374 (Gast)


Lesenswert?

Mit wenig Ahnung von USB, noch von Elektronik wuerde ich mir das nicht 
antun, dafuer alternativ fuer 4 Euro einen FT232 chip drauf tun.

von tom (Gast)


Lesenswert?

Oder AT90USB. Der hat USB onboard.

von Thomas K. (tkrieger)


Angehängte Dateien:

Lesenswert?

Hallo,

leider kann ich die AT90USB nicht verwenden, da bereits ein Atmega32 in 
dem Projekt verwendet wird, wo die USB Schnittstelle eingepflegt werden 
soll.

Da schon einige IO-Pins belegt sind, kam mir die AVR USB Lösung am 
besten vor. Bisher habe ich einen Grundschaltung (siehe Anhang), jetzt 
erstmal als Bus Powered USB Device angelegt und die PowerSwitch Software 
aus:

http://www.obdev.at/products/avrusb/powerswitch.html

Aufgespielt und angepasst. Bisher bekomme ich ca. jeden 3. oder 4. 
Versuch einen Verbindung mit dem PC hin. Unter Linux zumindest, bei 
Windows Vista meldet er sich noch nicht. Unter Linux wird die 
entsprechende Device und Vendor ID bei lsusb angezeigt, allerdings mehr 
auch nicht.

Wollte zunächst mal einen 1MOhm Pull-Down Wiederstand an D+ anbringen, 
um falsche Interrupts zu vermeiden.

Werde dann nochmal berichten.

Gruß

Thomas

von Εrnst B. (ernst)


Lesenswert?

der 1.5K Pull-Up zur Device-Speed-Erkennung muss nach 3.3V geschaltet 
werden, nicht an 5V.
So fliesst da zuviel Strom, das kann deine "wacklige" USB-Verbindung 
erklären.
Versuch da mal eher 2.2k, wenn du nur 5V zur Verfügung hast.

von Thomas K. (tkrieger)


Lesenswert?

Hab mal gerade umgelötet, und habe jetzt scheinbar noch häufiger ein 
Connect. Allerdings so ganz in Ordnung scheint es auch noch nicht zu 
sein, werde nochmal prüfen, ob es neben den 2k2 Widerstand noch andere 
Optimierungen gibt oder evtl. ein Software Problem.

Danke für den Tip!

Gruß

Thomas

von Thomas K. (tkrieger)


Lesenswert?

Juhu, hab eine erste Kommunikation!

Hab mit dem PowerSwitch Projekt kurze Abfragen gesandt, die die 
usbFunctionSetup beantwortet hat ;)

Der Schaltplan ist noch der alte (s.o. ca. 2 Antworten). Denke der 
Schaltplan bräuchte noch kleine Änderungen, da eine Verbindung nur jedes 
2. oder 3. mal zustande kommt.

Die Firmware enthällt die folgende usbconfig.h
1
#define USB_CFG_IOPORTNAME      D
2
#define USB_CFG_DMINUS_BIT      3
3
#define USB_CFG_DPLUS_BIT       2
4
#define USB_CFG_CLOCK_KHZ       16000
5
#define USB_CFG_HAVE_INTRIN_ENDPOINT    0
6
#define USB_CFG_HAVE_INTRIN_ENDPOINT3   0
7
#define USB_CFG_EP3_NUMBER              3
8
#define USB_CFG_IMPLEMENT_HALT          0
9
#define USB_CFG_INTR_POLL_INTERVAL      10
10
#define USB_CFG_IS_SELF_POWERED         0
11
#define USB_CFG_MAX_BUS_POWER           100
12
#define USB_CFG_IMPLEMENT_FN_WRITE      0
13
#define USB_CFG_IMPLEMENT_FN_READ       0
14
#define USB_CFG_IMPLEMENT_FN_WRITEOUT   0
15
#define USB_CFG_HAVE_FLOWCONTROL        0
16
#define USB_CFG_LONG_TRANSFERS          0
17
#define USB_COUNT_SOF                   0
18
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH   0
19
#define  USB_CFG_VENDOR_ID       0xc0, 0x16
20
#define  USB_CFG_DEVICE_ID       0xdc, 0x05
21
#define USB_CFG_DEVICE_VERSION  0x00, 0x01
22
#define USB_CFG_VENDOR_NAME     'o', 'b', 'd', 'e', 'v', '.', 'a', 't'
23
#define USB_CFG_VENDOR_NAME_LEN 8
24
#define USB_CFG_DEVICE_NAME     'U', 'S', 'B', '-', '2', '3', '2'
25
26
#define USB_CFG_DEVICE_NAME_LEN 7
27
28
#define USB_CFG_DEVICE_CLASS        0xff    /* set to 0 if deferred to #define USB_CFG_DEVICE_SUBCLASS     0
29
#define USB_CFG_INTERFACE_CLASS     0x02   /* define class here if not at device level */
30
#define USB_CFG_INTERFACE_SUBCLASS  2
31
#define USB_CFG_INTERFACE_PROTOCOL  1
32
#define USB_CFG_DESCR_PROPS_DEVICE                  0
33
#define USB_CFG_DESCR_PROPS_CONFIGURATION           0
34
#define USB_CFG_DESCR_PROPS_STRINGS                 0
35
#define USB_CFG_DESCR_PROPS_STRING_0                0
36
#define USB_CFG_DESCR_PROPS_STRING_VENDOR           0
37
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT          0
38
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER    0
39
#define USB_CFG_DESCR_PROPS_HID                     0
40
#define USB_CFG_DESCR_PROPS_HID_REPORT              0
41
#define USB_CFG_DESCR_PROPS_UNKNOWN                 0
42
43
/* #define USB_INTR_CFG            MCUCR */
44
#define USB_INTR_CFG_SET        ((1 << ISC00) | (1 << ISC01)) 
45
/* #define USB_INTR_CFG_CLR        0 */
46
#define USB_INTR_ENABLE         GIMSK
47
#define USB_INTR_ENABLE_BIT     INT0 
48
/* #define USB_INTR_PENDING        GIFR */
49
/* #define USB_INTR_PENDING_BIT    INTF0 */
50
#define USB_INTR_VECTOR         SIG_INTERRUPT0 
51
52
#endif /* __usbconfig_h_included__ */

Insbesonder die auskommentierung von den letzten Interrupt 
Einstellungen, hat die Kommunikation im letzten Schritt zum laufen 
gebracht.

Als main habe ich folgendes Konstrukt:
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <avr/wdt.h>
5
#include <avr/interrupt.h>
6
7
#include <util/delay.h>
8
#include <avr/pgmspace.h>   /* required by usbdrv.h */
9
#include "usbdrv.h"
10
#include "oddebug.h"        
11
12
usbMsgLen_t usbFunctionSetup(uchar data[8])
13
{
14
  usbRequest_t    *rq = (void *)data;
15
  static uchar    replyBuf[2];
16
17
    usbMsgPtr = replyBuf;
18
    if(rq->bRequest == 0){  /* ECHO */
19
        replyBuf[0] = rq->wValue.bytes[0];
20
        replyBuf[1] = rq->wValue.bytes[1];
21
        return 2;
22
    }
23
    if(rq->bRequest == 1){  /* GET_STATUS -> result = 2 bytes */
24
        replyBuf[0] = 0x00;
25
        replyBuf[1] = 0xFF;
26
        return 2;
27
    }
28
    if(rq->bRequest == 2 || rq->bRequest == 3){ /* SWITCH_ON or SWITCH_OFF, index = bit number */
29
    }
30
31
    return 0;   /* default for not implemented requests: return no data back to host */
32
}
33
34
int main(void) 
35
{
36
    uchar i;
37
  
38
    wdt_enable(WDTO_1S);
39
    
40
    // Reset USB API
41
    usbDeviceDisconnect();
42
43
  // Wait some ms        
44
    for (i=0;i<254;i++)
45
    {
46
  wdt_reset();
47
  _delay_ms(1);
48
    }
49
    
50
    // Re-init USB API
51
    usbDeviceConnect();
52
    
53
    // Init USB 
54
  usbInit();
55
  
56
  // Enable interrupts    
57
    sei();
58
    
59
    for(;;){     
60
        wdt_reset();
61
        usbPoll();
62
    }
63
}

Der Code ist ein bisschen zusammenkopiert aus dem AVR USB PowerSwitch 
Projekt. Daher nochmal ein herzliches Danke und hier der Hinweis auf die
Homepage:

http://www.obdev.at/products/avrusb/powerswitch.html

Die Abfragen an das Device wurden ebenfalls mit dem PowerSwitch 
commandline
Tool gesandt. Als erfolgreiche Kommunikation hat mir heute Nacht erstmal 
die Statusabfrage gelangt. Es wird immer 0x00 und 0xFF zurückgesandt, 
und
entsprechend werden die Zustände der (nicht vorhandenen) LED's 
angezeigt.

Ich hoffe es hilft vielleicht auch einigen anderen, auch wenn hier noch
ein bisschen Arbeit nötig ist.

- Verbindung funktionier nicht auf anhieb
- Vendor und Produktbeschreibung werden nicht übertragen

Unter Linux bisher nur getestet, werde mich Morgen mal an Windows dran 
wagen.

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.