2016-08-20 5 views
0

J'ai besoin de transférer des données du microcontrôleur ATC UC3 vers le PC via USB. Je vérifie le travail de ADC et PDCA dans le MCU de remplissage du tampon, et cela fonctionne parfaitement sans perte de données. Mais quand j'envoie des données de l'USB certains octets sont perdus. Je ne sais pas, pourquoi cela arrive. J'écris des programmes simples pour envoyer des données de MCU à PC et vérifier ces données. Dans le MCU, je remplis le tampon avec des nombres de 0,1,2 .. à 255 en continu, puis envoie le tampon via USB au PC, et vérifie le contenu de ce tampon. Ainsi, certains chiffres sont différents des données d'origine. Certains octets sont perdus. J'utilise EVK1100 en mode appareil CDC.AVR32 UC3 Perte de données USB en mode périphérique cdc

Code AVR:

#include <asf.h> 
#include "conf_usb.h" 

#define BUF_SIZE 32 

int main(void){ 

    irq_initialize_vectors(); 
    cpu_irq_enable(); 

    sysclk_init(); 

    udc_start(); 
    udc_attach(); 

    char pbuf[BUF_SIZE]; 
    for(int i=0; i<BUF_SIZE; i++){ 
     pbuf[i] = (char)i; 
    } 

    while (true) { 
     udi_cdc_write_buf(pbuf, BUF_SIZE); 
    } 
} 

code C#:

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.IO.Ports; 

    namespace acc_tester 
    { 
    class Program 
    { 
     static void Main(string[] args) { 
      Console.WriteLine("Start"); 
      int N = 32; 

      SerialPort serialPort = new SerialPort(); 

      serialPort.PortName = "COM6"; 

      serialPort.Open(); 

      byte[] buf = new byte [N]; 

      for (int n = 0; n < 10000; n++) { 
       serialPort.Read(buf, 0, N); 

       for (int i = 0; i < N; i++) { 
        if (buf[i] != (byte)(buf[0] + i)) { 
         Console.WriteLine("Data Lost. n =" + n.ToString() + " i=" + i.ToString()); 
         return; 
        } 
       } 
      } 

      serialPort.Close(); 
      Console.WriteLine("Stop"); 
      return; 
     } 
    } 
} 

La sortie de mon programme C# est:

données perdues. n = 257 i = 31

Données perdues. n = 385 i = 31

Données perdues. n = 641 i = 31

Données perdues. n = 257 i = 31 et etc.

S'il vous plaît, aidez-moi à résoudre le problème.

+0

Quelle version du framework, quel compilateur et quel pilote utilisez-vous? Aussi quel OS sur PC vous avez. Vérifiez également le port USB (devrait être 2.0 pas 3.0 juste pour être sûr). Dans le cas de Windows sur des machines plus lentes (comme les ordinateurs portables) si le système d'exploitation est trop occupé (comme avec gfx), le transfert de masse USB CDC a tendance à perdre la synchronisation et créer des pauses de transfert dans le calque du pilote. Si votre côté MCU n'est pas conçu pour le gérer, tout peut arriver (mais je n'ai jamais vu de perte de données auparavant) – Spektre

Répondre

0

SerialPort.Read lit au plusN (32) octets, cela dépend de combien d'octets sont dans la mémoire tampon d'entrée (docs). Read renvoie la quantité d'octets lus.

Pour lire un bloc de données de longueur N, vous devez vous tamponner les données et vérifier uniquement le contenu lorsque vous atteignez N octets. Par exemple.

while (true) { 
    var bytesInBuffer = 0; 
    bytesInBuffer += serialPort.Read(buf, bytesInBuffer, N - bytesInBuffer); 
    if (bytesInBuffer == N) { 
     // Here the buffer is ready 
     bytesInBuffer = 0; // reset the counter 
    } 
} 
+0

Dans Atmel AVR4901 du tableau 4-2, les types de terminaux suivants sont utilisés: contrôle, interruption, bulk et isochrone. Mais seul le mode bulk a été garanti le transfert de données. J'ai besoin de savoir, dans quel mode fonctionne le mode de l'appareil CDC et comment le passer en mode bulk CDC en ASF. – Leonid

+0

Est-ce que cela fonctionne avec mon code? – aghidini