530 likes | 666 Views
Pourquoi L’USB?. Vitesse. C’est un Bus. Présent sur tous les PC. Facilité pour l’utilisateur. … Mais difficulté pour le concepteur. Sommaire . Un microcontrôleur avec USB intégré: 68HC908JB8 Interface FT232 et microcontrôleur 68HC908AB32 Interface FT245 et PIC 16F873-20
E N D
Pourquoi L’USB? • Vitesse. • C’est un Bus. • Présent sur tous les PC. • Facilité pour l’utilisateur. • … • Mais difficulté pour le concepteur.
Sommaire • Un microcontrôleur avec USB intégré: 68HC908JB8 • Interface FT232 et microcontrôleur 68HC908AB32 • Interface FT245 et PIC 16F873-20 La présentation se base sur le livre: ‘L’USB pour tous’ de Vincent Le Mieux au édition Dunod
Acquisition photodiode USB Le système acquisition photodiode USB, permet de faire l’acquisition de signal de 3 photodiodes simultanément via liaison USB d’un PC. F = 10Hz max Le produit se compose de la façon suivante : • La carte électronique. • 3 photodiodes reliées à la carte électronique par une connexion BNC. • Le logiciel d’acquisition : Phodiode_USB.exe • Le package USBIO de Thesycon : usbio_el.exe version 1.51 en version freeware. • Le driver USB modifié comprenant : carte_HC08.inf et carte_HC08.sys
Diagramme de contexte du système PC Communication USB Carte USB Commande Pot num Conv I/U Communication SPI CAN Alimentation Carte photodiode Courant des photodiodes Photodiodes
Hardware device: 68HC08JB8 + connecteur USB Interface USB
Hardware device: Ref U CAN Photodiode + Conv I/U+ Pot num
Enumération L'énumération est le processus qui permet à l’hôte de déterminer l'appareil qui vient d'être branché au bus et les paramètres dont il besoin, comme la consommation électrique, le VID/PID, le nombre et le type de terminaison du produit, etc.… Les étapes du processus d’énumération sont: • L'hôte ou Hub détecte la connexion d'un nouvel appareil via les résistances de rappel de l'appareil reliées sur les 2 fils de données. L'hôte attend au moins 100ms, le temps que la prise soit insérée complètement et que l'alimentation de l'appareil soit stabilisée. • L'hôte émet un "reset" mettant l'appareil dans l'état par défaut. L'appareil peut maintenant répondre à l'adresse zéro par défaut. • L'hôte demande le descripteur de device. • l'hôte émet immédiatement un autre reset sur le bus. • L'hôte émet maintenant une commande SetAdress, mettant l'appareil dans l'état adressable. • L'hôte demande les différents descripteurs (device, configuration, chaines).
//============================================================================//============================================================================ // File: U08DESC.C Ver.: 1.01 // Func: Device-, Configuration- and String-Descriptors for USB08 Demo Application (all const Data, placed in Flash-ROM) // // Auth: (C)2000,2001 by Oliver Thamm, MCT Elektronikladen GbR http://hc08web.de/usb08 //============================================================================ const device_descriptor DeviceDesc = { sizeof(device_descriptor), // Taille de ce descripteur en octets DT_DEVICE, // Type de descripteur (=1 pour le matériel) {0x10, 0x01}, // Version USB (ici = 1.10) 0, // Code de classe (aucun) 0, // Code de sous-classe(aucun) 0, // Code de protocole (aucun) 8, // taille maximum d'un paquet(transféré par EP0) {0x70, 0x0C}, // Vendor ID = MCT Elektronikladen 0x0C70 {0xA6, 0xF0},// Product ID = 0xF0A6 {0x00, 0x01}, // Numéro de version (codé en BCD) 1, // Index du descripteur de chaîne fabricant 2, // Index du descripteur de chaîne produit 0, // Index du descripteur de chaîne N° de série 1 // Nombre de configurations possibles }; const configuration_descriptor ConfigDesc = { sizeof(configuration_descriptor), // Taille du descripteur en octets DT_CONFIGURATION, // Type de descripteur(=2 pour Configuration) {sizeof(configuration_descriptor)+sizeof(interface_descriptor)+sizeof(endpoint_descriptor)+sizeof(endpoint_descriptor), 0x00}, // Longueur totale des données pour cette configuration 1, // Nombre d'interfaces supportées par cette configuration 1, // Valeur désignant cette configuration 0, // Index du descripteur de chaîne pour cette configuration 0x80, // Bus Powered : alimenté par l'USB (0xC0 = Self Powered) 0x64// 100x2mA = 200 mA (car Ox64 = 100 en décimal) }; Les descripteurs HC08JB8
const interface_descriptor InterfaceDesc = • { • sizeof(interface_descriptor), // Taille du descripteur en octets • DT_INTERFACE, // Type de descripteur (=4) • 0, // Numéro de cette Interface (0..) • 0, // interface secondaire • 2,// Nbre d'endpoints pour cette interface(EP0 exclu) • 0xff, // Code de classe (0xff = Vendor specific) • 0x01, // Code de sous-classe • 0xff, // Code de protocole (0xff = Vendor specific) • 0 // Index du descripteur de chaîne pour cette interface • }; • const endpoint_descriptor Endpoint1Desc = • { • sizeof(endpoint_descriptor), //Taille du descripteur en octets • DT_ENDPOINT, // Type de descripteur(=5 pour un endpoint) • 0x81,// Adresse de cet EndPoint (EP1, IN) • 0x03,// fonctionnement sous Interruption • {0x08, 0x00},// Taille maximum du paquet pour cet EndPoint (8 octets) • 10// Intervalle de scrutation (en ms) • }; • const endpoint_descriptor Endpoint2Desc = • { • sizeof(endpoint_descriptor), // Taille du descripteur en octets • DT_ENDPOINT, // Type de descripteur(=5 pour un endpoint) • 0x02,// Adresse de cet EndPoint(EP2, OUT) • 0x03,// fonctionnement sous Interruption • {0x04, 0x00},// Taille maximum du paquet pour cet EndPoint (4 octet) • 10// Intervalle de scrutation (en ms) • };
//Chaîne Fabricant //-------------------------------------------- #define SD1LEN sizeof("CPMOH")*2 //-------------------------------------------- const uchar String1Desc[SD1LEN] = { // Size, Type SD1LEN, DT_STRING, // Unicode String 'C', 0, 'P', 0, 'M', 0, 'O', 0, 'H', 0 }; // Chaîne Produit //----------------------------------------------- #define SD2LEN sizeof("carte_HC08")*2 //----------------------------------------------- const uchar String2Desc[SD2LEN] = { // Size, Type SD2LEN, DT_STRING, // Unicode String 'c', 0, 'a', 0, 'r', 0, 't', 0, 'e', 0, '_', 0, 'H', 0, 'C', 0, '0', 0, '8', 0 }; Descripteur de chaine
Soft HC08JB8 : exemple Dongle USB #include "hc08jb8.h" // définitions des registres du 68HC908JB8 #include "u08usb.c"// toutes les fonctions USB (merci Oliver Thamm !) void main() { uchar i ; //index uchar recep; //variable accueillant l'octet envoyé par le PC uchar code[8] = {100,101,102,103,104,105,106,107}; //tableau de 8 octets constituant le code du dongle initUSB();// initialisation de l'USB cli(); // autorise les interruptions while(1) { recep = getUSB();// récupération de l'octet envoyé par le PC if (recep == 67) /67 = code ASCII de la lettre C { for (i=0;i<=7;i++) putUSB(code[i]);// envoi du code du dongle vers le PC : } } }
Programme Visual Basic 6 Dim WithEvents Endpoint1 As USBIOCOMLib.USBIOInterface ' déclaration de variable objet de type USBIOCOMLib.USBIOInterface qui fait référence Dim WithEvents Endpoint2 As USBIOCOMLib.USBIOInterface ‘ a une instance de classe capable de générer des événements. Dim tampon_reception(0) As Byte ' un octets à recevoir Dim tampon_emission(0) As Byte ' un octets à émettre Dim Status As Long ' variable d'état Private Sub Form_Load() ‘ Chargement de la feuille Dim Devices As Long Dim Status1 As Long Dim Status2 As Long Dim Index As Byte Set Endpoint1 = New USBIOCOMLib.USBIOInterface ' On crée une instance de l’objet USBIO COM pour l'Endpoint 2 Set Endpoint2 = New USBIOCOMLib.USBIOInterface ' On crée une instance de l’objet USBIO COMpour l'Endpoint 1 ' Enumération des matériels disponibles ' Un Guid perso a été obtenu avec Guidgen.exe ; ce même Guid est copié ‘ dans le fichier carte_HC08.inf, le fichier pilote de ce montage USB Endpoint1.EnumerateDevices "{6C9B5899-077E-4e3f-9A39-C2C6C99C8DE8}", Devices If Devices >= 1 Then ' test du nombre de matériels disponibles Endpoint1.OpenDevice 0, Status1 Endpoint2.OpenDevice 0, Status2 If (Status1 = USBIO_ERR_SUCCESS) And (Status2 = USBIO_ERR_SUCCESS) Then ‘teste si la fonction opendevice a réussi Endpoint1.AddInterface 0, 0, 4096, Status ‘ configuration du matériel Endpoint1.SetConfiguration 0, Status Endpoint1.Bind &H81, Status ‘ établi la liaison entre l’objet USBIO COM et l’endpoint EP1 in qui a pour adresse 0x81 Endpoint1.StartReading 1, 5, 5, Status ‘ valide la lecture pour EP1, la taille du tampon. Endpoint2.Bind &H2, Status ‘ établi la liaison entre l’objet USBIO COM et l’endpoint EP2 out qui a pour adresse 0x02 Endpoint2.StartWriting 1, 5, 5, False, Status ‘ valide l’ écriture pour EP2, la taille du tampon Else MsgBox "Erreur de communication avec la carte" End If Else MsgBox "La carte n'est pas connectée ou le driver n'est pas installé" End If End Sub Explication p122
Private Sub Endpoint1_ReadComplete(ByVal Obj As Object) Endpoint1.ReadData tampon_reception, 1, Status ‘ Reception d’un octet If Status = USBIO_ERR_SUCCESS Then LB_AFF.Caption = Format(tampon_reception(0) / 255 * Val(TB_Uref), " 0.000 V") ' affichage de la tension mesurée dans le Label LB_AFF Else MsgBox "Erreur de communication Read Complete" End If End Sub Private Sub Timer1_Timer() tampon_emission(0) = 77 Endpoint2.WriteData tampon_emission, 1, Status' envoi vers le hc08 End Sub Private Sub Form_Terminate() Close #1 Endpoint1.StopReading Endpoint2.StopWriting Endpoint1.CloseDevice Endpoint2.CloseDevice End Sub
Avantages Simplicité du hardware (coût et encombrement) Transfert en mode interrupt (90% de la bande passante allouée pour les transferts périodiques) Limites 1 transfert de 8 octets tous les 10ms → 800 octets/s Complexité de développement au niveau PC car obligation de passer par des .dll Pas de VID: 1500$ Avantages et limites du systèmes
Pulse Start Laser Synchro • Le but est de synchroniser le déclenchement de 2 lasers (ML et SL) Pour cela, le produit devra générer 2 pulses pour chaque laser. La première impulsion (FlashSL et FlashML) déclenchera une lampe flash. La seconde impulsion (QswitchSL et QswitchML) déclenchera un obturateur optique. • Chaque impulsion devra avoir une largeur de L=20µs. Les FlashSL et FlashML ont une fréquence de 10Hz. • Le retard de QswitchSM par rapport à QswitcML est de ∆t +/-2ns de précision. - ∆t : délais entre les Qswitch. -200ns < ∆t < 1s ∆t : -200ns → 1µs pas de 5ns 1µs → 1s pas de 1µs
10Hz 5V 0V FlashSL 230µs Laser 1 5V 0V QswitchSL ∆t 20µs 5V 0V FlashML Laser 2 5V 0V 10Hz 140µs QswitchML Chronogramme
PC Labview + VCP USB FT232 HC08AB32 SCI Programmation retard de 1ns → 1µs Programmation : - Retard de 1µs → 1s FlashSL +/-1ns Laser1 FlashSL +/-1us DS1023-500 QswitchSL +/-1ns XILINX XCS30XL QswitchSL +/-1us DS1023-500 FlashML +/-1us FlashML +/-1ns Laser2 DS1023-500 QswitchML +/-1us QswitchML +/-1ns Génération des pulses +/-1µs DS1023-500 Générateur de retard de 1ns → 1µs Schéma fonctionnel
Hardware device EEPROM FT232
Hardware device Vers mon08 HC908AB32
Soft HC08 /************************************************************/ /* initialisation du micro et des périphériques */ /************************************************************/ void initialisation(void) { CONFIG1 = 0x01; /* watchdog disable */ DDRA |= 0xFE; /* PTA1..7 en sortie */ DDRB = 0xFF; /* PTB en sortie */ DDRD = 0xFF; /* PTD en sortie */ DDRE = 0b01111101; /* PTE2..6 en sortie et PTE7 en entrée */ DDRF = 0xF0; /* PTF0..3 en entrée et PTF4..7 en sortie */ DDRG = 0x07; /* PTG en sortie */ PTFPUE = 0x0F; /* PTF0..3 pull-up activé */ PTF |= 0xF0; /* Pulse enable */ PTA &= 0x0F; /* DS_LE = 0 */ PTB = 0x00; /* DS DATA = 0 */ PTG = 0x00; /* Xilinx START, WR, RST = 0 */ PTD = 0x00; /* Xilinx DATA = 0 */ PTE &= 0b10000011; /* Xilinx ADRESSE = 0 */ SCBR = 0x31;/* Baudrate = Fclk/(64xPDxBD) = 32MHz/(64*13*2) = 19200 Bauds */ SCC1 = 0x40;/* SCI enable */ SCC2 = 0x0C;/* Validation du mode réception et émission */ EnableInterrupts; /* validation des interruptions */ }
Soft HC08 /* Déclaration des variables */ unsigned char buffer_reception[TAILLE_BUFFER]; /* Création d’un tableau dont la taille est TAILLE_BUFFER */ unsigned char *ptr_reception = buffer_reception; /* Création d’un pointeur sur le buffer_reception[0] */ /* Réception par l'usb */ unsigned char reception_usb(void) { unsigned char trame_recut = 0; static unsigned char attente_trame = 1; static unsigned char longueur_a_recevoir; if (SCS1_SCRF == 1)/* si le buffer de réception est plein */ { *ptr_reception = SCDR;/* on stocker la donnée dans buffer_reception */ if (attente_trame == 1) /* si c'est le premier octet de la trame */ { longueur_a_recevoir = *ptr_reception; /* le premier octet correspond a la longueur de la trame */ attente_trame = 0; } longueur_a_recevoir--; ptr_reception++; /* pointe sur prochain octet à recevoir */ if(!longueur_a_recevoir) /* Si plus d'octet à recevoir */ { trame_recut = 1; attente_trame = 1; /* on passe en mode attente de trame car la transmission est terminée */ ptr_reception = buffer_reception; /* pointe le début du buffer */ } else trame_recut = 0; } else trame_recut = 0; return trame_recut; /* trame_recut = 1 si une trame est reçut */ }
Soft HC08 /***********************************************/ /* Emission par l'usb */ /***********************************************/ void emission_usb(unsigned char caractere_a_envoyer) { while (SCS1_SCTE != 1); /* on attend tant que le buffer de transmission n'est pas vide */ SCDR = caractere_a_envoyer; /* copie du caractère dans le registre d’emission */ }
Soft PC pour VCP On peut utiliser tous les logiciels permettant de communiquer avec une liaison série: • HyperTerminal de Microsoft ou Terminal v1.9b: http://bray.velenje.cx/avr/terminal/ • Visual basic, Visual C++,… avec le contrôle ActiveX de Microsoft dédié aux communications série (MSCOMM32.OCX). • Labview que l’on a choisi. • …
HC908AB32 FT232 Xilinx
Sélection du Port COM 3 En fonctionnement Soft PC: Labview
Avantages Facilité d’utilisation et de développement en utilisant les VCP Vitesse de transfert: FT232 + HC08AB32 → 45Ko/s avec les VCP. Limites Complexité de développement au niveau PC si on veut utiliser les D2XX mais on a acces a de nouvelles fonctionnalités: - meilleurs débit - mode bit bang Avantages et limites du systèmes
Quelles performances peut-on obtenir en associant un PIC 16F873 et un FT245? • Le montage précédemment présenté remplit parfaitement le cahier des charges demandé. Mais la vitesse de transfert des données peut-elle être augmentée de façon significative ? Sinon comment peut-on opérer en conservant cet interface et sa facilité de mise en œuvre?
Limites de la liaison série • Quand on utilise une liaison série , chaque octet est mis en série .Sachant que chaque bit est échantillonné 16 fois et que 8 bits + 1 bit de start+1 bit d’arrêt donc au moins 10 bits sont nécessaires , la fréquence du débit des données est égale à la fréquence de cycle micro divisée par 160 (10*16) ; pour nous ici c’est 2Mhz divisé par 160= 50Kbytes /seconde . • C’est la limite d’ envoi des données pour cette interface
Choix du module FT 245 Au lieu d’utiliser le module FT232 , nous travaillons avec le module FT245 qui permet l’envoi des données directement en parallèle vers le module USB donc avec un gain de temps appréciable . Nous allons voir que les instructions même minimales du micro ne permettent pas un débit proche du maximum permis par la liaison USB. Nous utilisons un microprocesseur PIC16F
/*Fichier usb_Lecture.h Microcontrôleur : PIC16F873 /20P Quartz : 20MHz */ /* Déclaration des fonctions usb */ #define RXF PORTB.1 #define RD PORTB.5 char usb_Lecture(void) // Réception d'un octet { unsigned char donne; while (RXF); //teste si ordre de départ arrivé RD=0; // activation de la lecture donne=PORTC; RD=1; return donne; }
TMR1IF=0; // mettre le flag à 0 , mais sans permettre interruption T1CON=0x7; // autorisation du compteur d’événements // on viendra simplement tester le flag de dépassement WRL=1; // synchro oscillo while (TMR1IF==0) { if (TXE==0) // mode envoi normal { WRM=1; // PORTC--; WRM=0; } TMR1IF=0; // raz du flag WRL=0; // synchro oscillo // fin=0; // signifier que c est fini WRL=0; // synchro oscillo TMR1IF=0; T1CON.0=0; // arrêt du compteur événements WRM=1; // dernière donnée avec forçage du msb à 1 WRM=0; }
Essais et performances • L’utilisation d’ un microprocesseur 16F873-20 est nécessaire pour obtenir des vitesses de transmission élevées. • Ce montage permet d’autres possibilités d’interfaçage grâce aux commandes diverses sur les sorties des ports non employées.