Messen, Steuern und Regeln mit USB - FAQ


Frage: Kann das EZUSB-System unter Windows 2000 verwendet werden?

Antwort: Bei Anchorchips (jetzt unter www.cypress.com) wurde der Treiber weiterentwickelt. Auf der Cypress-Seite kann man die komplette Software zum EZUSB-Entwicklungssystem laden. Die Treiber funktionieren unter Windows 2000. Sie haben jedoch noch keine digitale Signatur. Man muss also unter Systemeigenschaften/Hardware/Gerätemanager/Treibersignierung einstellen, dass man ohne Signatur installieren will. Der Treiber EZUSB.SYS und die passende INF-Datei kann hier geladen werden: ezusbw2k.zip (24 k)


Frage: Gibt es neben dem EZUSB eine preiswertere Lösung für einfache Portzugriffe über den USB?

Antwort: Auf der Basis des CY7C63001 wurde von Modul-Bus (http://www.ak-modul-bus.de) ein Spezialchip USBport entwickelt, der den freien Zugriff auf 12 Portanschlüsse erlaubt. Der Chip hat für den USB eine ähnliche Funktion wie ein UART für die serielle Schnittstelle. Man kann ihn also in beliebige Steuerungen oder Anlagen einbauen. Der USBport verwendet die Vendor-ID von Modul-Bus und wird mit einem Treiber und einem Programmbeispiel in Visual Basic ausgeliefert.


Frage: Wie übersetzt man Treiber mit der DDK?

Antwort: Hierzu gibt es auf meiner Homepage einen eigenen Schwerpunkt: USB-Treiberentwicklung


Frage: Mit welchem Gerät kann der CY7C63001 programmiert werden?

Antwort: Das inzwischen leider nicht mehr lieferbare Starterkit von Cypress hatten einen speziellen Programmer CY3649-xxxV von Hi-Lo Systems. Das Gerät ist anscheinend einzeln nicht mehr zu bekommen. Jetzt ist man auf den Universalprogrammer ALL-11 von Hi-Lo angewiesen, siehe http://www.hilosystems.com.tw/

Nachtrag: Anscheinend ist der Programmer aus dem Starterkit doch noch zu bekommen: Future Electronics Deutschland GmbH, Oskar-Messter-Str. 25, 85737 Ismaning, Telefon 089 95727-0, Typenbezeichnung des Brenners: CY3649-220V, Preis ca. 210 DM + MwSt.


Frage: Arbeitet der CY7C63001 nur mit einem zweipoligen Keramikresonator

Antwort: Die ersten Typen aus dem Starterkit waren sehr empfindlich im Anschwingverhalten. Die A-Version des Prozessors CY7C63000A läuft aber anscheinend genauso gut mit einem Quarz oder einem dreipoligen Keramikresonator. Der mittlere Pin kann frei bleiben oder auf Masse gelegt werden.


Frage: Das Programm Seraiusb.exe zeigt am Kanal 7 grobe Messfehler.

Antwort: Das nachgeladene Programm EZad.Bin auf der CD im Buch hatte einen Fehler. Hier ist die berichtigte Version: ezad.zip (1k)

Noch ein Fehler: Der zweite Fehler wurde zuerst im Anwenderprogramm SeraiUSB entdeckt, dann aber auch im Beispiel Max186a aus dem Buch: Wenn Kanal 4 an Masse gelegt wird, dann zeigen alle anderen Kanäle falsche Werte.

Nach mühsamer Suche wurde folgendes festgestellt: Die Funktion ReadRamBytes verwendet VENDOR_REQUEST_IN zum Lesen von Datenblöcken. Wenn in einem gelesenen Block genau an der Stelle 08 eine Null steht, wird der ganze Datenbereich falsch gelesen. Ich vermute hier einen Bug im USB-Kern des Prozessors. Falls jemand näheres weiß, wäre ich für eine Rückmeldung dankbar.

Jetzt gibt es zwei Lösungen des Problems. Eine quick-and-dirty-Lösung vermeidet einfach die Null an dieser Stelle auf Kosten der Genauigkeit von Kanal 4:

     mov a,#174 ;Ch4   
     lcall RdAD
     mov a,R3   ;Highbyte
     jnz min1
     inc a
min1 mov DPTR,#0208h   ;Notlösung wg. Bug im EZusb?
     movx @DPTR,A
     mov a,R4   ;Lowbyte
     inc DPTR  
     movx @DPTR,A

Auszug aus dem Assemblerprogramm EZad.asm.

Dieser Quelltext wurde als Binärfile kompiliert. Das neue Programm EZad.bin muss nun in das Verzeichnis von SeraiUSB kopiert werden. Nun funktionieren alle Kanäle außer Kanal 4 problemlos. Programm laden (ezad2.zip, 2k)

Die saubere Lösung:

Man liest einfach einen größeren Datenbereich ab 01F0h aus. Das gestörte Byte liegt dann in einem Bereich, den man nicht benötigt. Dann muss man aber auch noch dafür sorgen, dass an der fraglichen Stelle nicht zufällig eine Null steht. Diese Lösung wird an dem Programm Max186a aus dem Buch demonstriert. Es kann hier in der veränderten Form geladen werden: Max186a (Max186a.zip, 6k)

     mov a,#1   ; Bug-Korrektur an Pos. 08h 
     mov DPTR,#01F8h   
     movx @DPTR,A

Auszug aus Max186a.asm

procedure TForm1.Timer1Timer(Sender: TObject);
var     Messwert: Word;
begin
  ReadRamBytes ($1F0,32);
  Messwert := InBuffer[$11]+16*InBuffer[$10];
  Edit1.Text := FloatToStr (Messwert);
  Messwert := InBuffer[$13]+16*InBuffer[$12];
  Edit2.Text := FloatToStr (Messwert);
  Messwert := InBuffer[$15]+16*InBuffer[$14];
  Edit3.Text := FloatToStr (Messwert);
  Messwert := InBuffer[$17]+16*InBuffer[$16];
  Edit4.Text := FloatToStr (Messwert);
  Messwert := InBuffer[$19]+16*InBuffer[$18];
  Edit5.Text := FloatToStr (Messwert);
  Messwert := InBuffer[$1B]+16*InBuffer[$1A];
  Edit6.Text := FloatToStr (Messwert);
  Messwert := InBuffer[$1D]+16*InBuffer[$1C];
  Edit7.Text := FloatToStr (Messwert);
  Messwert := InBuffer[$1F]+16*InBuffer[$1E];
  Edit8.Text := FloatToStr (Messwert);
end;

Auszug aus dem Beispiel Max186a.pas

Diese saubere Lösung wurde nun auch in das Programm SeraiUSB eingebaut. Auf der Seite von H.-J. Berndt kann das neue Programm geladen werden: http://www.hjberndt.de/soft/seraiusb.html


Frage: Warum werden bei einigen Beispielen zum I2C-Bus im Buch nach dem letzten Bit noch weitere SCL-Siganle erzeugt?

Antwort: (Dank an Karsten Böhme!) Das Problem lag bei der Stopkondition. Das Stopbit im Kontrollregister muss vor dem Lesen des letzten Bytes gesetzt werden. Will man nur ein Byte lesen, muss der Ablauf folgender sein :

Bei mehr als einem Byte muss vor dem Lesen des vorletzten Bytes LastRead, und vor dem Lesen des letzten Bytes Stop gesetzt werden.


Frage: Windows erkennt mein USB-Gerät nicht, es gibt keine Reaktion. Wo könnte der Fehler liegen?

Antwort: Wenn nicht einmal die Windows-Sanduhr erscheint, liegt der Fehler wahrscheinlich noch vor dem Prozessor am USB-Anschluss. Dort muss ein Widerstand von 1,5 k die Leitung D- (für Lowspeed) oder D+ (für Fullspeed) gegen Vcc ziehen. Nur daran erkennt der PC, dass ein Gerät angeschlossen wurde.


Frage: Warum gibt es mit den VB-Beispielen Probleme unter Windows 2000 ?

Antwort von Dr.Igor Holländer: Bei der Deklaration von CreateFile muss unbedingt ein ByVal Modifikator vor dem Parameter lpSecurityAttributes stehen, und dann kann es auch weiterhin als long deklariert werden. Die Deklaration von CreateFile muss so ausschauen:

Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long

und die Aufrufe so:

DeviceHandle = CreateFile("\\.\CompuLABusb_0", GENERIC_WRITE, _
FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)


Probleme mit den Delphi-Beispielen: Unter Win2000/XP kam es teilweise zu Fehlern. Das Kernproblem lag genau wie beim VB-Beispiel oben in der fehlerhaften Übergabe von TemplateHandle in der Funktion CreateFile. Der letzte Parameter ist jetzt Null. Der Fehler blieb lange unentdeckt, weil er sich unter Win98/ME nicht und unter 2000/XP nur bei einigen PCs auswirkt.

Lösung: Das folgende Beispiel zeigt die korrekte Ansteuerung des CompuLAB-USB. Zusätzlich wurde auch die Fehlerbehandlung verbessert. Der Fehler steckte auch in der Unit EZUSB.PAS, die nun ebenfalls berichtigt wurde.

  bresult := false;
  DeviceHandle := CreateFile ('\\.\CompuLABusb_0',Generic_write,File_Share_write,nil,open_existing,0,0);
  if (DeviceHandle <> INVALID_HANDLE_VALUE) then begin
     bResult := DeviceIoControl(DeviceHandle,$08,@lIn,sizeof(lIn),@lOut,sizeof (lOut),nBytes,nil);
     CloseHandle (DeviceHandle);
  end;
  if bResult then begin
    Din := lOut.bValue1;
    AnA := (4*lOut.bValue2+ (lOut.bValue4 and 15))/1023*5;
    AnB := (4*lOut.bValue3+ (lOut.bValue4 div 16))/1023*5;
  end;

Download des Delphi-Projekts CompUSB1 (compusb1.zip, 8KB)
Download der Unit EXZUSB.PAS (ezusb.zip, 2 KB)