Forum: Projekte & Code USB-Stick am Mikrocontroller VNC1L


von Matthias K. (matthiask)


Lesenswert?

Ich habe in die Artikelsammlung einen Beitrag dazu eingestellt.
http://www.mikrocontroller.net/articles/USB-Stick_am_Mikrocontroller

Dort steht auch der vollständige Quelltext zum Download bereit.

Kurze Zusammenfassung:

Eingesetzt wird ein USB-Hostcontroller, Typ VNC1L-1A von Vinculum/FTDI 
auf einem VDIP1-Modul. Firmware ist VDAP. Das Testprogramm ist in Ansi-C 
geschrieben, getestet einem auf 8051-System, sollte leicht auch auf 
andere Mikrocontrollerfamilen protierbar sein.

Kommunikation erfolgt über SPI-Interface, damit behält man sich die 
wertvolle µC-UART für andere Anwendungen frei.

Alle Funktionen können bei Bedarf auf einem LC-Display verfolgt werden.

Die Software bietet alle Grundfunktionen, wie elementare SPI 
I/O-Routinen, Initialisierungen und das lesen & schreiben von Dateien 
auf den USB-Stick.

Sicher gibt es noch Verbesserungsvorschläge, über die ich dankbar wäre.

von K. J. (Gast)


Lesenswert?

Hi haste ne Bezugsquelle für den Chip ?

bei Reichelt kostet das teil 19eur :P

Ansonsten saubere Arbeit.

von EF (Gast)


Lesenswert?


von SMD-Hasser (Gast)


Lesenswert?

Können die den Controller nicht in DIL anbieten? Dieser SMD-Quatsch ist 
einfach nicht mit Lochraster kompatibel...

von Micha (Gast)


Lesenswert?

@ Matthias K.
Wie lange dauert es etwa bis ein Befehl ("VF") ausgeführt wurde?

Da ich hin und wieder mp3-Files mit einer längeren Laufzeit (>45min)
habe, ist es natürlich recht umständlich in 5-Sekunden-Schritten bis zur
38. Minute zu "spulen" - deswegen die Frage.

von Matthias K. (matthiask)


Lesenswert?

>Wie lange dauert es etwa bis ein Befehl ("VF") ausgeführt wurde?

VF ist kein Kommando der VDAP-Firmware. Dazu müsste man auf dem VNC1L 
erstmal die VMSC Firmware flashen. Bisher habe ich mich nur mit VDAP 
beschäftigt. Es gibt aber auch fertige Module mit VMSC und MP3 
Decoderchip, VMUSIC siehe hier: http://www.vinculum.com/prd_vmusic1.html

von Micha (Gast)


Lesenswert?

> VF ist kein Kommando der VDAP-Firmware.
Stimmt. Hatte ich nicht bedacht - sorry!

> Es gibt aber auch fertige Module mit VMSC und MP3 Decoderchip
Das weiß ich. Mich hätte nur vorab interessiert wie lange es dauert 
einen Befehl auszuführen. Ggf. kommt diese Lösung dann nämlich nicht für 
mich in Frage.

Danke trotzdem!

von VDIP1 (Gast)


Lesenswert?

Hi,

wie machst du das eigentlich mit der Initialisierung des VDIP1?
So wie ich das verstanden habe, brauchst das Modul ja einige Zeit bis es 
den angesteckten USB Stick kennt(blinken der LED).
Sendest du während des Erkennung des Sticks schon Daten?

von Matthias K. (matthiask)


Lesenswert?

VDIP1 wrote:
> wie machst du das eigentlich mit der Initialisierung des VDIP1?
> So wie ich das verstanden habe, brauchst das Modul ja einige Zeit bis es
> den angesteckten USB Stick kennt(blinken der LED).
> Sendest du während des Erkennung des Sticks schon Daten?

Nach dem Einschalten bzw. einem Hardware-RESET meldet sich das Mdoul mit 
der Firmware-Versions-Nr. und wartet auf das anstecken des Sticks oder 
falls er bereits angesteckt war, beginnt automatisch die 
Initialisierung. Wenn alles Ok, wird "Device Detect P2" gemeldet und das 
Prompt "D:\>" wird gesendet. Dieses Promt als Zeichekette mußt Du 
erwarten, dann ist das ganze System betriebsbereit. Siehe dazu das 
Video.

von VDIP1 (Gast)


Lesenswert?

Danke, alles klar.

Ich hab bei meiner UART Routine nicht auf das Prompt nach dem 
Initialisieren gewartet, sondern sende gleich Befehle an das VDIP1 
Modul. Ich glaub das könnte das Problem sein...

von Andreas H. (dropkickmonkey)


Lesenswert?

Hallo,

ich bin neu in der Mikrocontrollerprogrammierung und würde deine 
Schaltung gerne dazu benutzen um einen Datenlogger zu bauen. Das Board 
ist soweit fertig. Den Kern bildet ein Atmega16L, der über SPI mit dem 
VNC1L kommunizieren soll.

Was sind denn die spezifischen Änderungen im Quelltext die vornehmen 
muss, damit erstmal dein Testprogramm laufen würde?

Viele Grüße

Andi

von Frank B. (frankman)


Lesenswert?

SMD-Hasser schrieb:
> Können die den Controller nicht in DIL anbieten? Dieser SMD-Quatsch ist
> einfach nicht mit Lochraster kompatibel...

Werde doch Bäcker!

von Hannibal (Gast)


Lesenswert?

Hallo.


Ich hab das Programm soweit auf meinem AT89C51RE2 laufen. Ich kann 
Dateien erstellen und Befehle senden usw, aber wenn ich was an eine 
vorhandene Datei anhängen will stürtzt das Ding ab. Ich hab schon 
versucht mit dem SEK-Befehl den Pointer von Hand an die richtige 
Position zu bringen, aber das war nciht erfolgreich. Laut Datenblatt 
reichts ja eigentlich wenn man den SEK-befehl ganz weglässt und so die 
letze Position im datei-pointer steht. Ich hab immo keine Ahnung mehr 
woran das liegen könnte.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

K. J. schrieb:
> Hi haste ne Bezugsquelle für den Chip ?

Gibbet auch bei Reichelt.

von Bernd (Gast)


Lesenswert?

(Nicht SMD-Hasser...)
Frank B. (frankman) schrieb:
>SMD-Hasser schrieb:
>> Können die den Controller nicht in DIL anbieten? Dieser SMD-Quatsch ist
>> einfach nicht mit Lochraster kompatibel...
>Werde doch Bäcker!

Was hatn das damit zu tun?
Er kritisiert einfach nur das die Hersteller nicht an die Bastler 
denken.

von Alex H. (hoal) Benutzerseite


Lesenswert?

Bernd schrieb:
> Was hatn das damit zu tun?
> Er kritisiert einfach nur das die Hersteller nicht an die Bastler
> denken.

Ich glaube nicht, dass die Hersteller solcher Chips einen wesentlichen 
Umsatz mit Bastlern machen. Sieht man gerade daran, dass sie diesen 
Markt nicht bedienen.

Insofern hat der Bastler nunmal das Los gezogen, sich den Bedingungen 
anzupassen. Wenn man dazu SMD löten muss, sollte man es halt lernen. 
Ansonsten gibt es auch fertige Adapter. Die sind dann wieder kompatibel 
mit Lochraster.

von Matthias (Gast)


Lesenswert?

>> Können die den Controller nicht in DIL anbieten? Dieser SMD-Quatsch ist
>> einfach nicht mit Lochraster kompatibel...

Nimm z.B. VDIP1 im DIL-Raster, ist sofort betriebsbereit, Bezug u.a. 
hier: http://www.watterott.com/VDIP1

von Matthias (Gast)


Lesenswert?

Christian M. schrieb in e-mail:

>Ich habe deinen Quelltext benutzt, um einen Vdrive anzusteuern. Dabei
>stellt sich das Problem,dass er zwar die Datei erstellt und füllt,wenn
>ich aber nur Daten anhängen will bleibt er "hängen" und reagiert nicht
>mehr.
>Ich habe schon versucht nach dem erstellen einen neustart des Modules zu
>machen, das hat aber zu keinem Erfolg geführt.
>Vielleicht weisst du da was, denke es gibt da noch irgendwas, worauf man
>achten muss, oder was man zusätzlich machen muss. Das Datenblatt ist da
>recht ungenau. Im Troubleshootig schreiben sie dazu nur,dass die Länge
>der Daten nicht stimmen würde, und er sich deshalb blockieren würde.

Ich antworte mal hier.

Das mit der exakten Anzahl der Byte beim schreiben ist ein Knackpunkt. 
Die Anzahl muss genau stimmen, sonst gibs Probleme. Timeout oder sowas 
kommt im Fehlerfall nicht. Probier doch mal, die Anzahl testweise als 
feste Zahl vorzugeben und nicht berechnen zu lassen.

Mit VDRIVE habe ich es allerdings nicht probiert.

von Matthias (Gast)


Lesenswert?

Habe mir das APPEND-Problem nochmal angesehen und denke das Problem 
gefunden zu haben. Ohne den "SEK" Befehl wurde vergeblich auf das PROMPT 
gewartet. Probier es mal hiermit:
1
// ***********************************************************************
2
// VNC1L - Erzeugen eines Text-Files auf dem USB-Stick
3
// Übergabe: filename   : Adresse des Filenamen
4
//           fileinhalt : Adresse des Textblockes
5
//           funktion   : File 0=Neu oder 1=Inhalt anhängen
6
// ***********************************************************************
7
void vnc_wr_txtfile(byte *filename, byte *fileinhalt, byte funktion) {
8
word vnc_i;
9
word filelen, filecr;
10
byte *fileptr;
11
byte batch_wr = 0;
12
  // Byte-Anzahl berechnen
13
  fileptr = fileinhalt;
14
  filelen = 0;
15
  filecr  = 0;
16
  while (*fileptr != 0xFF) {
17
    if (*fileptr) filelen++; else filecr++;
18
    fileptr++;
19
  }
20
  // 1. Promptzeichen liegt bereits vor
21
  do {
22
    switch (batch_wr) { // Batchprozess
23
      case 0:  // File Öffnen bzw. Erstellen
24
               sprintf (&vnc.send_buffer[0],"OPW %s",filename);
25
               vnc_wr_cmd(vnc.send_buffer);
26
               break;
27
      case 1:  // File Position bei Bedarf auf Anfang setzen
28
               if (!funktion) {
29
                 vnc_wr_cmd("SEK 0");
30
                 break;
31
               } else batch_wr++;  // Nun wird sofort auch noch case 2: ausgeführt
32
      case 2:  // File Byteanzahl
33
               sprintf (&vnc.send_buffer[0],"WRF %d",filelen);
34
               vnc_wr_cmd(vnc.send_buffer);
35
               fileptr = fileinhalt;
36
               for(vnc_i = 0; vnc_i < (filelen + filecr); vnc_i++) {
37
                 if (*fileptr) vnc_wr_byte(*fileptr); // NULL-Terminierung ausblenden
38
                 fileptr++;
39
               }
40
               break;
41
      case 3:  // File schließen
42
               sprintf (&vnc.send_buffer[0],"CLF %s",filename);
43
               vnc_wr_cmd(vnc.send_buffer);
44
               break;
45
    } // Switch
46
    delay_ms(500); // Pause
47
    batch_wr++;    // nächster Schritt
48
    if (batch_wr == 4) return; // Fertig
49
  } while (vnc_rd_answer(PROMPT_UND_ERROR_CHECK) == PROMPT_OK); // Prüfung auf nächstes Promptzeichen >
50
}
51
52
// Aufruf zB. mit:
53
vnc_wr_txtfile("VNCFILE1.TXT",file1[0],FILE_APPEND); // File Append

von Christian M. (christian_m)


Lesenswert?

Danke,werde es am Monatag gleich mal ausprobieren.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Ich nehme an, der ELV-Bausatz enthält ebenfalls den Vinculum:
http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=20659&flv=1&bereich=&marke=
USB-Stick-Interface STI 100, Komplettbausatz Artikel-Nr.: 68-759-50 
37,95€

von Matthias K. (matthiask)


Lesenswert?

>Ich nehme an, der ELV-Bausatz enthält ebenfalls den Vinculum:

ja, VNC1L

Schaltplan vom ELV_Modul konnte ich nicht finden. Sieht nach einem 
VDRIVE1 Nachbau aus: http://www.vinculum.com/prd_vdrive1.html (VDRIVE1 
ist praktisch kaum noch zu bekommen, nur als OEM). Firmware dürfte auch 
VDAP sein.

Bsp.-Software ist für UART-Nutzung geschrieben.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Ja ich habe die ELV 5/07 und 6/07, da ist auch das Schaltbild. VNC1L, 
3,3V- Spannungsregler  (Typ HT-7533, kenne ich nicht), 12MHz-Quarz, 
PTC-Sicherung in der 5V-Leitung von der USB-Buchse, zwei 22µH-Drosseln 
in derselben Leitung, drei LEDs und einige R und C, das ist alles. 
Programmierjumper,  Jumper UART/SPI und ein weiterer nicht näher 
genannter Jumper, der immer auf Vcc stehe sollte und gleichzeitig Pin 36 
und 45 des Vinculum versorgt.

von Christian M. (christian_m)


Lesenswert?

Wenn man "Case 1" aus deinem Quelltext herauskommentiert, dann 
funkioniert das Anhängen.
Haben es gerade ausprobiert.

von Matthias (Gast)


Lesenswert?

Bei mir läuft es so wie oben geschrieben.

von Nick O. (lpt)


Lesenswert?

Hallo

Ich hab mich auch mal an das Thema rangewagt.
Aber bei mir funktioniert es nicht.

Das Programm läuft nach einigen Versuchen jetzt soweit.
Aber auf dem USB-Stick wird keine Datei geschrieben.

Beim einschalten Blinken die beiden LED's auf dem VDIP1 Modul 2x 
abwechselnd.

Und danach nie wieder.
Sind das Date Sende und Empfangs "anzeigen" und kann ich davon ausgehen 
das dann keine Daten vom µC zum Modul gelangen?

würde mich über Infos freuen.

P.S. bei dem Musterprojekt würden die Original Pin's von der SPI 
Schnittelle genutzt.
Das ist doch sicher nur Zufall.
So wie ich den Code gelesen hab kann man die Kanäle jedem PIN zuordnen.
Oder liege ich da falsch?

mfg
LPT

von Nick O. (lpt)


Lesenswert?

Ach ja eine Frage hab ich noch!

Wieso eigentlich eine Virtuelle SPI Schnittstelle.
Kann man nicht eine (die) Normale Hardware- Schnittstelle nehmen?

mfg
LPT

von Matthias (Gast)


Lesenswert?

"Nicht vergessen, die Jumper J3 und J4 des VDIP1-Moduls auf SPI zu 
stecken!" Hast Du sicher gemacht?

Welchen µC hast Du verwendet?

Die SPI ist in Software realisiert, weil es ein spezielles Protokoll ist 
(13Bit), was mit den üblichen SPI-Verfahren nicht viel zu tun hat. Lässt 
sich nicht mit der Hardware-SPI realisieren, zumindest nicht beim 
AT89C51ED2. Die Pins kannst Du frei zuordnen.

von Nick O. (lpt)


Lesenswert?

Danke für die schnelle antwort.

Erst mal zu deiner Frage ich arbeite mit einem ATmega644.
Und die Jumper sind gesteckt.

Irgendwie war dein Programm bei mir nicht lauffähig.
Hab des hab einiges ändern müssen, wie zB. die Zuweisung zu dem Kanälen.
P1_1 geht bei mir nicht, bin jetzt bei
#define R_SCLK    PORTB &= ~(1<<PIN0)
#define S_SCLK    PORTB |=  (1<<PIN0)

und das für jeden Kanal.

Mit deinen Funktionsnamen kann ich nicht zurecht also auch dort mal 
etwas ins Deutsche übersetzt und die Gliederung etwas angepasste.
Klammern in neue Zeilen und so’n Zeug.
Damit ich es besser verstehe.

Das sollte aber eigentlich nicht das Problem sein.
Aber es passiert nix müssen den die LED's Blinken beim beschreiben?
Ich hab gerade mal mein Oszilloskop rangehalten.
Die gute Nachricht ist der Reset funktioniert offenbar.
Zumindest reagiert das VDIP auf mit einem Reset wenn ich an den Kanal 
komme.

Aber ansonsten hab ich keine Impulse auf den Leitungen.
Dafür aber 3V Gleichspannung.

Der AVR arbeite noch mit 1MHz Internem Takt aber das ist ja auch kein 
Problem bei einer SPI.

Mir gehen so einmählich die Ideen aus.

Kann vielleicht etwas kaputt sein?
Ich hatte erst die Kanäle 0-4 vom PortC verwendet.
Aber bei der Fehlersuche hab ich festgestellt das die Kanäle 2-5 nicht 
mehr reagieren.
Aber ich weiß nicht seit wann schon.

Ich hoffen mal das da nix am VDIP kaputt gegangen ist.
Vertaucht oder Verpolt hatte ich nix.

Jetzt hängt das Modul am PortB.

mfg
LPT

von Matthias (Gast)


Lesenswert?

>Erst mal zu deiner Frage ich arbeite mit einem ATmega644.

>Irgendwie war dein Programm bei mir nicht lauffähig.
>Hab des hab einiges ändern müssen, wie zB. die Zuweisung zu dem Kanälen.
>P1_1 geht bei mir nicht, bin jetzt bei
>#define R_SCLK    PORTB &= ~(1<<PIN0)
>#define S_SCLK    PORTB |=  (1<<PIN0)

Das C-Programm im Beitrag läuft auf einen 8051er. Der hat Bitbefehle, 
welcher der AVR nicht kennt. Musst es entsprechend anpassen, kein 
Problem, nur da kann ich Dir nicht gross helfen.

>Aber ansonsten hab ich keine Impulse auf den Leitungen.

Elementare Voraussetzung

VDIP ist recht robust, geht so schnell nicht kaputt.

von Nick O. (lpt)


Lesenswert?

Narbend

Eine Frage hab ich noch.

Diese sprintf Befehle sind doch sicher für das Display.
Oder irre ich mich da.
sprintf (&sende_buffer[0],"CLF %s",filename)

Ich werde daraus nicht so ganz schlau.
Einerseits sprintf was soweit ich weiß für Monitor Geschichten ist.
Und andererseits der Befehl CLF der für das VDIP1 Modul ist.

Vielleicht kannst Du mir das noch mal erklären?

mfg
LPT

von Matthias (Gast)


Lesenswert?

Das Projekt ist nicht als Einstieg geeignet. Du solltest erstmal mit den 
C-Grundlagen anfangen und Dir ein µC-Basiswissen aneignen.

Hier findest schon sehr viel (AVR Tutorial):
http://www.mikrocontroller.net/articles/Hauptseite

>sprintf (&sende_buffer[0],"CLF %s",filename)

Gibt nichts auf dem Display aus, sondern schreibt CLF und den Filenamen 
in den sende_buffer ab Position 0.

von Nick O. (lpt)


Lesenswert?

Hallo ich bin es noch mal.

Das mit dem C-Programmieren ist so eine Sache.
Ich hab es damals auf der PC (DOS) Ebene kennensgelernt ist aber noch 
nicht solange her.

Und meiner Meinung nach ist es auf der Objektorientierten Ebene etwas 
komplexer kommt mir zumindest so vor..

Aber Du hast recht und hätte ich mal im Buch nachgeschlagen und nicht 
auf mein alt"wissen" zurückgegriffen hätte ich auch rausgefunden.

Das mit dem von vorne anfangen und langsam rantasten mache ich ja schon 
seit ein paar Monaten, allerdings muss mein Projekt vorankommen (da der 
Abgabetermin steht) und dafür brauch ich nun mal das Modul.



Ich bin jetzt soweit das Datentransfer auf den Leitungen statt findet 
aber beim
Verbindung Prüfen [vnc_rd_answer()]

Bekomme ich als Rückgabewert im lese_buffer [vnc.rec_buffer[0]
immer 0x00 übergeben.

Und eine Fehlercode Tabelle finde ich im Datenblatt nicht.

Kannst Du mir da noch mal einen Tipp geben wie ich jetzt weiter komme.

Danke schon mal im Voraus.

mfg
LPT

von Matthias (Gast)


Lesenswert?

Zeigmal den Quellkode, möglichst komplett.

>Bekomme ich als Rückgabewert im lese_buffer [vnc.rec_buffer[0]
>immer 0x00 übergeben

Die SPI Kommunikation dürfte noch nicht richtig funktionieren, Du liest 
vermutlich noch nichts ein, deshalb 0x00

von Nick O. (lpt)


Angehängte Dateien:

Lesenswert?

Hab jetzt mal etwas Zeit zum Googlen gehabt.

Jetzt hab ich auch ein paar Kurzanleitungen auf Deutsch gefunden.
Und viele Unser die Viele Probleme damit haben.

Die Datei hab ich mal angehangen.
Ich hab dir mal schnell etliche rauskommentierte Versuche und LED 
anzeigen gelöscht ich hoffe das dabei keine Klammer zuviel weg ist.

Großen Dank schon mal für deine Hilfe.

mfg
LPT

von Matthias (Gast)


Lesenswert?

>#define SDO_VDIP   PINB &= ( 1<<PIN4)

Das dürfte so nicht funktionieren. Dein Programm ist außerdem für die 
Erstinbetriebnahme viel zu komplex. Versuch doch erstmal alles 
unwesentliche auszubauen und zunächst nur das was von VNC1L kommt zu 
empfangen. Der legt nach Reset sofort mit dem Senden von 
Statusinformationen los. Dieser Vorgang endet mit den Senden eines 
Prompt ('>') gefolgt von CR (0x0D). Erst danach kann die eigentliche 
Kommunikation beginnen. Also alle Byte empfangen und wenn ein > dabei 
ist, zB. eine LED anschalten.

Besser wäre es allerdings, wenn Du ein LCD, zumindest testweise mal 
anschliessen könntest.

von Matthias (Gast)


Lesenswert?

Hier ist noch ein interessantes Video zur Verdeutlichung der VNC1L 
Funktionsweise:
http://www.youtube.com/watch?v=r3fF48pI0Wo

Läuft hier zwar mit einen Terminalprogramm über UART, per SPI ist die 
Endfunktion aber gleich.

von Nick O. (lpt)


Lesenswert?

Matthias schrieb:
>>#define SDO_VDIP   PINB &= ( 1<<PIN4)
>
> Das dürfte so nicht funktionieren.

Danke für den Tipp ich hätte schwören können dass das so funktioniert.
Aber war auch das erste mal das ich über define auf Ein/Ausgänge zu 
greife.

Ich hab es jetzt über eine Funktion realisiert.
Jetzt hab ich auch Werte im Buffer.
So wie ich es auf den LED's gesehen hab sind es immer die gleichen 5Byte 
die empfangen werden.

Display wäre sicher schön aber ich muss (nee will es erst mal) so 
hinbekommen.
Keine Zeit und kein Geld für zusätzliche Experimente.
Aber vor allem halt keine Zeit.

Morgen bzw. Mi werde ich mal weiter suchen wo es jetzt hängt.
Weil eine Datei hab ich immer noch nicht auf dem Stick.

Bis dahin heißt es BWL büffeln.

mfg
Und Danke noch mal
LPT

von Matthias (Gast)


Lesenswert?

Hier ein absolutes Minimalprogramm zum testen der Kommunikation zwischen 
VNC1L und µC per SPI. Zur Signalisation reicht eine LED. Wenn diese etwa 
im Sekundentakt blinkt, ist alles ok. Details siehe im Programm.
1
//************************************************************************
2
// ATmega644 zu VDIP1 über SPI
3
//************************************************************************
4
5
// Das Programm testet die Kommunikation zwischen dem MC und dem VNC1L
6
// bzw. VDIP1-Modul per SPI-Schnittstelle. Dazu wird die Echo-Funktion
7
// benutzt. Ein E + CR wird zum VNC1L gesendet. Dieser sendet das 
8
// E + CR als Echo unmittelbar zurück.
9
// Zu Beginn wird die Bereitschaft des VNC1L abgewartet. Der sendet
10
// nach dem Reset einige Statusinformation zur geladenen Firmware und
11
// ob ein USB-Stick eingesteckt und erkannt wurde. Der Vorgang endet
12
// mit dem Senden eines > (Prompt) gefolgt von CR. Danach ist der
13
// VNC1L zur weiteren Kommunikation bereit.
14
// Hinweis: Es muss ein USB-Stick angesteckt sein!!!
15
// Wenn alles OK ist, sollte die LED nach ca. 5 Sekunden mit blinken,
16
// etwa im Sekundentakt beginnen.
17
18
#define F_CPU 1000000UL
19
#include <avr/io.h>
20
#include <string.h>          
21
#include <stdio.h>            
22
#include <stdlib.h>
23
#include <util/delay.h>
24
25
//************************************************************************
26
// Definebereich VDIP1
27
//************************************************************************
28
29
// Ports anpassen!!!!
30
31
#define R_SCLK    PORTB &= ~(1<<PIN6)   /* P1_6 */
32
#define S_SCLK    PORTB |=  (1<<PIN6)
33
34
#define R_SDI     PORTB &= ~(1<<PIN7)   /* P1_7 */
35
#define S_SDI     PORTB |=  (1<<PIN7)
36
37
#define SDO_VNC   (PINB & (1<<PIN5))   /* P1_5 zum einlesen */
38
39
#define R_CS_VNC  PORTB &= ~(1<<PIN0)    /* P1_0 */
40
#define S_CS_VNC  PORTB |=  (1<<PIN0)
41
42
#define R_RE_VNC PORTB &= ~(1<<PIN1)    /* P1_1 */
43
#define S_RE_VNC PORTB |=  (1<<PIN1)
44
45
#define R_LED_D1  PORTA &= ~(1<<PIN7)   /* P0_7 */
46
#define S_LED_D1  PORTA |=  (1<<PIN7)
47
48
#define PORT_DEFS DDRA = 0xFF; DDRB = 0xDF /* Ports anpassen!!!! */
49
50
// Typendefinition
51
typedef unsigned char byte;
52
typedef unsigned int  word;
53
typedef unsigned long dword;
54
55
// Variablenbereich
56
byte read_e, read_cr;
57
58
// ***********************************************************************
59
// VNC1L - USB HOST CONTROLLER - SPI-MODE (MC: Master, VNC1L: SLAVE)
60
// VDIP1: Jumper-Set: J3 - Pulldown / J4 - Pullup
61
//        VDAP Firmware muss installiert sein, mit Version 3.68 getestet
62
// ***********************************************************************
63
64
// ***********************************************************************
65
// VNC1L - Intialisierung SPI-Interface und VNC1L
66
// SPI Mode
67
// ***********************************************************************
68
void vnc_init(void) {
69
  R_CS_VNC;  // SPI-Interface inaktiv
70
  R_SCLK;    // Ruhezustand der SPI-Leitungen herstellen
71
  S_SDI;
72
  R_RE_VNC;  // Hardware-Reset VNC1L
73
  _delay_ms(100); // Pause
74
  S_RE_VNC;  // VNC1L starten
75
}
76
77
// ***********************************************************************
78
// VNC1L - Senden eines Zeichens
79
// SPI Mode
80
// Übergabe: wr_byte   : Auszugebendes Zeichen
81
// Rückgabe: statusbit : 0=Accept (ok) 1=Reject (nicht ok)
82
// ***********************************************************************
83
byte vnc_wr_byte(byte wr_byte) {
84
byte stelle, status;
85
  S_CS_VNC;        // SPI-Interface aktiv
86
  S_SDI;           // Startbit (immer 1)
87
  S_SCLK;  R_SCLK; // L/H Flanke
88
  R_SDI;           // RW-Bit (0=Write)
89
  S_SCLK;  R_SCLK; // L/H Flanke
90
  R_SDI;           // ADDR (0=Daten)
91
  S_SCLK;  R_SCLK; // L/H Flanke
92
  // 8 Datenbits senden (MSB zuerst)
93
  for ( stelle = 0x80; stelle; stelle >>= 1 ) {
94
    if (wr_byte & stelle) S_SDI; else R_SDI;
95
    S_SCLK;  R_SCLK; // L/H Flanke
96
  }
97
  // Statusbit einlesen
98
  status = SDO_VNC; // Statusbit (0=Accept, 1=Reject)
99
  // hier sollte jetzt Prüfung von status erfolgen!!!
100
  S_SCLK;  R_SCLK;  // L/H Flanke
101
  // End Sequenz
102
  R_CS_VNC;;        // SPI-Interface inaktiv
103
  S_SCLK;  R_SCLK;  // L/H Flanke
104
  _delay_ms(100); // Pause nur zum Test
105
  return status;
106
} 
107
108
// ***********************************************************************
109
// VNC1L - Empfangen eines Zeichens
110
// SPI Mode
111
// Rückgabe: Datenbyte
112
// ***********************************************************************
113
byte vnc_rd_byte(void) {
114
byte stelle, daten, status;
115
  daten  = 0;
116
  S_CS_VNC;        // SPI-Interface aktiv
117
  S_SDI;           // Startbit (immer 1)
118
  S_SCLK;  R_SCLK; // L/H Flanke
119
  S_SDI;           // RW-Bit (1=Read)
120
  S_SCLK;  R_SCLK; // L/H Flanke
121
  R_SDI;           // ADDR (0=Daten, 1=SPI-Statusinformation)
122
  S_SCLK;  R_SCLK; // L/H Flanke
123
  // 8 Datenbits empfangen (MSB zuerst)
124
  for ( stelle = 0x80; stelle; stelle >>= 1 ) {
125
    if (SDO_VNC) daten |= stelle;
126
    S_SCLK;  R_SCLK; // L/H Flanke
127
  }
128
  // Statusbit einlesen
129
  status = SDO_VNC; // Statusbit (0=New Data, 1=Old Data)
130
  // hier sollte jetzt Prüfung von status erfolgen!!!
131
  S_SCLK;  R_SCLK; // L/H Flanke
132
  // End Sequenz
133
  R_CS_VNC;        // SPI-Interface inaktiv
134
  S_SCLK;  R_SCLK; // L/H Flanke
135
  _delay_ms(100); // Pause nur zum Test
136
  return daten;
137
} 
138
139
// ********************************************************************
140
// Hauptprogramm
141
// ********************************************************************
142
int main (void) {
143
  PORT_DEFS;   // Portdefinition
144
  vnc_init();  // VNC1L-Initialisierung
145
  // VNC1L Bereitschaft abwarten indem auf > und CR geprüft wird 
146
  while(vnc_rd_byte() != '>');
147
  vnc_rd_byte(); // CR nach dem > jetzt noch abholen
148
  // VNC1L hat Promptzeichen > gesendet und kann jetzt neue Kommandos annehmen
149
  while(1) {
150
    S_LED_D1; // LED aus
151
    vnc_wr_byte('E'); // Echo senden
152
    vnc_wr_byte(0x0D); // CR senden
153
    _delay_ms(500); // Pause
154
    read_e  = vnc_rd_byte(); // Echo empfangen
155
    read_cr = vnc_rd_byte(); // CR empfangen
156
    if ((read_e == 'E') && (read_cr == 0x0D)) R_LED_D1; // LED ein wenn Echo empfangen wurde
157
    _delay_ms(1000); // Pause
158
  }
159
}

von Nick O. (lpt)


Lesenswert?

So jetzt hab ich wieder etwas Zeit zum weiter probieren.

Ich hab mit dem großem Programm weiter gearbeitet. Aber ich nehme jede 
Funktion einzeln in Betrieb.

Die Gute Nachricht ist ein Echo bekomme ich.
Ich kann Byte und Strings senden und das Daten empfangen und im Buffer 
ablegen funktioniert auch.

Aber Ein Echo bekomme ich nur wenn ich vorher am VDIP Modul ein Reste 
durchführe.
Und dann bekomme ich nur ein Echo ein mal zurück.

Anschließend bekomme ich nur die Meldung Modul Bereit
D:\>

Das ist doch sicher nicht normal oder?


mfg
LPT

von Keinen N. (mytss)


Lesenswert?

Ist es möglich an diesem Versuchsaufbau/ diesr Schaltung noch eine SD 
Karte anzusprechen ? Würde gerne Datein auf der SD Karte mit denen auf 
dem USB Stick vergleichen.

Bin noch Anfänger ^^.

Habe mich schon belesen nur ist mein Problem das die SD Karte und der 
USB Controller ja beide zB. MISO und MOSI benötigen.

Gibts nen Trick ?

Danke im Vorraus

von Matthias (Gast)


Lesenswert?

>Aber Ein Echo bekomme ich nur wenn ich vorher am VDIP Modul ein Reste
>durchführe. Und dann bekomme ich nur ein Echo ein mal zurück.

E(cho) senden und empfangen muss immer gehen, wenn der VNC Online ist, 
also ein Prompt > gesendet hat. Dann kann er wieder neue Kommandos 
aufnehmen. Siehe Bsp. davor, da läuft das Echo senden und empfangen auch 
in einer Endlosschleife, ohne Reset dazwischen.

Vermutlich stimmt Dein Timing oder die Sende-Empfangssequenzen noch 
nicht ganz.

von Nick O. (lpt)


Lesenswert?

So ich hab jetzt noch mal ein Neues Projekt geöffnet und dein 
"Kurzprogramm"
rein gespielt.

I/O Ports angepasst und für den SDO eine Funktion geschrieben damit ich 
nicht wieder das selbe Problem hab wie am Anfang.

Was soll ich sagen die LED Blinkt.

Das Programm hab ich schon so hingerückt das die Optik mir wieder etwas 
vertrauter vor kommt. Und es funktioniert immer noch. :-)

Jetzt werd ich mal die beiden Codes Parallel lesen.
Der Fehler muss doch zu finden sein.

Nochmals Danke für deine Geduld.

mfg
LPT

von Matthias (Gast)


Lesenswert?

>Habe mich schon belesen nur ist mein Problem das die SD Karte und der
>USB Controller ja beide zB. MISO und MOSI benötigen.
>Gibts nen Trick ?

Ist kein Problem. Du kannst die Portpins für den VDIP1 auch auf andere 
µC-Pins legen. Die SPI-Funktionen werden ohnehin per Software 
nachgebildet.
Damit hättest Du die Hardware-SPI frei für Deine SD-Card.

2. Variante: MISO/MOSI/SCK der SPI-Schnittstelle können auch an mehrere 
Teilnehmer parallel angeschlossen werden. Wichtig ist, dass dann immer 
nur ein Teilnehmer mit CS adressiert wird. Die anderen fühlen sich nicht 
angesprochen.

Bedenke noch, dass SD-Card keine 5V verträgt.

@lpt:
>Was soll ich sagen die LED Blinkt.
>Das Programm hab ich schon so hingerückt das die Optik mir wieder etwas
>vertrauter vor kommt. Und es funktioniert immer noch. :-)
>Jetzt werd ich mal die beiden Codes Parallel lesen.
>Der Fehler muss doch zu finden sein.

Dann kannste zumindest Hardwarefehler ausschliessen.

>while(antw = 1)

Kuck nochmal, ob Du dass schon in Deinem Ursprungsprogramm geändert 
hast, aus der Schleife kommst Du nie wieder raus! --> while(antw == 1)

von Nick O. (lpt)


Lesenswert?

Jetzt hab ich es fast geschafft.

Ich hab zwar keinen Fehler im Alten Code gefunden aber noch einigen 
Rückschlägen hab ich es geschafft aus dem keinem Programm was richtiges 
zu machen.

und anscheint sogar Fehlerfrei.

Bist Du dir Sicher mit dem
While (antw = 1)

Aus meiner Sicht wird der Variablen "antw" wenn man das so schreibt eine 
1 zugewiesen und das erbebt dann eine Endlosschleife.

mit dem antw == 1 funktioniert es auf jeden fall.

mfg
LPT

von Matthias (Gast)


Lesenswert?

>Bist Du dir Sicher mit dem
>While (antw = 1)

So gesehen ja. Das macht man dann besser so, ohne Variable zu opfern:
While (1) { ......  }

oder so wenn Abbruch irgendwann erforderlich ist:

antw = 1;
While (antw) {
  if (bedingung erfüllt) antw = 0; // dann wird Schleife beendet
}

von Nick O. (lpt)


Lesenswert?

Jetzt weiß ich erst was Du meinst.
Da haben wir wohl etwas an einander vorbei geschrieben.
Dabei meinten wir das gleiche.

Es ist Richtig das man eine Abfrage mit == schreibt
das mit dem „While (antw = 1)“ war wenn ich mich recht erinnere nur um 
besser die Signale mit dem Oszilloskop messen zu können.


Irgendwie hattest Du schon recht das Programm ist nicht für Anfänger.
Vom Prinzip her verstehe ich ja jede Zeile des Codes.

Bloß die Feinheiten scheine ich meistens zu übersehen.
Aber kaum hat man ein Problem gelöste tauchen 2 neue auf.

Ich hab es jetzt soweit das Strings gesendet werden können.
Die Funktion für Verbindung Prüfen ist OK hab’s sogar noch wegen der 
Echoprüfung erweitert.
Es wird auch das VDIP1 Modul erkennt die Befehle kommen durch und es 
wird auch eine Datei auf dem Stick angelegt

Allerdings werden keine Daten darin gespeichert.
Und das obwohl der µC etwa 10s braucht um den Befehl

Bin_Daten_Schreiben

Abzuarbeiten.
Ich dachte schon das ich die Zeiger falsch zuweise aber das müsste so 
stimmen.
Muss ich vielleicht von IPA auf IPH umschalten bevor ich Binäre Dateien 
beschreibe?
Aber so wie ich die Befehlsliste verstanden hab ist IPA und IPH für die 
Art der Befehls Sätze.

Außerdem hab ich noch ein paar Grundlegende Fragen.
Ich will eigentlich Zahlenwerte speichern und das ohne sie vorher in 
ASCII Zeichen zu wandeln.

Dafür bietet sich ja der Binäre Modus gerade zu an.
Aber die Datenmenge ändert sich je nach Laufzeit und Abtastrate.

Beim anlegen der Bin-Datei muss man aber eine Datenlänge angeben.
Ist das die Bytemenge der aktuellen Übertragung?
Oder die Absolute Menge?

Kann ich über "SEK x" an das Ende der Datei springen und jeder Zeit 
weitere Daten ranhängen.

Jeder Sektor ist dann wahrscheinlich 1Byte groß, dann braucht man nur 
mitzählen wie viele Daten man schon gesendet hat und die Zahl dann 
übergibt.

mfg
LPT

von Michael S. (Gast)


Lesenswert?

Hallo allerseits,

vor einiger Zeit habe ich mir Routinen für den VDIP geschrieben, die 
allerdings via RS232 zugreifen.
Die Entwicklung war mühsam, da nur sehr am Rande beschrieben wird, das 
die Angaben wie 115200 Baud und 12MHz SPI absolut nicht alltagstauglich 
sind.
Im praktischen Betrieb macht der VDIP bei mehr als 19200 Baud dicht.

Den Beitrag von Matthias vom 27.10. habe ich zum Anlass genommen, meine 
bislang nicht erfolgreichen Versuche, auf die SPI-Schnittstelle 
umzusteigen, noch einmal zu aktivieren.

Zwei Dinge - an denen ich gescheitert bin - sind mir aus dem Beispiel 
von Matthias als wichtig klar geworden:
1.) Bei Programmstart alle Daten bis zu einem RETURN verwerfen
  (das sind die Einschaltmeldungen etc.)
  Und dann für die Angst noch einmal 1 Sekunde alles einlesen.
  Dann mit einem Synch die Bereitschaft testen.
2.) Nach dem Senden eines Kommandos lange Pausen eingelegt.
  Dadurch blieb im Misserfolg erspart.

Denn ein Fehler steckt in den SPI-Routinen:
das Status-Flag wird nicht ausgewertet.
Werden Daten abgeholt - die aber noch nicht bereitstehen - dann ist 
Frust angesagt.
Ich habe die spi_write() und spi_read() so aufgebaut, dass sie je nach 
Erfolg TRUE oder FALSE zurückliefern.
Ein empfangenes Byte wird via globaler Variable übergeben.
Die Senderoutine hat eine eigene Schleife, die den Sendeversuch bei 
Misserfolg wiederholt.

Wenn man jetzt while (!(spi_read()); schreibt, hat man eine 
Warteschleife, die solange liest, bis wirklich Daten vom VDIP 
bereitgestellt sind.

Überhaupt erscheint es mir im Moment sinnvoll, den Datenfluss erst 
einmal mit geringer Geschwindigkeit in den Griff zu bekommen.

Bei mir gelingt es inzwischen, Verzeichnisse und Dateien anzulegen, zu 
löschen, Inhaltsverzeichnis bzw. Dateigröße auszulesen.

Allerdings scheitere ich noch daran, in eine geöffnete Datei zu 
schreiben (obwohl das via RS232 immer funktionierte).

Wenn ich die grundliegenden Funktionen fertig habe, werde ich den Code 
mal bereitstellen.

Ziel meiner Übung ist es übrigens, einen Datenlogger auf der Basis eines 
M88 zu bauen, der die Daten via RS232 und TWI entgegenehmen kann, in 
einem Ringpuffer speichert und in 512Byte Blöcken auf den Stick 
schreibt.

Michael S.

von Nick O. (lpt)


Lesenswert?

So ich glaub ich geb es für heute auf.
10 Stunden sollten reichen.
Und nix geschafft.

Die Datei die noch von ein paar Stunden erzeugt wurde und ohne Inhalt 
war, hatte die Endung .BIN .

Nach dem ich in der Funktion Verbindung Prüfen mit einer if abfrage 
rumgespielt habe hat die gleiche Datei plötzlich die Endung .BIS .

Änderung wieder zurück und Datei wieder .BIN .

Das ging dann ein paar mal hin und zurück weil ich die Funktion der 
Schleife irgendwie haben wollte.

Jetzt verzichte ich auf die if Abfrage.
Alles wieder original
Aber die Datei hat jetzt auch bei jedem erzeugen die Endung .BIS .

Ich glaub die der Controller hat was geben mich.
Ich sollte vielleicht lieber bei der Elektronik bleiben und mich von der 
Software fernhalten.
Auch wenn es jetzt dafür etwas zu spät ist.

mfg
LPT

von Nick O. (lpt)


Lesenswert?

Ich kann es doch nicht lassen.
Jetzt hab ich den Code Parel gelesen mit dem vom Backup das 4 Stunden 
älter ist einziger unterschied.

In der Aktuellen Version ist ein delay länger, die Kommentare sind 
anders
und die Funktion Test_file_schreiben gibt es noch nicht.

Alte Datei getestet alles OK
Aktuelle Datei getestet auch alles OK.
Hab es jetzt 3 mal durchlaufen lassen jedes mal gibt es keine Fehler.

Aber ich bekomme immer noch keine Daten in die Binäre Datei geschrieben.
und mit dem Text schreiben scheint auch noch was nicht zu stimmen.

@ Matthias
Hat es eigentlich einen Grund warum Du bei der Funktion
vnc_wr_txtfile
um den Befehl "strlen" einen riesen Bogen machst.
Und statt dessen mit filelen und filecr die Länge ermittelst?

mfg
LPT

von Matthias (Gast)


Lesenswert?

>Hat es eigentlich einen Grund warum Du bei der Funktion
>vnc_wr_txtfile
>um den Befehl "strlen" einen riesen Bogen machst.
>Und statt dessen mit filelen und filecr die Länge ermittelst?

C-Grundlagen!

Bei den Textdaten handelt es sich um ein Zeigerfeld. Jede einzelne 
Zeichenkette (Zeile) endet mit einen 0x00. strlen würde nicht die 
Gesamtlänge aller Zeichen liefern, sondern nur bis zur ersten 0x00.

Ich habe das Original-Programm vom 8051 nun auf einen ATmega laufen.
Txtfile, Binärfile Schreiben und lesen klappt soweit. An paar Details 
arbeite ich noch. Ich lade es vielleicht schon morgen hoch.

von Matthias K. (matthiask)


Lesenswert?

Den Beitrag in der Artikelsammlung habe ich überarbeitet und neue 
Software (siehe Projektarchiv bei Links/Download) hochgeladen.

http://www.mikrocontroller.net/articles/USB-Stick_am_Mikrocontroller

Neu ist jetzt eine AVR/GCC-Version.

Getestet mit einem ATmega644 (andere möglich), VDIP1 mit VDAP-Firmware 
3.68. Zum Betrieb kann optional ein LCD angeschlossen werden (zur 
Inbetriebnahme sehr zu empfehlen). Die Software zeigt die grundlegende 
Kommunikation mit dem VNC1L per SPI, schreibt ein Text-File sowie ein 
Binär-File auf den USB-Stick und zeigt wie ein File vom USB-Stick 
eingelesen werden kann.

Gegenüber der ursprünglichen Version (8051), sind in die AVR-Version 
einige Verbesserungen zur Stabilität und Erfahrungen aus der Diskussion 
eingeflossen. Die 8051er Version ist noch unverändert enthalten.

Der Schaltplan befindet sich auch auf der Artikelseite.

Weiterhin ist eine einfache Testsoftware für die Erstinbetriebnahme 
(AVR) enthalten. Dabei wird nur die elementare Kommunikation zwischen µC 
und VNC1L, durch E(cho)-Kommandos getestet. Das Programm sollte man zum 
Einstieg als Erstes verwenden. Danach kann man ziemlich sicher sein, 
dass der grundlegende Datenaustausch in Ordnung ist.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

wie ich sehe, seid ihr noch nicht viel weitergekommen.

Gestern hatte ich darauf hingewiesen, dass der VDIP krötenlangsam ist.
Wenn ihr meint, dass nach dem Schreiben eines Kommandos die Antwort 
bereits vorliegt, dann irrt ihr gewaltig.

Darum muss beim Lesen/Schreiben das Statusbit getestet werden.
Natürlich kann man statt dessen auch eine 500ms Pause einlegen.

Effizienter ist aber der andere Weg, nämlich zu prüfen, ob wirklich 
schon gültige Daten (beim Lesen) anliegen.

Ich füge einmal meine geringfügig geänderte Routinen zum Lesen und 
Schreiben via SPI bei.
Und die Initialisierung, in der man die Einschaltmeldung in einem
Puffer zwischenspeichert und als Textstring ausgeben kann.
Vielleicht hilft es ja weiter.
Mir hat zumindest euer Beitrag geholfen, den Knoten im Hirn zu 
zerschlagen.

Bei mir funktionieren jetzt alle Dateioperationen sowie Lesen und 
Schreiben von Daten.

Noch die Frage: Warum differenziert ihr zwischen Textdaten und 
Binärdaten ? Ist doch für den VDIP egal, was er speichert.

mfg

Michael S.

von Michael S. (Gast)


Lesenswert?

Hallo Matthias K.

eben habe ich mir dein aktuelles Projektarchiv noch einmal angesehen.
Weil mir nicht klar war, warum dein Code überhaupt funktionieren kann.

Und was sehe ich da ?
Überall _delay_ms(x).

Also hast du das Problem durchaus erkannt - aber durch Zeitverzögerungen 
gelöst.
Welche Datenübertragungsraten bleiben denn da am Ende übrig ?

Wirf mal alle delays raus (naja fast alle, Endlosschleifen soll man ja 
auch verhindern dürfen).
Statt dessen ändere deine SPI-Routine.

Und du wirst erstaunt sein, wie einfach das Leben sein kann.

mfg

Michael S.

von Matthias K. (matthiask)


Lesenswert?

>Gestern hatte ich darauf hingewiesen, dass der VDIP krötenlangsam ist.
>Wenn ihr meint, dass nach dem Schreiben eines Kommandos die Antwort
>bereits vorliegt, dann irrt ihr gewaltig.

Das ist bekannt, betrifft aber im wesentlichen nur die Antwort auf 
gesendete Kommandos. Beim senden von Daten kann man ihn flott 
beschicken. Hohe Erwartungen an den Datendurchsatz darf man bei diesen 
Verfahren insgesamt nicht stellen. Im Gegenzug sind keine Kenntnisse von 
FAT usw. nötig. Für Datenlogger-Aufgaben, oder Parameterübergaben ist es 
jedoch ausreichend.

>Überall _delay_ms(x).

Nur bei Kommandos. Das eigentliche Datensenden geht wie schon gesagt 
(fast) ohne delays. Ich schau mir Deine Routinen noch genauer an und 
versuche sie einzubauen. Die Timerverwendung gefällt mit nicht 
besonders, um es kompatibel für andere µC zu halten.

>Noch die Frage: Warum differenziert ihr zwischen Textdaten und
>Binärdaten ? Ist doch für den VDIP egal, was er speichert.

Dem VNC ist es egal. Es ist nur eine Handlingsache im Programm. Da gibt 
es sicher mehrere Lösungen. Meine ist nur ein Beispiel.

von Michael S. (Gast)


Lesenswert?

Hallo Matthias K.

deinen Programmcode habe ich mir noch ein weiters mal angesehen.

Es sind mehrere _delay_ms(100) vorhanden.
Die Verzögerungszeiten sind durch Ausprobieren entstanden.
Es besteht keine Garantie, dass die Zeiten immer ausreichen.
Als Ausgleich dafür werden sie in der Regel zu lang sein.

Während man die delays noch als Geschmacksfrage sehen mag,
ist das Fehlen einer Fehlerbehandlung beim Schreiben und Lesen via SPI 
schon bedenklich.
Eine leuchtende LED kann ja wohl noch nicht alles sein.

Im Manual wird empfohlen, die Statusbit zu prüfen und ggf. eine neues 
Senden/Schreiben zu initieren.
Kann ich auch nur empfehlen.
Dann kannst du deine delays ins Wochende schicken.
Und Lese-Schreib-Fehler werden auch abgefangen.

Aber du selbst wissen, was nach deiner Meinung der richtige Weg ist.
Der jetzige erscheint mir allerdings suboptimal.

Dennoch schönen Dank für deinen Beitrag, er hat mich weitergebracht.

mfg

Michael S.

von Matthias K. (matthiask)


Lesenswert?

http://www.mikrocontroller.net/articles/USB-Stick_am_Mikrocontroller

Ich habe jetzt auf Grund der Hinweise von Michael S. praktisch alle 
Delays eliminiert und komplett auf Abfrage der Statuszustände des VNC1L 
umgestellt. Hat sich wirklich gelohnt. Läuft jetzt noch schneller und 
stabiler. Danke nochmal für die Hinweise. Projektarchiv ist hochgeladen.

Details:

"SPI Master Status Read Transaction" wird vor jedem Schreiben abgefragt 
und das RXF# Bit ausgewertet.

Die Auswertung von TXE# hat nichts gebracht, hat offenbar gleiche 
Funktion, wie die Prüfung, dass der VNC1L neue Zeichen liefern kann. 
(Statusbit New/Old-Data)

Die Funktion von RXF IRQEn und TXE IRQEn im Statusbyte erschliesst sich 
mir bisher nicht. Datasheet macht keine Aussage dazu.

Alle Fehlerzustände werden jetzt von der untersten Ebene bis zum 
Hauptprogamm durchgereicht.

Timeouts eingeführt, der Stick könnte ja jederzeit raus gezogen werden.

Einige neue Funktionen, wie das warten auf bestimmte Meldungen sind neu.

von Nick O. (lpt)


Lesenswert?

Man da hab ich ja was losgetreten.

Aber ich sag schon mal Danke für die viele Mühe und Arbeit.

Ich freu mich schon mir das Programm anzusehen und auch auszuprobieren 
aber das muss noch bis Mittwoch warten.

mfg
LPT

von Michael S. (Gast)


Lesenswert?

Hallo Matthias K.

ich habe dein neues Programmm mal kurz überflogen, das sieht doch gleich 
wesentlich besser aus - damit wirst du eher zu Ziel kommen.

Was mir aufgefallen ist: du wertest das Status-BYTE aus.

Ehrlichgesagt ist mir der rechte Nutzen dieses Bytes nicht klar 
geworden.

Ich beschränke mich auf das Status-BIT in den Daten.
Ist es gesetzt, dann war's ein Schuss in den Ofen.
Also wird einfach wiederholt.
Solange, bis eine '0' zurückgeliefert wird.
Das spart das Einlesen eines Bytes (nämlich des Status-Bytes), das keine 
Daten transportiert.
Ausserdem muss man keinen Parameter übergeben.
Das spart Speicherplatz.

Noch ein Tip.
Es gibt einen SCS-Modus, in dem man den VDIP mit 'binären' Befehlen 
füttern kann. Auch die Antworten sind dann kompakter.
Und dadurch leichter auszuwerten.

Dass ich den VDIP neulich als "krötenlangsam" bezeichnet habe, möchte 
hier noch einmal relativieren. Die Antworten im SPI-Modus brauchen 
einige Zeit (die relativ länger scheint als im RS23-Modus).
Wenn man sich die Bitfolgen am logic-analyser im RS232-Modus ansieht, 
dann kommt die Antwort sofort (aber wir reden hier von Bitzeiten von 
100us).
Im SPI-Modus (Bitzeiten um 1us) kommt nach einem Kommando lange Zeit nur 
fehlerhafte Daten rein.
Und der Speicher des Analysers ist voll, bevor die gültige Anwort 
erscheint.
Ich hatte immer angenommen, dass irgendetwas in der Kommunikation nicht 
funktioniert.
Naja, nun habe ich es begriffen.
Mein Logger funktioniert inzwischen auch - und ist via SPI 'gefühlt' 
schneller als via RS232.

Übrigens hast du dein Testprogramm noch auf dem alten Stand.
Das (bzw. der Inhalt) mag potentielle Leser irritieren.

Zumal da noch ein kleines Missverständnis steckt:
_delay_ms() und _delay_us() haben Beschränkungen.
Im Manual zum WINAVR steht bei
_delay_ms() : max 262ms / F_CPU (in MHz)
_delay_us() : max 768us / F_CPU (in MHz)
Bei 10 MHz kann man also maximal 26ms Verzögerung erreichen.
_delay_ms(500) wird somit keine 500ms Wartezeit erreichen.

Viel Erfolg bei deinem weiteren Projekt.

Michael S.

von Matthias K. (matthiask)


Lesenswert?

>Was mir aufgefallen ist: du wertest das Status-BYTE aus.

Da sind 2 Bits zum VNC1L Status des FIFOs drin. Das Datenblatt ist dazu 
eine Katastrophe.

Wenn RXF# = 1 ist, ist der FIFO des VNC voll und kann keine Daten mehr 
annehmen. Abfrage hat sich bewährt, ich habe hier zum probieren u.a. 
eine alte Stickgurke, die extrem langsam ist beim schreiben. Legt schon 
nach 20 Byte eine Gedenksekunde ein. Zusätzliche Abfrage des Statusbits, 
ob dann das Byte akzepiert wurde, ist eine weitere Sicherheitsstufe.

Wenn TXE# = 1 liegt kein Byte zum abholen im FIFO bereit. Das glaube ich 
jetzt nach paar Tests verstanden zu haben. Ist noch nicht im Programm 
eingebaut, Funktion war mir lange unklar. Hier habe ich jedoch wenig 
bedenken, weil das Statusbit praktisch gleiche Info liefert (neues/altes 
Byte).

Beim Abholen des Status-Bytes ist übrigens das Status-Bit am Ende der 
SPI-Sequenz immer 0, also es ist immer gültig. Die Abfrage geht offenbar 
nicht über den FIFO und wird sofort bedient.

Ein knapper Hinweis findet sich im Datenblatt dazu beim Parallelmode, wo 
beide Signale auch hardwarmäßig zur Verfügung stehen.

>Es gibt einen SCS-Modus, in dem man den VDIP mit 'binären' Befehlen

Kenne ich, auch schon mal ausprobiert.

>Zumal da noch ein kleines Missverständnis steckt:
>_delay_ms() und _delay_us() haben Beschränkungen.
>Im Manual zum WINAVR steht bei
>_delay_ms() : max 262ms / F_CPU (in MHz)
>_delay_us() : max 768us / F_CPU (in MHz)
>Bei 10 MHz kann man also maximal 26ms Verzögerung erreichen.
>_delay_ms(500) wird somit keine 500ms Wartezeit erreichen.

Das war mal so:
Ab der avr-libc Versionen ab 1.6 geht es länger:
_delay_ms() 6553,5 ms
_delay_us() dito.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

>Viel Erfolg bei deinem weiteren Projekt.

Ebenfalls

von Nick O. (lpt)


Lesenswert?

> Wenn RXF# = 1 ist, ist der FIFO des VNC voll und kann keine Daten mehr
> annehmen. Abfrage hat sich bewährt ...


Hallo ich bin es noch mal.

Mein bzw. Dein Programm geht bei mir immer noch nicht.
Es entstehen wieder nur lehre Dateien auf dem USB-Stick.

Anschein ist der status in der Funktion "char vnc_wr_spi" immer 1
und somit nicht OK selbst wenn ich aus den 15µs Wartezeit 150ms mache 
ist der Fehler da und es entsteht ein überlauf.

Da ich Echos senden und Dateien anlegen kann muss das senden doch 
eigentlich richtig programmiert sein.
Kann es am dem Modul liegen?

Weiß einer woran es sonst noch liegen kann.
Ich will jetzt erst mal das Modul Updaten.

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

Hast Du Dir die letzte Version des Projektarchives runtergeladen?

Häng Dein gesamtes Projekt hier an, oder PM, dann lasse ich es bei mir 
mal laufen.

>Ich will jetzt erst mal das Modul Updaten.
Das ist wichtig, mit alten VDAP Version geht nicht alles.

von Korinthenkacker (Gast)


Lesenswert?

Wenn man den Befehl RD file absetzt ist nach genau 'nem kByte Schluß, 
der Promp-Check versagt. Any hints?

mfg

von Nick O. (lpt)


Lesenswert?

Hi Korinthenkacker

RD File absetzen???
Was meist Du mit absetzen??

RD ist doch der Befehl für Datei lesen aber das will ich ja nicht.
Dann gibt es noch RDF aber das ist Dateilänge zurückgeben.

Kannst Du mir das bitte noch mal erklären.

Der Testfile der in die Datei geschreiben werden soll ist 80Byt groß.
Also noch weit enfternt von dem kB

Oder meinst Du alle Bits und Byts die ich sende (also auch die Befehle 
das Ping und das je mit 13Bit?

@  Matthias ich hab dir mal ein Mail geschreiben.

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

@lpt:

Meine e-mail steht unten im Beitrag!

>RD file ...

Lese-Buffergröße im Programm angepasst?

von Korinthenkacker (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe mir aus dem Vorhandenen selber was zusammengeschustert, mein 
Monitoring läuft über die serielle Schnittstelle, über die ich auch 
Befehle absetzen kann. Laufen tut's auf 'nem MEGA32 mit 14.7456MHz, die 
Baudrate beträtg 38400 Baud und die Error-LED ist bei mir dummerweise 
von PB0 nach Masse geschaltet (im File natürlich geändert). Hab's mal 
angehängt.

mfg

von Matthias K. (matthiask)


Lesenswert?

> VNC1L_AVR_C-Projekt_uart.zip

Läuft bei mir auf Mega644.

Baudrate auf 2400 runtergesetzt, habe gerade keinen Baudratenquarz dran. 
So gehts auch mit den interen 1MHz.

Fehler wie Bad command werden noch nicht ausgewertet. Deshalb ist bei 
falschen Befehlen erstmal Schluß.

von Korinthenkacker (Gast)


Lesenswert?

Hab's "langsam" auch mal probiert, selbes Ergebnis, bei exakt 1 kByte 
ist Sense. Wie wird denn eigentlich eine Fehlermeldung erfolgreich 
abgefangen?
Wenn ich Mist schicke, nimmt der VDIP1 mir das sofort übel (zeigt keine 
Reaktion mehr). Egal, für heute ist Schluß!

Gute N8

von Matthias K. (matthiask)


Lesenswert?

@LPT:
Da passt einiges nicht:

>vdip1_init();
kannst Du nicht vor der PORT-Festlegung machen.

Ansonsten habe ich mal die LCD an Dein Programm angebunden.

Es wird was gesendet, auch Antworten kommen. Nur das Timing stimmt 
nicht. Nach ECS und IPA kommt kein prompt, erst irgendwann später 
dazwischen kommt dann mal ein promt durch. Aber inzwischen sendest Du 
immer weiter...

Kannst Du nicht wenigstens mal die UART nutzen, um alles zu Monitoren?

@Korinthenkacker
>Wie wird denn eigentlich eine Fehlermeldung erfolgreich
>abgefangen?

Das müsste in dieser Routine geschehen:
unsigned char vnc_rd_answer(unsigned char buffer_check) {
als weiterer Case-Zweig

Zur Zeit wird nur commad failed abgefangen.
Kann auch auf bad command und andere erweitert werden. -->demnächst 
geplant

von Nick O. (lpt)


Lesenswert?

Das mit dem anschissen von irgend einer Monitorring Gelegenheit wird 
schwierig.

Es Existiert noch kein Bord.
Im Augenblick ist der AVR auf dem STK500 und über fliegende Verdrahtung 
mit dem VDIP1 verbunden, der Provisorisch auf einer Lochrasterkarte 
stecket

Ist es vielleicht leichter das VDIP1 Modul über ein UART Verbindung 
anzusprechen?
Ich wollte sie mir eigentlich frei halten aber brauchen tue ich sie 
nicht.
Ich muss nur so schnell wie möglich Daten senden/schreiben können.

Bin so ein mählich nämlich etwas verzweifelt.
Vor allem da dein Programm bei mir auch nicht läuft und irgendwo min 3 
Fehler erkannt werden.

Übersichtlich ist es für mich erst wenn ich denn Code auflockere um zu 
sehen wo was anfängt und endet und selbst dann finde ich zu meinem 
Programm keinen Unterschied.
Das meiste ist eh nur kopiert.
Jetzt ist erst mal WE da komme ich leider nicht zum weiter arbeiten also 
geht es nächste Wochen für mich weiter.
Das Ding muss doch zu knacken sein.

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

>Das mit dem anschissen von irgend einer Monitorring Gelegenheit wird
>schwierig.

Serielle Schnittstelle kann nicht das Problem sein. Und ein 
Monitorprogamm auf dem PC auch nicht. Du hättest Dir viel Abeit ersparen 
können. So ein Programm kann man praktisch nicht ohne Hilfmittel 
erstellen, dazu ist der VNC zu komplex. Dazu kommt, dass man in C schon 
ziemlich fit sein sollte.

>Ist es vielleicht leichter das VDIP1 Modul über ein UART Verbindung
>anzusprechen?

Nicht wirklich. Die gesamte Datenauswertung, woran es bei Dir scheitert, 
bleibt gleich. Nur die Daten kommen auf andere Art und Weise in den 
Buffer.

>Ich muss nur so schnell wie möglich Daten senden/schreiben können.

Erwarte da nicht zu viel. Datenraten, wie auf den Stick, wenn er am PC 
hängt, sind nicht annährend nicht zu erwarten. Ein kleiner AVR8 kann 
auch garnicht so schnell die Daten liefern.

von Korinthenkacker (Gast)


Lesenswert?

Jetzt hab ich's:
1
...
2
unsigned int rd_answer_versuche = 1000; // TIMEOUT bis Fehler/Abbruch ggf. ANPASSEN!
3
  while(rd_answer_versuche) {
4
...
Naja, muß ich mal alles umfummeln.

mfg

von Matthias K. (matthiask)


Lesenswert?

Du solltest Dir mal die lezte Version des Projektarchives runterladen. 
Dort sind ua. die TIMEOUTS integriert. Ich bin gerade dabei, die 
Fehlermeldungen abzufangen. Lade es morgen hoch. Auch die 
USART-Funktionen als Monitoring sind dann drin.

von Matthias K. (matthiask)


Lesenswert?

http://www.mikrocontroller.net/articles/USB-Stick_...

Aktualisierte Version des Projektarchives ist hochgeladen.

Details:

Fehlerzustände werden jetzt weitgehend abgefangen.
1
// ***********************************************************************
2
// Fehlermeldungen
3
// ***********************************************************************
4
//  1  = Kommando wurde vom VNC1L nicht akzeptiert
5
//  2  = Command Failed
6
//  3  = Bad Command
7
//  4  = Disk Full
8
//  5  = Filename Invalid
9
//  6  = Read Only
10
//  7  = File Open
11
//  8  = Dir Not Empty
12
//  9  = No Disk
13
//  20  = kein VNC1L mit VDAP-Firmware vorhanden
14
//  21  = kein USB-Stick angesteckt
15
//  50  = Buffer zu klein zum Einlesen der Datei
16
//  51  = Dateilänge > 64kByte
17
//  99  = Timeout
18
// ***********************************************************************
Die Funktion endet zur Zeit erstmal in einer Fehlerroutine. Je nach 
Anwendungsfall muss entschieden werden, wie der Fehler zu behandeln ist 
(kehrt man zur Kommunikation zurück, oder doch lieber Reset 
durchführen?). Ob dies alle mögliche Fehlerzustände sind, wage ich nicht 
definitiv zu sagen. Sicher gibt es noch Zustände, die noch nicht erkannt 
werden. Auch konnte ich nicht alle provozieren.

UART-Monitoring ist jetzt als Option eingebaut. Sollte für die Testung 
unbedingt genutzt werden. (Eine "Fernbedienung" per UART ist nicht 
vorgesehen. Wer die VNC1L-Funktionen nur mal testen will, sollte das 
VDIP1 erstmal ohne µC direkt per UART (RS232-Treiber nicht vergessen) am 
PC+Terminalprogramm betreiben.)

Neue Routine: vnc_rd_dir(......)
Liest die Filelänge einer bestimmten Datei ein. Die Längenangabe wird 
vorab gebraucht, wenn die Datei später mit RD oder RDF eingelesen werden 
soll.

Weitere Änderungen zur Stabilitätsverbesserung.

von Matthias K. (matthiask)


Lesenswert?


von Nick O. (lpt)


Lesenswert?

> Es wird was gesendet, auch Antworten kommen. Nur das Timing stimmt
> nicht. Nach ECS und IPA kommt kein prompt, erst irgendwann später


Danke für die mühe.
Ich hab mich heut noch mal rangesetzt und nachgesehen.
Daraufhin hab ich in main statt nach jedem Befehl 1s zu warten, mal eine 
Überprüfung auf Promt ('>') eingefügt und schon hab ich Daten im meiner 
Datei. Und schneller geht es auch noch.

Allerdings in ASCII vorm und leider stimmen die nicht mit den Gesendeten 
Daten überein.
Allerdings stimmt schon mal die Anzahl.

Morgen geht es weiter N8

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

Warten/delays sind in den letzten Versionen nicht mehr nötig. Nimm 
möglichst die letzte Version von heute zur Orientierung. Läuft bei mir 
zumindest sehr stabil.

Prompt-Prüfung ist ein zentraler Punkt bei der gesamten Ansteuerung des 
VNC1L.

von Nick O. (lpt)


Lesenswert?

OK ich hab es soweit das die Daten auf dem USB abgelegt werden.
Und offenbar sogar richtig bloß der Texteditor interpretiert es 
wahrscheinlich falsch.

Die Zeichen 32 bis 126 aus der ASCII Tabelle (also alle Buchstaben die 
Zahlen und die gängigen Zeichen) werden richtig dargestellt.

Ich hatte eigentlich gedacht das die Binären Daten vom PC auch als Hex 
vom USB_Stick gelesen werden.

Aber anscheint hab ich mit dieser Annahme daneben gelegen.

Wie wertet ihr die Daten aus?
Auf eine Rechenintensive Wandlung von 8Bit auf ASCII Zahlen wollte ich 
mir eigentlich sparen um denn µC zu entlasten und so schneller Abtasten 
zu können.

Oder gibt es ein Programm das aus denn USB die Daten in Hex ausliest?

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

>Ich hatte eigentlich gedacht das die Binären Daten vom PC auch als Hex
>vom USB_Stick gelesen werden.

Der VNC schreibt die Daten 1:1, welche Du ihm anbietest. Unterschieden 
zwischen ASCII und Binär wird nicht. Das unterliegt der Interpretation 
Deiner Auswerte-Software. Jedes ASCII-Zeichen ist auch Binär oder als 
HEX anzeigbar.

>Die Zeichen 32 bis 126 aus der ASCII Tabelle (also alle Buchstaben die
>Zahlen und die gängigen Zeichen) werden richtig dargestellt.

Jeder Texteditor kann nur die ASCII-Zeichen darstellen. Wenn Du die 
dazugehörigen Hex-Werte sehen willst, bieten einige Editoren zB. die 
Ansicht als HEX.

von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Hallo an alle

ich hänge momentan auch an einem Datenlogger-Projekt mit dem VDIP1. Mein 
VDIP1 soll von einem NEC-V850 über SPI mit Daten versorgt werden, die 
dieser auf einen USB-Stick abspeichern soll.

Nachdem am Anfang nichtmal der USB-Stick erkannt wurde (trotz FAT32 und 
512 Byte Speichereinheiten) hab ich die Firmware von 3.66 auf 3.68 
geupdatet. Jetzt erkennt er den USB-Stick. Über meine Oszi kann ich auch 
die Daten, die der VDIP1 zu Beginn schickt (Versions Nr. / USB-Device an 
P2 detected etc...) auslesen und scheint zu funktionieren.

Mein Knackpunkt liegt aber beim Senden der Kommandos. Ich habe die 
Sende-Routine ( aus VDIP1 Datenblatt und auch aus dem VNC1L-Datenblatt) 
mit C nachgebildet und auf dem Oszi sieht sie auch -meiner Meinung nach- 
gut aus. Nur nimmt der VDIP1 die Kommandos nicht an (kein Blinken an LED 
2, keine Prompt-Antworten bei '\n', DIR, FWV etc.) Das einzige mal 
blinkt die LED 2, wenn vom VDIP beim Initialisiern der Disk "No Upgrade" 
gemeldet wird. Danach leuchtet die LED nur durch und bei Lese-Versuchen 
kommt immer nur 0x0D und Statusbit auf High (alte Daten).

Hat jemand eine Idee, woran es liegen könnte, dass meine Kommandos nicht 
angenommen werden?

Meine Clock-Zeiten liegen über 1 us, also zu schnell dürfte ich auch 
nicht senden (VDIP nimmt ja angeblich 12 MHz CLK-Signale an...)
Gesendet Wird in der Reihenfolge: "ECS" , "IPA" und dann "DIR", jeweils 
mit Lesezyklen dazwischen.

Hier ist mein Sendecode (noch ohne Status Überwachung, das führe ich 
noch per Oszi durch):
1
void WriteData(unsigned char wr_byte)
2
{
3
  unsigned char stelle, status;
4
    SPI_CLK_H;   /* 1. Bit */
5
    SPI_CLK_L;
6
    SPI_CS_H;
7
    SPI_MOSI_H;
8
  
9
    SPI_CLK_H;   /* 2. Bit */
10
    SPI_CLK_L;
11
    SPI_MOSI_L;
12
    
13
    SPI_CLK_H;   /* 3. Bit */
14
    SPI_CLK_L;
15
    
16
    SPI_CLK_H;   /* 4. Bit */
17
    SPI_CLK_L;
18
    
19
    for(stelle = 0x80 ; stelle ; stelle >>= 1)
20
    {
21
      /* 5. - 12. Bit */
22
      if(wr_byte & stelle)
23
      {
24
        SPI_MOSI_H;
25
      }
26
      else
27
      {
28
        SPI_MOSI_L;
29
      }
30
      SPI_CLK_H;   
31
      SPI_CLK_L;
32
    }
33
    
34
    SPI_MOSI_L;
35
    
36
    SPI_CLK_H; 
37
    SPI_CLK_L;
38
    SPI_CS_L;
39
  
40
    SPI_CLK_H;   /* 14. Bit halte CS Pegel low für 1 cycle */
41
    SPI_CLK_L;
42
}

Im Anhang befindet sich ein Oszibild eines gesendeten 'E' (ASCII: 0x45)
Zur Legende:
Blau:  MISO
Gelb:  Chip Select
Rot:   CLK
Grün:  MOSI
Zeit Division: 10 us

Danke schonmal für die Hilfe!

Gruß
Markus

von Markus (Gast)


Lesenswert?

Edit: Ein Edit Button wäre cool...

Ok, ich habe das Problem jetzt gefunden. Meine '\n' Zeichen nach den 
Einzel Commandos wurden falsch gesendet.
Schickt dem VDIP1 lieber direkt eine '13', dann passt das auch mit dem 
Return Zeichen!

So jetzt sitze ich gleich am nächsten Problem. Bei jedem Kommando (ECS, 
IPA bisher getestet) erhalte ich ein "Bad Command". Mal sehen was ich da 
noch so finde...

Gruß

von Matthias K. (matthiask)


Lesenswert?

>So jetzt sitze ich gleich am nächsten Problem. Bei jedem Kommando (ECS,
>IPA bisher getestet) erhalte ich ein "Bad Command". Mal sehen was ich da
>noch so finde...

Nach jedem Kommando unbedingt auf die Bestätigung des VNC1L warten 
(D:\>), meist Prompt_Check genannt. Erst dann kann er weitere Kommandos 
annehmen. Sendest Du vorher schon weitere Kommandos, kommt irgendwann 
ein 'Bad command'.

von Markus (Gast)


Lesenswert?

Hallo Matthias,

danke für die schnelle Antwort.

Mein Plan sieht augenblicklich so aus:
Ich schicke dem VDIP1 ein Kommando und gebe ihm dann direkt im Anschluss 
(nach kurzer Delay-Zeit) mit Read-Zyklen solange Gelegenheit zu 
antworten, bis das Status-Bit "Alte Daten" anzeigt.

Diese Antwort ist immer "Bad Command", obwohl weitere Kommandos erst 
danach übermittelt werden.

Einzige Ausnahme: ein Echo scheint er zu erkennen. Das Echo beantwortet 
er mit: E "Return" und dann nur noch "Alte Daten", also auch ohne Prompt 
Zeichen.

Kann es sein, dass ich zu kurz warte, bis ich mit den Read-Zyklen 
beginne?

Gruß
Markus

von Matthias K. (matthiask)


Lesenswert?

>Ich schicke dem VDIP1 ein Kommando und gebe ihm dann direkt im Anschluss
>(nach kurzer Delay-Zeit) mit Read-Zyklen solange Gelegenheit zu
>antworten, bis das Status-Bit "Alte Daten" anzeigt.

Er wird möglicherweise zunächst 'alte Zeichen' liefern, dann erst Neue. 
Lies doch einfach alle empfangenen 'neuen Zeichen' nach einem Kommando 
in einen Buffer ein und prüfen den Buffer auf "D:\>". Dann ist mit 
Sicherheit die Bestätigung der Kommandoannahme da. Allein auf die 
Abfrage alte/neue Zeichen würde ich mich nicht verlassen. Das passiert 
auch schon mal mitten in einer Antwort. Da würde Dir dann ein Teil zur 
Auswertung fehlen.

>Kann es sein, dass ich zu kurz warte, bis ich mit den Read-Zyklen beginne?

Du kannst ohne Delays sofort beginnen zu lesen. Nur Status-Bit und 
Status-Byte immer auswerten.

von Markus (Gast)


Lesenswert?

Ok. Dann optimiere ich mal meinen Code auf Prompt-Abwarten, Status-Bit- 
und Status-Byte-Auswertung.

Danke nochmals für deine Hilfe.

von Uwe J. (ohweee)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
ich versuche gerade den vdip1 in Betrieb zu nehmen und komme dabei nicht 
allzuweit. Ich habe ihn provisorisch verdrahtet und mich mit einem 
terminal programm mit ihm verbunden. soweit ich das verstehe, sollte ich 
nach dem einschalten ueber das terminal lesen koennen wer und was der 
controller ist und wenn er bereit ist, dann erscheint das D:\>
Komischer weise passiert genau das nicht (siehe Screenshot) und ich habe 
nicht wirklich eine idee woran es liegt. Ich kann ihn flashen via usb, 
das habe ich schon probiert. Hab die Uart Uebertragungsgeschwindigkeit 
veraendert. Das es funktioniert mache ich daran fest, dass die 
Empfangene Nachricht (egal wie unsinnig mir erscheint) die gleiche ist 
bei 4800 und 9600 (ohne und mit rts/cts)
hat vielleicht jemand eine idee woran es liegen koennte? Vielleicht ist 
das problem ja schon mal bei jemandem aufgetreten. ich bin nicth so 
super firm mit dem inbetriebnehmen solcher boards, somit koennte es halt 
auch ein voellig bescheuerter fehler sein :)
Uwe

von Matthias K. (matthiask)


Lesenswert?

Du hast foffentlich einen MAX232-Pegelwandler für TXD und RXD dazwischen 
geschaltet! Sonst dürfte das Teil kaputt sein.

Ansonsten lt. Datenblatt:

Baud rate (default =9600 baud), flow control settings (default = 
RTS/CTS), number of data bits (default=8), parity (default is no parity) 
and number of stop bits (default=1) are all configurable using the 
firmware command interface. Please refer to http://www.ftdichip.com (or 
latest version).

RTS-CTS (PIN9-PIN10) muss direkt am VDIP1 verbunden sein. Die beiden 
Jumper hast Du sicher auf UART gesteckt?

von Michael S. (Gast)


Lesenswert?

Hallo Uwe,

bei der seriellen Übertragung (ohne Handshake) den Pin CTS auf Masse 
ziehen,
Standardparameter 9600 Baud, keine Parität, 1 Stopbit.

Vielleicht hilft auch die Beschreibung zum Bausatz STI100 
(USB-Stick-Interface), hier ist der selbe Chip eingesetzt.

Michael S.

von Uwe J. (ohweee)


Lesenswert?

Jup! Ja der fehler lag natürlich im fehlenden max202.
hab jetzt halt den schritt übersprungen und den vdip1 driekt mit meinem 
µC verbunden. Dann stimmen die Pegel.
danke für die Hilfe.

von Matthias K. (matthiask)


Lesenswert?

>Jup! Ja der fehler lag natürlich im fehlenden max202.

Und er lebt noch?

von Uwe J. (ohweee)


Lesenswert?

Also, zumindest schickt er die nachrichten, die man erwartet. ich würde 
das als indiz sehen, dass es er noch funktioniert. Anfänger glück was :)

von Matthias K. (matthiask)


Lesenswert?

Einen gewissen Schutz haben die Eingäne offenbar. Sie sind ja auch 
5V-tolerant.

von Filth _. (filth)


Lesenswert?

Hallo,

vielleicht ist das der passende Thread für mein Problem.

Ich schreibe Daten auf das Interface, ohne Handshake.

Das wird vom µC gesendet:
1
<\r>
2
IPA<\r>
3
<\r>
4
OPW 666.txt<\r>
5
WRF 140<\r>
6
$GPRMC,000004.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*70^^$GPGGA,000005.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4B#^<\n>CLF 666.txt<\r>
7
<\r>
8
OPW 666.txt<\r>
9
WRF 140<\r>
10
$GPRMC,000006.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*72^^$GPGGA,000006.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*48#^<\n>CLF 666.txt<\r>
11
<\r>
12
OPW 666.txt<\r>
13
WRF 140<\r>
14
$GPRMC,000007.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*73^^$GPGGA,000007.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*49#^<\n>CLF 666.txt<\r>
15
<\r>
16
OPW 666.txt<\r>
17
WRF 140<\r>
18
$GPRMC,000008.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*7C^^$GPGGA,000008.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*46#^<\n>CLF 666.txt<\r>
19
<\r>
20
OPW 666.txt<\r>
21
WRF 140<\r>
22
$GPRMC,000009.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*7D^^$GPGGA,000009.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*47#^<\n>CLF 666.txt<\r>
23
<\r>
24
OPW 666.txt<\r>
25
WRF 140<\r>
26
$GPRMC,000010.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*75^^$GPGGA,000010.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4F#^<\n>CLF 666.txt<\r>
27
<\r>
28
OPW 666.txt<\r>
29
WRF 140<\r>
30
$GPRMC,000011.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*74^^$GPGGA,000011.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4E#^<\n>CLF 666.txt<\r>
31
<\r>
32
OPW 666.txt<\r>
33
WRF 140<\r>
34
$GPRMC,000012.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*77^^$GPGGA,000012.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4D#^<\n>CLF 666.txt<\r>
35
<\r>
36
OPW 666.txt<\r>
37
WRF 140<\r>
38
$GPRMC,000013.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*76^^$GPGGA,000013.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4C#^<\n>CLF 666.txt<\r>
39
<\r>
40
OPW 666.txt<\r>
41
WRF 140<\r>
42
$GPRMC,000014.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*71^^$GPGGA,000014.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4B#^<\n>CLF 666.txt<\r>
43
<\0>

Aber auf dem Stick landet folgendes:
1
$GPRMC,000004.026,V,5122.9659,N,00656.9130,E,0.00,0.00,06GA,000005.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4B#^
2
CLF 666.txt
3
4
OPW $GPRMC,000006.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*72^^$GPGGA,000006.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*48#^
5
$GPRMC,000007.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*73^^$GPGGA,000007.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*49#^
6
$GPRMC,000008.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*7C^^$GPGGA,000008.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*46#^
7
$GPRMC,000009.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*7D^^$GPGGA,000009.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*47#^
8
$GPRMC,000010.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*75^^$GPGGA,000010.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4F#^
9
$GPRMC,000011.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*74^^$GPGGA,000011.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4E#^
10
$GPRMC,000012.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*77^^$GPGGA,000012.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*4D#^

Man sieht, dass der zu schreibende String nicht komplett ankommt und 
daher die folgenden Steuerbefehle als Teil vom Eingabestring angesehen 
werden.
Dieser Fehler tritt immer wieder auf, dazwischen sind korrekt 
geschriebene Blocks.

Betrieben wird das Ganze mit 9600 Baud.

Jemand eine Idee was es sein kann?

von Matthias K. (matthiask)


Lesenswert?

Ich habe es mir mal angesehen.

Im ersten Datenblock fehlt mittendrin ein Stück. Konkret: es werden die 
ersten 57 Byte korrekt geschrieben, dann fehlen 17 Byte und dann folgt 
der Rest. Da der VNC1L aber auf exakt 140 Byte wartet, interpretiert er 
natürlich nun alle weiteren Bytes nicht als Kommando, sondern Nutzdaten, 
bis die 140 erreicht wird.

Sieht nach einem Bufferüberlauf aus. Um das Problem einzugrenzen, 
erstmal versuchsweise nach jedem gesendeten Byte ein delay. Besser wäre 
gleich die Nutzung der Handshakesignale. RTS#/CTS# ist bei VDAP 
standardmäßig aktiviert. Möglicherweise tritt es auch nicht bei allen 
Sticks gleichermaßen auf.

Aus Erfahrung mit dem SPI-Interface weiss ich inzwischen, dass durchaus 
auch hier der Buffer, besonderes beim schreiben, relativ schnell voll 
wird und ohne diesbezügliche Prüfungen kommt es da auch zu 
Fehlfunktionen.

von Filth _. (filth)


Lesenswert?

Danke für die Antwort!

Die Daten werden mit etwa 1Hz an den STI gesendet, eigentlich ist es ja 
nicht besonders schnell. Ich benutze BASCOM, der Sendeteil sieht bei mir 
so aus:
1
' write given data to the usb device
2
Sub Writeusb(mydata As String)
3
   Length = Len(mydata)
4
   Writestring = "WRF " + Str(length)
5
6
   Print #2 , Chr(&H0d);
7
8
   Print #2 , "OPW myFile.txt";
9
   Print #2 , Chr(&H0d);
10
11
   Print #2 , Writestring;
12
   Print #2 , Chr(&H0d);
13
14
   Print #2 , Mydata;
15
16
   Print #2 , "CLF myFile.txt";
17
   Print #2 , Chr(&H0d);
18
End Sub

Ich habe gelesen, dass man nach jedem Befehl auf den Prompt warten 
sollte - ist vielleicht hier der Fehler?
Wie man hier sieht, sende ich den gesamten String auf einmal (Print #2 , 
Mydata;) und nicht Zeichen für Zeichen. Allerdings weiß ich auch nicht, 
wie Bascom das intern regelt.

Fragen:
- Ich sitze gerade nicht vor dem Aufbau, aber jetzt fällt mir auf, dass 
in der Schreibmethode meine Befehle ohne Delays hintereinander versendet 
werden. Ist evtl da schon der Fehler?
- Soll ich den String tatsächlich lieber Zeichen für Zeichen in einer 
Schleife senden?
- Wie hoch sollten die Delays zwischen den einzelnen Zeichen sein?
- Wie genau funktioniert der Handshake? Habe damit noch nie gearbeitet.
- Ich habe angenommen, dass 1Hz Schreibrate eigentlich recht 
unproblematisch ist, später sollte diese auf 5 oder 10Hz steigen. Wenn 
aber jetzt schon bei 1Hz Probleme auftreten, wird man dann überhaupt mit 
5Hz auf den Stick schreiben können?

von Matthias K. (matthiask)


Lesenswert?

>Ich habe gelesen, dass man nach jedem Befehl auf den Prompt warten
>sollte - ist vielleicht hier der Fehler?

Ja, nur so weist Du, dass der VNC wieder in der Lage ist neue Kommandos 
anzunehmen.

Mit 1Hz meist Du wohl die Frequenz, mit der Du die Subroutine 
aufrufst(?) Das eigentliche senden darin dürfte wesentlich schneller 
gehen. Auf eine bestimmte Geschwindigkeit kannst Du Dich nicht 
verlassen. Jeder Stick erreicht bauartbedingt unterschiedliche Zeiten. 
Also, nach jedem Befehl auf das Prompt prüfen, noch einen Timeout 
einbauen usw., dann holst Du das maximale raus.

Testweise erstmal jedes Byte einzeln senden und eine Pause ca. 1...10ms 
dazwischen.

Bascom halte ich nicht besonderes dafür geeignet, schon wegen der 
Tatsache, dass man nicht weiß, was die vordefinierten Funktionen 
überhaupt genau machen. Handshake-Nutzung dürfte damit auch ein Problem 
werden.

Hast Du RTS# und CTS# am VNC direkt miteinander verbunden?

von Filth _. (filth)


Lesenswert?

Matthias K. schrieb:
>
> Mit 1Hz meist Du wohl die Frequenz, mit der Du die Subroutine
> aufrufst(?)

Ja

> Also, nach jedem Befehl auf das Prompt prüfen, noch einen Timeout
> einbauen usw., dann holst Du das maximale raus.

Gibt es Erfahrungen, mit welcher Frequenz man eine solche Schreibroutine 
zuverlässig aufrufen könnte? Eigentlich wollte ich darauf hinaus alle 
250ms einen Datensatz von etwa 300 kb zu schreiben.

> Testweise erstmal jedes Byte einzeln senden und eine Pause ca. 1...10ms
> dazwischen.

Ok, werde das heute testen.

> Hast Du RTS# und CTS# am VNC direkt miteinander verbunden?

Nein, ich habe es wie im Datenblatt zum STI angegeben gemacht:

" Möchte man ohne Handshake auskommen oder ist ein Handshake
nicht möglich, kann der /CTS-Pin mit Masse verbunden
werden. "

Sollten RTS und CTS miteinander verbunden werden?

von Matthias K. (matthiask)


Lesenswert?

>Gibt es Erfahrungen, mit welcher Frequenz man eine solche Schreibroutine
>zuverlässig aufrufen könnte? Eigentlich wollte ich darauf hinaus alle
>250ms einen Datensatz von etwa 300 kb zu schreiben.

Das wird auf keinen Fall was. Rechne doch mal nach: Bei 9600Baud (Bit/s) 
schaffst Du den Overhead mit eingerechnet ca. 0.9kbyte je Sekunde zu 
übertragen. Wieviele Minuten Deine 300kb brauchen kannst Du Dir 
ausrechnen.

>Hast Du RTS# und CTS# am VNC direkt miteinander verbunden?
>Nein, ich habe es wie im Datenblatt zum STI angegeben gemacht:

Versuchsweise mal machen.
Besser beide Signale mit Portpins verbinden und auswerten/setzen.

von Filth _. (filth)


Lesenswert?

Sorry - ich habe mich vertippt.
Es sollte 300 Byte nicht nicht Kb heissen.

Die Baudrate würde ich dann auf 115.200 hochsetzen, wobei auch 9600 für 
die Datenmenge ausreichen sollten.

Werde heute abend also CTS und RTS miteinander verbinden. Den String 
Zeichen für Zeichen mit Delays senden.

Zwei abschliessende Fragen noch:
Ist die Auswertung der CTS / RTS Pins nicht äquivalent zum Warten auf 
den Prompt vom STI?
Verstehe ich das richtig, dass CTS auf 1 geht, wenn das STI bereit zum 
Empfangen ist?

von Matthias K. (matthiask)


Lesenswert?

>Ist die Auswertung der CTS / RTS Pins nicht äquivalent zum Warten auf
>den Prompt vom STI?

Nein, die RTS/CTS Auswertung ist einige Ebenen tiefer angesetzt und 
betrifft den internen Hardwarebuffer des VNC1L.

Die Funktionensweise von RTS/CTS findest Du im Internet oder hier:
http://www.mikrocontroller.net/articles/RS-232
beschrieben. Wahrscheinlich hält der VNC1L den RTS-Pin auf 0, wenn er 
weitere Daten annehmen kann. Das musst Du mit dem µC erfassen und wenn 
der RTS-Pin 1 wird entsprechend das Senden unterbrechen bis RTS wieder 0 
wird. (PS: Es könnte auch 1/0 sein, habe jetzt keine Zeit das Datenblatt 
genauer zu lesen;-) ) Eventuell musst Du es ausprobieren.

von Filth _. (filth)


Lesenswert?

So, ich habe alles mögliche getestet:

- Zuerst CTS und RTS direkt am STI miteinander verbunden --> kein Erfolg
- Daten in einer Schleife mit timeouts nach jedem Zeichen gesender --> 
kein Erfolg
- Nach jedem Befehl timeouts eingebaut --> kein Erfolg

Mir ist jedoch etwas aufgefallen:
Wenn ich meinen String, der geschrieben wird im Code statisch 
deklariere, tritt der Fehler nicht auf. Es gibt den Fehler nur, wenn der 
String vom UART0 kommt.

Hier der gesamte Code. Habe ich dort irgendwo einen Fehler, den ich 
nicht sehe?
1
$regfile = "m644pdef.dat"
2
$crystal = 16000000
3
$hwstack = 128
4
$swstack = 512
5
$framesize = 128
6
$baud = 9600
7
$baud1 = 9600
8
9
Open "COM2:" For Binary As #2
10
Config Serialin = Buffered , Size = 100 , Bytematch = 13
11
12
Declare Sub Serial0charmatch()
13
Declare Sub Clearvars()
14
Declare Sub Initsti()
15
Declare Sub Buildgpsstring()
16
Declare Sub Writeusb()
17
18
Dim Incoming_data As String * 100
19
Dim Gps_string As String * 200
20
Dim Mc As String * 100
21
Dim Ga As String * 100
22
Dim Writestring As String * 200
23
Dim Length As Integer
24
25
Call Initsti()
26
27
Enable Interrupts
28
29
Mc = ""
30
Ga = ""
31
32
Do
33
   If Mc <> "" And Ga <> "" Then
34
35
      ' write data to usb
36
      Call Writeusb()
37
38
      ' tidy up
39
      Call Clearvars()
40
   End If
41
Loop
42
End
43
44
45
'Daten vom Buffer auslesen
46
Sub Serial0charmatch()
47
   If Mc <> "" And Ga <> "" Then
48
      Return
49
   End If
50
51
   Input Incoming_data Noecho
52
53
   If Len(incoming_data) > 50 Then
54
55
      If Mid(incoming_data , 2 , 6) = "$GPRMC" And Mc = "" Then
56
         Mc = Incoming_data
57
      End If
58
59
      If Mid(incoming_data , 2 , 6) = "$GPGGA" And Ga = "" Then
60
         Ga = Incoming_data
61
      End If
62
   End If
63
   Return
64
End Sub
65
66
67
'STI Initialization
68
Sub Initsti()
69
   Wait 10
70
   Print #2 , Chr(&H0d);
71
   Print #2 , "IPA";
72
   Print #2 , Chr(&H0d);
73
   Wait 10
74
End Sub
75
76
77
' variablen leeren
78
Sub Clearvars()
79
   Mc = ""
80
   Ga = ""
81
   Incoming_data = ""
82
   Gps_string = ""
83
   Writestring = ""
84
End Sub
85
86
87
' create the cps writestring
88
Sub Buildgpsstring()
89
    Gps_string = Mc + "^"
90
    Gps_string = Gps_string + Ga
91
    Gps_string = Gps_string + Chr(&H0a)
92
End Sub
93
94
95
' write given data to the usb device
96
Sub Writeusb()
97
98
    ' wenn man das einkommentiert, funktioniert es.
99
    'Gps_string = "$GPRMC,000007.026,V,5122.9659,N,00656.9130,E,0.00,0.00,060180,,,N*73^^
100
$GPGGA,000007.026,5122.9659,N,00656.9130,E,0,0,,102.5,M,47.5,M,,*49#^"
101
102
   Disable Interrupts
103
   Length = 0
104
   Length = Len(gps_string)
105
   Writestring = "WRF " + Str(length)
106
107
   Print #2 , "OPW 1.txt";
108
   Print #2 , Chr(&H0d);
109
110
   Print #2 , Writestring;
111
   Print #2 , Chr(&H0d);
112
113
   Print #2 , Gps_string;
114
115
   Print #2 , "CLF 1.txt";
116
   Print #2 , Chr(&H0d);
117
118
   Enable Interrupts
119
End Sub

von Matthias K. (matthiask)


Lesenswert?

>Wenn ich meinen String, der geschrieben wird im Code statisch
>deklariere, tritt der Fehler nicht auf. Es gibt den Fehler nur, wenn der
>String vom UART0 kommt.

>Hier der gesamte Code. Habe ich dort irgendwo einen Fehler, den ich
>nicht sehe?

Das frag besser in einem Bascomforum. Ich verstehe zwar das Programm so 
ungefähr, aber Bascom hat zuviele unüberschaubare Funktionen, welche die 
Ursache sein könnten.

Soweit ich es Überblicke, schreibst Du nach wie vor einfach auf den 
VNC1L los, ohne auf Rückmeldungen, wie das Prompt oder Fehlermeldungen 
zu detektieren. Das wird so nichts.

Kuck Dir mal das Video an. Da siehest Du die Abläufe und die Antworten 
des VNC1L im Detail.
http://www.youtube.com/watch?v=r3fF48pI0Wo

von Filth _. (filth)


Lesenswert?

Ich denke ich habe den Fehler gefunden.
Verwende jetzt einen Handshake bzw. sende nur, wenn RTS vom STI auf 0 
ist und das Problem ist nicht mehr aufgetreten.

Mit der neuen Firmware fährt das Ding übrigens viel schneller hoch, da 
die Größe vom Stick nicht mehr ermittelt wird.

von Matthias K. (matthiask)


Lesenswert?

Schön dass es jetzt funktioniert. RTS hat demnach die oben vermutete 
Polarität.

Firmwareupdate sollte man unbedingt machen, meist haben die Module bei 
der Lieferung eine alte Version drauf.

von Josh (Gast)


Lesenswert?

hi,

ich habe mal eine Frage, die nicht unbedingt hiermit zu tun, die sich 
nur aus diesem Projekt ergeben hat. Es geht allgemein um C.

Die Testnachricht wird ja in eine Zeigerfeld geschrieben
1
char *file1[] =  {
2
  "USB-Stick am Mikrocontoller -\n\r",
3
    "Version: V1.24, Stand: 16.11.2009, Author: Matthias Kahnt\n\r",
4
  "Text-File 1 vom VNC1L/VDIP1 erzeugt!\n\n\r\a"};  // \a als File-Endekennung NEU

wenn ich das richtig verstehe, könnte man das zeigerfeld auch so 
schreiben
1
char file[];   //norales Array erstellen
2
*file[]=...    //in das eben erstellte Array schreiben
also, so, habe ich das bisher begriffen, ist ein zeigerfeld ein Array 
auf das gezeigt wird, oder? stehe gerade ein bischen aufn schlauch... 
mein Inhalt, der in der Textdatei stehen soll, den habe ich in einem 
normalen Array, ich weiß bekomme es aber echt nicht hin, diesen an 
file1[] zu übergeben, ich dachte es geht mit einer schleife bei der 
zeichen für zeichen übergeben wird, oder mit memcpy...

viell bin ich hier ja auch ganz falsch, aber vielleicht hat ja auch 
jemand einen kleinen typ ür mich, wie ich mein array inhalt in das 
zeigerfeld, bzw in die datei bekomm, dankeschön

von Matthias K. (matthiask)


Lesenswert?

So ähnlich ist die Binär-File-Variante organisiert. Diese kannst Du auch 
für Textfiles nehmen.

>char file[];   //norales Array erstellen
char*  myptr = file oder &file[0] liefert die Adresse des ersten 
Elementes des Arrays
file[0] = 'T'; schreibt T an die erste Stelle usw.
char myvar = file[0]; dto. auslesen

von Nick O. (lpt)


Lesenswert?

Hallo ich bin es mal wieder.

Mein VDIP1 arbeitet je seit einigen Monaten schon.
Und jetzt wo sich bei meinem Projekt dem Ende naht.
Wollte ich anfangen die Prozessorgeschwindigkeit erhöhen.

Atmel ON-Chip Takt mit 1MHz war ja zum Testen OK aber jetzt sollen es 
doch 12MHz sein.

Allerdings wird die Kommunikation mit dem VDIP1 immer langsamer je hör 
die Taktrate ist.
Bei 1MHz bekomme ich 14Datenpakete gesendet.
Bei 8MHz sind es noch 12 Datenpakete
Und bei 12MHz sind es nur noch 10Datenpakete.

Das kann doch nicht normal sein.

Und dann hab ich mal noch eine Frage zu denn Befehlen "CLS" und "SUD"
Also Datei schließen und VDIP1 deaktivieren.

Irgendwie will das bei mir nicht klappen, Das sind die einzigsten 
Befehle bei dennen ich eine Fehlermeldung bekomme.

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

Nick Olaus schrieb:
> Und dann hab ich mal noch eine Frage zu denn Befehlen "CLS" und "SUD"
> Also Datei schließen und VDIP1 deaktivieren.

Meinst Du "CLF <filename>"?

"SUD" geht nur, wenn das File vorher geschlossen wurde.

Was verstehst Du unter Datenpaketen konkret?

von Nick O. (lpt)


Lesenswert?

Ja, sorry natürlich CLF <dateiname>
Im Programm war es aber richtig geschrieben.

Die Datei zu erweitern geht und das mit Datei schließen ist der gleiche 
Programmablauf aber das geht nicht.


Datenpakete sind bei mir Messwerte die ich aufnehme und auf den 
USB-Stick schreibe.

Die Datenpakete waren bei mir immer gleich lang aber je schneller der 
Controller arbeitet desto länger ist der Zeitabstand zwischen 2 
Aufnahmephasen (in dieser Zeit wird der Stick beschrieben).

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

Bei 12Mhz Taktrate des µC kommst Du langsam in den Grenzbereich. Im 
Datenlatt ist für VNC1L SPI-Übertragung max. 12Mhz (SCLK Periode 83ns) 
angegeben. Da wirkt sich jedes nicht ganz korrekte Timing ungünstig aus.

von Nick O. (lpt)


Lesenswert?

Hallo Matthias

Danke für die antwort.
Aber bei mir ist es nicht nur bei 12MHz das er langsam wird.
Selbst bei 8MHz ist er langsamer als bei 1MHz.

mit welcher Frequenz betreibst Du denn deinen Prozessor?
Und wie lange dauert bei dir eine Übertragung von sagen wir mal 17Byte

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

Ich kann es erst bei Gelegenheit ausprobieren. Ich hatte mein aktuelles 
Testprogramm aber schon mit 18,432MHz laufen.

All zu großen Datendurchsatz kannst Du grundsätzlich nicht von dem 
Gesamtystem erwarten.

Kennst Du das Dokument:
http://www.vinculum.com/documents/appnotes/AN_112_VNC1L%20Data%20Transfer%20Speeds.pdf

von Nick O. (lpt)


Lesenswert?

Nein die Seite kannte ich noch nicht.

Aber hab ich das richtig gelesen die SPI Schnittstelle ist am 
langsamsten?

Mir war so als hätte ich irgendwo gelesen das die UART nicht besonders 
schnell ist und das es mit SPI besser bzw. schneller geht.

Wie ist das eigentlich, das beschreiben dauert doch gar nicht solange 
aber das aufrufen der Befehle und das warten bis das VDIP1 Modul bereit 
ist frisst soviel zeit.

Ist das richtig?
Weil dann übertrage ich nicht nach jedem Messintervall die Daten sondern 
Horte die erst mal auf dem Controller. Und schieb dann stoßweise gleich 
ein paar 100Byt mit einmal rüber.

mfg
LPT

von Matthias K. (matthiask)


Lesenswert?

SPI ist die langsamste Übertragungsvariante. Dafür bleibt die UART am µC 
für andere Dinge frei.

Der Preis der einfachen Kommunikation über Befehle ist die 
Geschwindigkeit. Du könnstest den VNC1L als USB-Host auch selber 
programmieren, nur das ist ein gewaltiger Aufwand, allein die 
FAT-Implementierung.

Blochweises schreiben ist auf jedem Fall eine günstige Variante.

von Nick O. (lpt)


Lesenswert?

Da hab ich also damals was falsch verstanden.

Aber Außer die Übertragungsgeschwindigkeit ist mein Hauptproblem 
eigentlich das ich denn Stick nicht sicher vom Gerät entfernen kann.
1
        sprintf (&sende_buffer[0],"CLF %s",*Dateiname);  // Datei schleißen
2
           if (vdip1_befehl_schreiben(sende_buffer))
3
          {                  // Fehler Überlauf, Komando 
4
            Stoerung = 1;            // wurde nicht angenommen
5
          }                    
6
    
7
        if (vdip1_befehl_schreiben("SUD"))    // VDIP1 Deaktivieren
8
          {
9
            Stoerung = 1;
10
          } 
11
        
12
        if (vdip1_pruefen(vdip1_fehl) == vdip1_ok);  // Prüfung auf VDIP1 Zustand   
13
          {                  // Befehl empfangen ???
14
            Stoerung = 1;          // Störung setzen
15
          }  
16
17
        if ( Stoerung == 1)
18
          {
19
            stoerung (Stoerung);      // Störung auswerten        
20
          }

Das sollte eigentlich funktionieren.
Bei Datei Anlegen oder Erweitern funktioniert es ja auch.

mfg
LPT

von Heiko_TA (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Allerseits,

ist ja schon ziemlich lang geworden, der Beitrag...

Ich betreibe den ELV-Bausatz STI100 an einem UART des ATMEGA644, am 
anderen hängt das Touch-Panel Kit 320-8 von Electronic Assembly. 
Funktioniert eigentlich super, mit mehreren Einschränkungen:
Da das Gerät mit einem Akku betrieben wird, wird es so gut wie nie 
ausgeschaltet. Deswegen passiert es hin und wieder, dass der USB-Stick 
erst dann initialisiert wird, wenn ich ihn eigentlich schon lesen 
möchte. Das ist nervig, weil jedesmal nach einem Firmwareupdate gesucht 
wird... Vielleicht weiß jemand, wie man das Suchen nach dem Update 
ausschalten kann.

Das eigentliche Lesen ist auch nichts kompliziertes: Eine Textdatei mit 
einer Liste von Artikelnummern und zugewiesenen Spezifikationsdaten. Im 
Moment mache ich es ganz simpel: Den Befehl RD + Dateiname an das VNC1L 
senden. Dann aus den empfangenen Daten die rauspicken, die ich brauche. 
Funktioniert eigentlich ganz gut, wenn nicht jedesmal die gesamte Datei 
gesendet werden würde. Die ist zwar nur ca. 20 kB groß, aber bis sie 
komplett bei 9600 Baud gesendet wurde, vergeht eben doch einige Zeit. 
Und in dieser Zeit ist das VNC1L "lahmgelegt".
Da die Daten zeilenweise, also pro Artikelnummer eine Zeile, in der 
Datei stehen, wäre es toll, wenn ich die Datei zeilenweise einlesen 
könnte. Wenn ich die richtige Zeile habe, okay...kein weiteres Lesen 
nötig. Hab aber leider noch nicht rausbekommen, wie das gehen könnte. 
Soweit ich das der ELV-Anleitung (Link unten) entnommen habe, gibt es 
noch den OPR in Verbindung mit RDF. Nur muß ich hier die Anzahl der zu 
lesenden Bytes angeben. Ich weiß nur leider vorher nicht, an welcher 
Stelle die gewünschte Artikelnummer steht... Möglicherweise könnte es 
mit SEK gehen. Also bspw. 50 Bytes lesen, mit SEK dann auf das 51. Byte 
einstellen und ggf. weiterlesen. Hat das vielleich schon jemand gemacht, 
oder eine andere Idee?

Da das mein erstes größeres Programm ist, bin ich natürlich auch für 
jeden anderen Tipp dankbar!!!

Viele Grüße
Heiko


http://www.elv-downloads.de/Assets/Produkte/8/857/85799/Downloads/85799_STI100_KM_um.pdf

von Vnc Tester (Gast)


Lesenswert?

Hi,

ich weiß der Thread ist ein wenig alt, brachte aber viele brauchbare 
Informationen zum vorschein.

Ich habe mich heute auch mal am VDip versucht.

Es klappt ansich auch alles recht gut. Ich habe allerdings ein paar 
Probleme bei der Auswertung der Daten bzw. Probleme beim Timing.

Setup:
Vdip <-> µC = Hardware Uart
Cts Vdip = Gnd
Rts Vdip = µC

Programmiert habe ich mi Bascom. Hier mal der Testcode:
1
Declare Sub Usb_init
2
Declare Sub Usb_wait
3
Declare Sub Usb_dir
4
Declare Sub Usb_open_file
5
6
$regfile = "m16def.dat"
7
$crystal = 16000000
8
$hwstack = 32
9
$swstack = 20
10
$framesize = 40
11
$baud = 9600
12
13
Config Porta = Output
14
Config Portb = Output
15
Config Portc = Output
16
Config Portd = Output
17
18
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
19
Open "COM1:" For Binary As #1
20
21
Open "comd.3:9600,8,n,1" For Output As #2
22
23
Config Pind.4 = Input
24
25
On Urxc Usbisr
26
Enable Urxc
27
Enable Interrupts
28
29
Dim I As Byte
30
Dim Daten As Byte
31
Dim Empfangen As String * 50
32
Dim Empf_array(15) As String * 50
33
Dim Empf_pointer As Byte
34
Dim Usb_found As Bit
35
Dim Usb_fin As Bit
36
Dim Eof_usb As Bit
37
Dim Command_set As String * 5
38
Dim Filename As String * 15
39
Dim Rts As Bit
40
41
Empfangen = ""
42
Command_set = ""
43
Usb_fin = 0
44
Filename = ""
45
Usb_found = 0
46
Empf_pointer = 0
47
Eof_usb = 0
48
49
Waitms 5000
50
51
Gosub Usb_init
52
53
Do
54
55
If Usb_found = 1 And Usb_fin = 0 Then
56
  Gosub Usb_dir
57
  Gosub Usb_open_file
58
  Usb_fin = 1
59
End If
60
61
If Eof_usb = 1 Then
62
  For I = 1 To 15
63
    If Empf_array(i) <> "" Then
64
      Print #2 , Empf_array(i)
65
    End If
66
    Empf_array(i) = ""
67
  Next I
68
  Eof_usb = 0
69
End If
70
71
Loop
72
73
End
74
75
'Empfangsroutine
76
77
Usbisr:
78
  Daten = Udr
79
80
  If Daten = 13 Or Daten = 10 Then                          'CR oder LF empfangen ?
81
82
    If Instr(empfangen , "Device Detected") <> 0 Then
83
      Usb_found = 1
84
      Usb_fin = 0
85
    End If
86
    If Instr(empfangen , "Device Removed") <> 0 Or Instr(empfangen , "No Device") <> 0 Then
87
      Usb_found = 0
88
    End If
89
90
    If Empfangen <> "" Then
91
      If Command_set = "DIR" Then
92
        Filename = Trim(empfangen)
93
      End If
94
      If Command_set = "RD" Then
95
        If Instr(empfangen , "[END]") = 0 Then
96
          Incr Empf_pointer
97
          Empf_array(empf_pointer) = Empfangen
98
        Else
99
          Empf_pointer = 0
100
          Eof_usb = 1
101
        End If
102
      End If
103
    End If
104
105
    Empfangen = ""
106
  Else
107
    Empfangen = Empfangen + Chr(daten)
108
  End If
109
Return
110
111
'Usb funstions
112
113
Usb_init:
114
  Gosub Usb_wait
115
  Command_set = "ECS"
116
  Print "ECS" ; Chr(13);
117
  Gosub Usb_wait
118
Return
119
120
Usb_dir:
121
  Gosub Usb_wait
122
  Command_set = "DIR"
123
  Print "DIR" ; Chr(13);
124
  Gosub Usb_wait
125
Return
126
127
Usb_open_file:
128
  Gosub Usb_wait
129
  Command_set = "RD"
130
  Print "RD TEST.txt" ; Chr(13);
131
  Gosub Usb_wait
132
Return
133
134
Usb_wait:
135
 While Rts <> 0                                             'Solange warten bis Usb Host bereit zum arbeiten ist
136
   Rts = Pind.4
137
 Wend
138
Return

Allerdings funktioniert das Auswerten der Usb_wait nicht. Oder anders 
gesagt die Commands werden alle nacheinander gefeuert, ohne zu warten ob 
der Vnc mit dem Senden der Antworten auf das letzte Command auch fertig 
ist. Das hat ein wildes Zerhacken der Antworten zur Folge.

Hat jemand eine Idee wie sich das auswerten lässt ?

von Uwe J. (ohweee)


Lesenswert?

Hi,
ich habe damals schlicht auf das ack des vnc gewartet. Er schickt am 
Ende immer 'D:>', werte also einfach den Empfangsstring aus. Ich habe 
sogar nur auf '>' gewartet. Besser ist natuerlich auf den gesamten 
String zu warten.
Nach dessen Empfang kann weiter gearbeitet werden.

von Michael S. (Gast)


Lesenswert?

@ VNC_tester,

immer dann, wenn Du etwas an den VDIP sendest, verarbeitet der die Daten 
oder das Kommando und sendet anschließend eine Rückmeldung.

Diese Rückmeldung musst du abwarten und analysieren.
(Analysieren deswegen, weil ja auch Fehlermeldungen kommen könnten).

Erst danach darfst Du die nächste Aktion starten.

Übrigens gibt es einen Modus, der sich - sofern ich es rechig erinnere - 
SCS (Short Command Set) nennt.
Hier sind die Dialoge wesentlich kompakter realisierbar (es müssen nur 2 
Zeichen und nicht ellenlange Strings verglichen werden).

mfg

Michael S.

von Vnc Tester (Gast)


Lesenswert?

Vielen Dank das auswerten funktioniert jetzt super wenn ich in der 
Usb_wait das "D:" als Acknowledge auswerte.

Zwei kleinere Fragen kamen mir allerdings gerade noch auf. In welcher 
Reihenfolge werden dir Datein per "Dir" aufgelistet ? Wird dort 
alphabetisch soriert ?

Zum was sendet der VNC1, wenn er gerade startet und kein Usb Stick 
angeschlossen ist ? Wird dann trotzdem ein "D:" gesendet ? Ich brauche 
noch irgendein Kriterium an dem ich festmachen kann, dass der Vnc mit 
seiner Initalisierung fertig ist um danach den entsprechenden select 
Command Mode Befehl senden zu können.

Gruß und Dank :)

von waldi (Gast)


Lesenswert?

Hallo, ich bin echt einsteiger auf dem Gebiet. Ich wollte dien Programm 
nutzen um Daten zu loggen. ich benutze einen AVR ATmega32 und AVR Studio 
5. Nun ist mir aufgefallen das du vnc2l_avr.c in VNC!L_AVR.c includierst 
ohne eine Header Datei zu packen...wenn ich das ganze kompilieren will, 
bekomme ich die fehlermeldung das vieles aus der vnc2l.c nicht 
deklariert sind. also ka was mache ich falsch? also eig habe ich das 
auch nur mit header-dateien kennen gelernt.
LG

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.