STM32 VCP über USB Problem

OP #3381254
Hallo Leute,

ich nutze das STM32 Discovery Board 
(http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/PF254044) um 
mir die Daten der darauf befindlichen Sensoren per User USB an den PC zu 
senden. Dafür habe ich das "VirtualComport_Loopback" Beispiel aus der 
STM32_USB-FS-Device_Lib_V4.0.0 auf meine Problemstellung adaptiert. 
Leider will der Code aber nicht wie gedacht funktionieren.

main:
1
int main(void)
2
{ 
3

4
    ...
5
    
6
    Gyro_Init(); // Gyro initialisieren
7
    Acc_Init(); // Acc initialisieren
8
    
9
    SysTick_init(); // Initialisiert die SysTicks
10
    fDt = FDT; // Timebase (CycleTime)
11
    
12
    while(1)
13
    {         
14
        if(sample)
15
        {
16
            GyroReadAngRate(raw_gyro); 
17
            AccReadData(raw_acc);
18
      
19
            if(bDeviceState == CONFIGURED)
20
            {
21
                //CDC_Send_DATA((unsigned char*)buffer, strlen(buffer));
22

23
                sprintf(buffer, "%+.2f,", raw_acc[0]);
24
                USB_SendData(buffer);
25

26
                sprintf(buffer, "%+.2f,", raw_acc[1]);
27
                USB_SendData(buffer);
28

29
                sprintf(buffer, "%+.2f\n\n", raw_acc[2]);
30
                USB_SendData(buffer);                
31
            }        
32
            
33
            sample = 0;
34
        }
35
    }
36
}

USB_SendData
1
void USB_SendData(char *data)
2
{ 
3
    if(packet_sent == 1)
4
    {
5
        CDC_Send_DATA((unsigned char*) data, strlen(data));    
6
    }
7
}

Ich habe das Beispiel so abgeändert das immer nur die Sensordaten 
rausgesendet werden. Allerdings werden diese teilweise falsch 
ausgegeben:

Empfangene Daten:

-329.00,+10.00,-328.00,+12.00,-334.00,+17.00,-329.00,+11.00,-329.00,+13. 
00,+1014.00<\n>
<\n>
+15.00,+1009.00<\n>
<\n>
+12.00,+1012.00<\n>
<\n>
+14.00,+1008.00<\n>

Es scheint mir nach einem Timing Problem, kennt jemand so ein Problem 
oder hat jemand einen Code der meine Problemstellung erfüllt?
Gast #3381271
>Allerdings werden diese teilweise falsch ausgegeben:

Woher denkst du soll jemand wissen welche Ausgabe du
ERWARTET hast? Was ist denn jetzt falsch an der Ausgabe?
OP #3381282
Wird eig. aus dem Code ersichtlich. Ich würde z.B. immer Zeilen in der 
folgenden Form erwarten:

0.20,102.00,0.39\n\n

Siehe Codeteil:
1
sprintf(buffer, "%+.2f,", raw_acc[0]);
2
USB_SendData(buffer);
3

4
sprintf(buffer, "%+.2f,", raw_acc[1]);
5
USB_SendData(buffer);
6

7
sprintf(buffer, "%+.2f\n\n", raw_acc[2]);
8
USB_SendData(buffer);
Gast #3381326
1
void USB_SendData(char *data)
2
{ 
3
    if(packet_sent == 1)
4
    {
5
        CDC_Send_DATA((unsigned char*) data, strlen(data));    
6
    }
7
}

Jetzt überleg mal was passiert wenn packet_send gleich Null ist.
Richtig: Deine Ausgabe wird nicht gemacht. Das dürfte des Rätsels
Lösung sein;)
Gast #3381385
>...nein das ist nicht die Lösung.

Schade.

> Vorallem sehr kurzsichtig gedacht.

Nö, logische Schlussfolgerung. Wenn packet_sent Null ist
wird nichts gesendet. Aus, Basta.
#3381852
Patrick L. schrieb:
> Am
> besten wäre es wenn sich hier Leute äussern die die
> STM32_USB-FS-Device_Lib_V4.0.0 einsetzen und sich damit auskennen

mit solchen Äuserungen wäre ich vorsichtig

und holger hat sehr wahrscheinlich recht


versuch mal das hier :
1
void USB_SendData(char *data)
2
{ 
3
    // warte bis letztes Packet komplett gesendet ist
4
    while(packet_sent != 1);
5

6
    // sende neues Packet
7
    CDC_Send_DATA((unsigned char*) data, strlen(data));    
8

9
}

und schreib ob das besser funktioniert
OP #3382237
Hab die oben angegebene Codeänderung mal ausgetestet. Resultat ist das 
dann gar nichts mehr empfangen wird. Ich hab habe packet_sent auch 
pauschal ausgeschlossen, da ich ja mitunter Daten empfange, diese dann 
aber nicht zwingend vollständig sind (siehe oben).

Für mich sieht das nach einem Timing Problem aus. Vllt. kann man die 
Sachen einfach nicht so schnell hintereinander raussenden und man müsste 
eine Wartezeit zwischen den USB_SendData Aufrufen einfügen?

Der ursprüngliche Code von STM sieht so aus:
1
int main(void)
2
{
3
  Set_System();
4
  Set_USBClock();
5
  USB_Interrupts_Config();
6
  USB_Init();
7
  
8
  while (1)
9
  {
10
    if (bDeviceState == CONFIGURED)
11
    {
12
      CDC_Receive_DATA();
13
      /*Check to see if we have data yet */
14
      if (Receive_length  != 0)
15
      {
16
        if (packet_sent == 1)
17
          CDC_Send_DATA ((unsigned char*)Receive_Buffer,Receive_length);
18
        Receive_length = 0;
19
      }
20
    }
21
  }
22
}

Dort werden die Daten die man vom PC an das Eval Board sendet direkt 
wieder zurück gesendet. Was auch ohne Probleme Funktioniert hat.

Die CDC_Send_DATA Funktion habe ich komnplett von STM übernommen.
1
uint32_t CDC_Send_DATA (uint8_t *ptrBuffer, uint8_t Send_length)
2
{
3
  /*if max buffer is Not reached*/
4
  if(Send_length < VIRTUAL_COM_PORT_DATA_SIZE)     
5
  {
6
    /*Sent flag*/
7
    packet_sent = 0;
8
    /* send  packet to PMA*/
9
    UserToPMABufferCopy((unsigned char*)ptrBuffer, ENDP1_TXADDR, Send_length);
10
    SetEPTxCount(ENDP1, Send_length);
11
    SetEPTxValid(ENDP1);
12
  }
13
  else
14
  {
15
    return 0;
16
  } 
17
  return 1;
18
}
#3382302
Patrick L. schrieb:
> Ich hab habe packet_sent auch
> pauschal ausgeschlossen, da ich ja mitunter Daten empfange, diese dann
> aber nicht zwingend vollständig sind

und da liegt halt dein Denkfehler

du hast eine IF-Abfrage vor dem eigentlichen senden
1
if(packet_sent == 1)

solange diese nicht erfüllt ist, kannst du die Funktion "USB_SendData" 
aufrufen sooft du willst...am PC wird nichts ankommen
(das sieht dann halt so aus als ob etwas fehlen würde)

hast du den Quellcode von ST 1:1 übernommen ?
dann müsste im Main.c das hier stehen :
1
uint32_t packet_sent=1;

was du auch probieren kannst ist alles in einem Rutsch zu senden :
1
sprintf(buffer, "%+.2f,%+.2f,%+.2f\n\n", raw_acc[0], raw_acc[1], raw_acc[2]);
2
USB_SendData(buffer);

dann wird halt u.U. der komplett String einmal nicht gesendet
(Vorsicht "bufffer" muss groß genug sein)

oder du machst (wie du schon geschrieben hast)
eine kleine Pause zwischen jedem Sendeaufruf

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.