Hallo zusammen,
habe folgendes Verständnisproblem. Wie ist das genau mit USB und RS232.
Ich sende Daten via USB in den PIC und nöchte diese via RS232
weitersenden. Muss beim senden via RS232 das interne USB Modul des PIC´s
deaktiviert werden?
lg,
blitzgeist
Die Seite kenn ich mitlerweile in und auswendig. Ist echt ne sehr gute
Seite jedoch wird da auch nicht meine Frage beantwortet.
Versuche es mal ein bischen genauer zu beschreiben...
In der Firmware von MP gibt es u.a. zwei Funktionen USBModuleEnable und
USBModuleDisable. USBModuleEnable macht folgendes: usb_device_state =
ATTACHED_STATE; d.h. Enable module & attach to bus
und USBModuleDisable macht: Disable module & detach from bus,
usb_device_state = DETACHED_STATE;
Jetzt gibt es in einer anderen Funktion namens BlinkUSBStatus den
Codeausschnitt:
.
.
.
if(UCONbits.SUSPND == 1)
{
if(led_count==0)
{
mLED_1_Toggle();
mLED_2 = mLED_1; // Both blink at the same time
}//end if
}
else
{
if(usb_device_state == DETACHED_STATE)
{
mLED_Both_Off();
PICDEMFSUSBDemoBoardTest();
}
else if(usb_device_state == ATTACHED_STATE)
{
mLED_Both_On();
}
.
.
.
Der Funktionsauffruf: PICDEMFSUSBDemoBoardTest() führt ein RS232 Setup
durch und startet die Übertragung via RS232.
ABER: PICDEMFSUSBDemoBoardTest() wird erst aufgerufen wenn
usb_device_state == DETACHED_STATE!!! Dann ist doch aber mein USB Modul
im PIC deaktiviert? Wie soll das genau funktionieren?
Versuche es schon seit Stunden zu vertehen, vergebens...
Wäre echt nett wenn jemand ein Paar erklärende Worte findet.
lg,
blitzgeist
@gast
aber laut fw wird doch das USB Modul ausgeschaltet.
Wie rufe ich überhaupt die Kommunikation auf, dass über RS232 gesendet
werden soll? Schaffe ich mir da ein Command namens SendViaRS232? Wenn
dieser Command in meiner switch/case Anweisung ankommt, in den
entsprechenden case Zweig geht, und da die RS232 initialisiert und die
Daten versendet? Aber wie gesagt, laut fw muss ich das interne USB Modul
deaktivieren (usb_device_state == DETACHED_STATE).
Kann ja nicht wissen, dass du von Microchips Firmware sprichst.
Das Problem ist, wenn das USB-Modul aktiviert ist und eine Übertragung
über RS232 erfolgt, welche ja deutlich länger braucht, als ein
USB-Transfer, dann bleibt für das Hauptprogramm nicht mehr genug Zeit,
um die State-Machine für die USB-Kommunikation zu bedienen. Es käme
somit zu einem sofortigen Abbruch und der PIC würde aus der
Systemsteuerung verschwinden. Das steht auch in irgendeinem PDF von
Microchip, dass in der USB-Schleife nichts gemacht werden soll, was
länger braucht.
Ich hoffe, das war einigermaßen verständlich.
@Gast
Ja benutze MCHPFSUSB. Aber wenn das USB Modul deaktiviert ist bekommt
dann der PIC überhaupt noch Spannung, wenn es ein bus power device
werden soll?
Klingt logisch.
Und was meinst du hierzu?
Wie rufe ich überhaupt die Kommunikation auf, dass über RS232 gesendet
werden soll? Schaffe ich mir da ein Command namens SendViaRS232? Wenn
dieser Command in meiner switch/case Anweisung ankommt, in den
entsprechenden case Zweig geht, und da die RS232 initialisiert und die
Daten versendet?
Denke das ist ein möglicher Ansatz, oder?
na von Microchip hab ich eine SW, die "CDC RS-232 Emulation Tutorial
Instructions" heisst und für ihre 18er-PICs mit USB geschrieben ist.
getestet habe ich sie noch nie, aber ich denke USB und RS232 kann man
gleichzeitig brauchen ...beid der performance kommt es halt darauf an,
wie die SW geschrieben wird.
@Ron
// For board testing purpose only
void PICDEMFSUSBDemoBoardTest(void);
Das ist tatsächlich nur eine Funktion zum testen des
Demoboards von Microchip. Soweit ich weiß hat das ein
eigenes Netzteil. Da in der Funktion solche Warteschleifen stehen
while(!Switch2IsPressed());
die zu einer längeren Unterbrechung der USB Routinen
führen könnten (was man wie Gast ja schon sagte nicht darf),
wird diese Routine nur aufgerufen wenn der PIC NICHT am
USB Port angeschlossen ist. Spannung bekommt er aber weiter
aus dem Netzteil. Somit macht DETACHED_STATE schon Sinn.
Sobald du den PIC an den USB Port anschließt kannst du die
Routine aber nicht mehr aufrufen.
Danke schon mal für eure Antworten=)
Mir ist das immernoch ein wenig unklar. Ich habe nun in der docu zu
diesem Demo Board von MCHP gelesen (steht auf im Datenblatt des PICs),
dass über das UCONbits.USBEN ein simulierendes trennen des PIC´s als USB
device erzeugen kann. Für was ist das gut? Und wenn man sich mal die
Firmware von MCHP und zwar genau die im Verzeichnis MCHPFSUSP\fw\demo
anschaut, frage ich mich WO hier der if Zweig
if(usb_device_state == DETACHED_STATE){
mLED_Both_Off();
PICDEMFSUSBDemoBoardTest();
}
aufgerufen wird. Ok, klar, wenn man den PIC vom BUS trennt. Man trennt
ihn aber doch nicht physikalisch sondern nur über UCONbits.USBEN = 0,
oder??????
Wenn ja, WO wird das in der fw gemacht?
Und, mal ne generelle Frage: Muss ich also immer, wenn ich was über
RS232 senden möchte den PIC in den usb_device_state == DETACHED_STATE
bringen? Wie ich nun aus euren Beiträgen herausgelesen habe, hält die fw
MCHPFSUSP\fw\demo die USB routinen an, solange via RS232
gesendet/empfangen wird, an.
Wäre nett, wenn ihr mir weiter helfen könntet.
lg
blitzgeist
Hi,
ist schon etwas länger her bei mir, dennoch versuche ich es mal.
Du hast die main(void), in der läuft als Endlosschleife
1
while(1)
2
{
3
USBTasks();
4
ProcessIO();
5
}
Wobei in USBTasks() zwei Dinge geschehen. Zum einen wird mittels der
Funktion USBCheckBusStatus() überprüft, ob ein Gerät angeschlossen ist.
Hierzu hat du zwei Möglichkeiten: entweder über einen Spannungspegel an
einem IO-Pin des PICs, oder aber unabhängig davon, also rein durch die
Firmware. Außerdem werden in USBTasks() sämtliche USB-relevanten
Interrupts ausgewertet. Die Funktion USBTasks() darf daher auf keinen
Fall lange unterbrochen werden. Wie lange, kann ich dir leider nicht
sagen. Solltest du es herausfinden, bitte schreien :)
In ProcessIO() kannst du nun deine Sachen reinschreiben,
Tastenauswertung oder Displayansteuerung, um nur zwei Beispiele zu
nennen. Auch kannst du in ProcessIO() natürlich deine RS232-Routine
reinbasteln.
Auf keinen Fall würde ich den PIC in den DETACHED_STATE versetzen, da
sich dadurch der PIC ja auch jedesmal am PC neu an- und abmeldet.
Theoretisch kein Problem, nur wie das halt so ist, es funktioniert
selten 100%. Aus eigener Erfahrung kann ich sagen, dass es manchmal
vorkommt, dass sich der PIC nicht mehr anmeldet. Nur ein Totalreset
rettet die Situation. Ich bezweifle, dass es am Betriebssystem des PCs
liegt, da ich das Problem sowohl unter Linux als auch Windows beobachtet
habe. Scheint wohl eher was mit der Firmware des PICs nicht in Ordnung
zu sein, oder aber sogar mit dem Host-Controller auf meinem Mainboard;
keine Ahnung.
Also daher versuche deine RS232-Routine so zu schreiben, dass sie
längere Ausgaben nicht an einem Stück macht. Lege einen Puffer an,
schreibe in diesen deinen Text und sende die Daten häppchenweise,
vielleicht sogar interruptgesteuert. Keine Ahnung, ob das in deinem Fall
funktioniert. Du hast ja auch leider nichts geschrieben, wieviel du
senden willst.
BTW: ich finde die Firmware von Microchip extrem unübersichtlich und
shlecht dokumentiert.
@Ron
>aufgerufen wird. Ok, klar, wenn man den PIC vom BUS trennt. Man trennt>ihn aber doch nicht physikalisch sondern nur über UCONbits.USBEN = 0,>oder??????>Wenn ja, WO wird das in der fw gemacht?
NIRGENDS !
>Und, mal ne generelle Frage: Muss ich also immer, wenn ich was über>RS232 senden möchte den PIC in den usb_device_state == DETACHED_STATE>bringen?
Nein, natürlich nicht !
Geh endlich aus diesem verdammten Demoprogramm raus.
Sieh dir die Beispiele für HID oder CDC an.
Vielen Dank für deine ausführliche Information. Sehr hilfreich
Kloberscht. Nun was mir ein wenig zu bedenken gibt, ist, dass man die
USB routine nur für eine gewisse Zeit unterbrechen darf. Für was ist
dann der isochrone Transfer gut, welcher Echtzeit unterstützt?
Angenommen ich habe ein System, das sagen wir mal 30 Minuten Daten über
RS232 an den PIC sendet und von da aus via USB an den Host (PC). Dann
geht das nur, wie du schon sagst, über kleine interruptgesteuerte
Datenpakete?
Hmmm...
Also das würde mich brennden interessieren wie lange man die USB Routine
unterbrechen darf. Woher stammt eigendlich diese Aussage? Man kann doch
bestimmt mal bei einen technischen support von Microchip anfragen was
das mit der Unterbrechung der USB routine betrifft.
lg.
blitzgeist
@holger
HID und CDC ist aber nichts für meine Anwendung. Ich benötige USB FS
also 12MBit/s, was mit HID und CDC(emulator) ja nicht möglich ist. Für
mich kommt nur die MCHP Custom Driver fw in Frage.
Communication Device Class (CDC) firmware
CDC auf Microchip:
The Communication Device Class firmware is the most direct way or
migrating a serial port (legacy) application to USB. In fact this
firmware provides direct emulation of a serial port on PC running
Windows 2K and Windows XP. As the PIC18F4550 is attached to the PC, a
virtual COMx port is created. All PC software using a COM1-4 port will
work without modifications with the virtual COM port if only at a much
higher speed (approx 1Mbit/s)
PROS: free, simple to use, easy migration from serial port applications
CONS: data transfer speed limited to about 1Mbit/s, no hardware
handshake emulation (not necessary)
Memory requirements: about 4K bytes
Windows drivers: no driver required (Windows 2K/XP), xxx.inf file must
be supplied
.
.
.
Ähm,
vielleicht verpasse ich etwas,
aber IMHO können USB- und EUSART-Hardware gleichzeitig laufen.
Die Int-Routinen für den UART können gar nicht lange dauern, um den
USB-Part auszubremsen.
Warum also die (Software-)emulierten Ports verwenden ?
@Bernd Rüter: das klingt doch etwas ermutigend =) Gut, denke mir auch
das die Init-Routine für einen EUSART nicht langen andauern, aber was
ist wenn ich ca. 30 Minuten z.B. eine Messung via RS232 aufnehme? Wird
dann zu lange die USBTasks() unterbrochen? Ich habe es noch nicht auf
der HW ausprobiert, aber ist das so?
Was mir auch aufgefallen ist in der Firmware MCHPFSUSB\fw\Demo wird
mittels while(!Switch2IsPressed()); quasi die USBTasks() für eine
unendliche Zeit unterbrochen, bis eben der User den Taster betätigt und
denke die Software wird sich auch nicht aufhängen.
Also Bernd, meinst du USB und EUSART können parallel arbeiten? Und was
hat das dann mit der MCHPFSUSB\fw\Demo aufsich? bezüglich
@Ron
>Danke trotzdem für deine Antworten, wäre aber noch sehr hilfreich wenn>du mir sagen würdest, wie es jetzt nun ist. Wo wird denn nun das>UCONbits.USBEN gesetzt?
usbdrv.c nimm einen Texteditor mit Suchfunktion.
>Was mir auch aufgefallen ist in der Firmware MCHPFSUSB\fw\Demo wird>mittels while(!Switch2IsPressed()); quasi die USBTasks() für eine>unendliche Zeit unterbrochen, bis eben der User den Taster betätigt und>denke die Software wird sich auch nicht aufhängen.
USBTasks() wird nicht unterbrochen. Warum nicht ? Es wird gar nicht
aufgerufen. Warum nicht ?
PICDEMFSUSBDemoBoardTest(); wird nur aufgerufen wenn keine
USB Verbindung vorhanden ist.
if(usb_device_state == DETACHED_STATE)
{
mLED_Both_Off();
PICDEMFSUSBDemoBoardTest();
}
Das hier: while(!Switch2IsPressed());
steht nur in PICDEMFSUSBDemoBoardTest();
Das wird nur dann aufgerufen wenn Programm nicht hat Verbindung
mit USB. Du mich jetzt können verstehen ?
Man bist du lernresistent.
>@holger>HID und CDC ist aber nichts für meine Anwendung. Ich benötige USB FS>also 12MBit/s, was mit HID und CDC(emulator) ja nicht möglich ist. Für>mich kommt nur die MCHP Custom Driver fw in Frage.
Du glaubst doch nicht ernsthaft das du mit einem lahmen PIC
auch nur annähernd 12MBit/s schaffen kannst ? So über den
Daumen 1MB/s. Jede us soll ein Byte aus dem PIC tröpfeln.
Bei einer softwarebasierten USB Lösung. Du kannst froh sein
wenn du da 100kB/s raus kriegst.
Geh vielleicht auch mal auf forum.microchip.com, dort sind sehr
kompetente Leute, u. a. auch Ingenieure von Microchip.
> Bei einer softwarebasierten USB Lösung. Du kannst froh sein> wenn du da 100kB/s raus kriegst.
Der PIC18Fx550 hat einen USB-FS-Transceiver eingebaut, 100kB/s ist kein
Problem.
Moin zusammen,
@holger: ich glaube ernsthat dass man mit den PICs 18F2455, 2550, 4455,
4550 12MBit/s hinbekommt. Es heißst ja nicht umsonst PIC´s mit FS auf
der Microchip Seite.
>USBTasks() wird nicht unterbrochen. Warum nicht ? Es wird gar nicht>aufgerufen.
USBTasks() wird IMMER aufgerufen.
if(usb_bus_sense==USB_BUS_ATTACHED)// Is USB bus attached?
11
{
12
if(UCONbits.USBEN==0)// Is the module off?
13
USBModuleEnable();// Is off, enable it
14
}
15
else
16
{
17
if(UCONbits.USBEN==1)// Is the module on?
18
USBModuleDisable();// Is on, disable it
19
}//end if(usb_bus_sense...)
20
21
/*
22
* After enabling the USB module, it takes some time for the voltage
23
* on the D+ or D- line to rise high enough to get out of the SE0 condition.
24
* The USB Reset interrupt should not be unmasked until the SE0 condition is
25
* cleared. This helps preventing the firmware from misinterpreting this
26
* unique event as a USB bus reset from the USB host.
27
*/
28
if(usb_device_state==ATTACHED_STATE)
29
{
30
if(!UCONbits.SE0)
31
{
32
UIR=0;// Clear all USB interrupts
33
UIE=0;// Mask all USB interrupts
34
UIEbits.URSTIE=1;// Unmask RESET interrupt
35
UIEbits.IDLEIE=1;// Unmask IDLE interrupt
36
usb_device_state=POWERED_STATE;
37
}//end if // else wait until SE0 is cleared
38
}//end if(usb_device_state == ATTACHED_STATE)
39
40
}//end USBCheckBusStatus
Ist das USB Modul deaktivert, wird es über USBModuleEnable(); aktiviert
gelangt somit in die states DETACHED -> ATTACHED -> POWERED -> DEFAULT
-> ADDRESS_PENDING -> ADDRESSED -> CONFIGURED -> READY
In main.c, ProcessIO(),
In der wiederrum die Funktion PICDEMFSUSBDemoBoardTest(), welche dann
letzt endlich eine RS232 Übertragung startet.
Aber nur wenn usb_device_state == DETACHED_STATE. Der usb_device_state
kann nur über USBTasks()-> USBCheckBusState() (hier wird nur die
physikalische Verbindung überprüft) oder -> USBDriverService(). Dort
verläuft es sich dann in den Tiefen des USB Treibers... Fakt ist das
jedoch nur über USBTasks()->USBCheckBusState()->USBModuleDisable()
usb_device_state in den DETACHED_STATE gelangt oder noch über die
Funktion void USBSoftDetach(void). Wo jedoch die aufgerufen wird, habe
ich noch nicht gefunden(spätestens jetzt brauche ich endlich mal einen
Texteditor mit Suchfunktion, Spaß am Rande).
Wie gelangt nun usb_device_state in den DETACHED_STATE? Nur über
USBTasks()->USBCheckBusState()->USBModuleDisable(), wenn das USB-Kabel
physikalisch getrennt ist? Das kann nicht sein. Denke das hat was mit
void USBSoftDetach(void) zutun.
ABER, laut Bernd Rüter, mus usb_device_state gar nicht in den
DETACHED_STATE. Was meint der Rest dazu? Wenn dem so ist, finde ich die
MCHPFSUSB\fw\Demo ein wenig verwirrend, dass nur RS232
gesendet/empfangen werden kann, wenn usb_device_state im DETACHD_STATE
ist.
lg,
blitzgeist
@Gast:
Ich habe auch schon mal eine Schilderung des Sachverhalts an den support
vom MCHP gesendet. Bin mal gespannt wann/was zurückkommt =)