STM32 VCP über USB Problem

OP #3381254
Lesenswert?

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?
OP #3381282
Lesenswert?

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
Lesenswert?

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;)
#3381852
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren