Aide CAN sur dsPIC30f
Répondre à la discussion
Affichage des résultats 1 à 4 sur 4

Aide CAN sur dsPIC30f



  1. #1
    invite25df009a

    Aide CAN sur dsPIC30f


    ------

    Bonjour,

    Voila je suis sur un projet dont le but est de convertir 3 tensions analogiques en Numériques et de les transmettre à un PC via un port RS232.

    J'ai donc réalisé un programme qui fonctionne mais mon souci est que je suis obligé d'insérer un délais de 10 us après chaque conversion car sinon le résultat obtenue me donne un peu n'importe quoi.

    Voici mon code :
    Code:
    void init_ADC()
    {
    	ADPCFG = 0xF1FF; 	// all PORTB = Digital
    			        // RB10 to RB8 = analog(0) 
    	ADCON1 = 0x00E0; 	// SSRC bit = 111 implies internal
    			       // internal counter ends sampling and starts conversion (auto convert)
    	ADCHS = 0x0009; 	// Connect RB9/AN9 as CH0 input
    			       // RB9/AN9 is the input
    	ADCSSL = 0;		// 
    	ADCON3 = 0x1F02; 	// Sample time = 31Tad, Tad = internal 2 Tcy
    	ADCON2 = 0;		// use MUX A
    			       // one 16-word buffer
    			       // interrupt to each sample/convert sequence
    	ADCON1bits.ADON = 1; 	// enable module ADC 
    }
    main()
    {
    	TRISBbits.TRISB9  = 1;		// Port RB9  mis en entree pour la phase1
    	TRISBbits.TRISB10 = 1;		// Port RB10 mis en entree pour la phase2
    	TRISBbits.TRISB11 = 1;		// Port RB10 mis en entree pour la phase3
    
    	LCD_Setup();
    	LCD_HomeClear();
    
    	valeur1 = 0;
    	valeur2 = 0;
    	valeur3 = 0;
    
    	UART1_Init();
    	init_ADC();
    
    	while(1)
    	{
    
    		/**************************************
    		*		CONVERSION PIN RB9			  *
    		**************************************/
    		ADCHS = 0x0009;			// Selection de la broche RB9
    		ADCON1bits.SAMP = 1; 		// demarrer l'échantillonnage
    						// Après 31 Tad faire la conversion
    		while (!ADCON1bits.DONE);	// Attend la fin de la conversion
    		valeur1 = ADCBUF0; 		// lecture de la valeur converti
    		Delay_Us(10);
    
    		/**************************************
    		*		CONVERSION PIN RB10			  *
    		**************************************/
    		ADCHS = 0x000A;			// Selection de la broche RB10
    		ADCON1bits.SAMP = 1; 		// demarrer l'échantillonnage
    						// Après 31 Tad faire la conversion
    		while (!ADCON1bits.DONE);	// Attend la fin de la conversion
    		valeur2 = ADCBUF0; 		// lecture de la valeur converti
    		Delay_Us(10);
    
    		/**************************************
    		*		CONVERSION PIN RB11			  *
    		**************************************/
    		ADCHS = 0x000B;			// Selection de la broche RB11
    		ADCON1bits.SAMP = 1; 		// demarrer l'échantillonnage
    						// Après 31 Tad faire la conversion
    		while (!ADCON1bits.DONE);	// Attend la fin de la conversion
    		valeur3 = ADCBUF0; 		// lecture de la valeur converti
    		Delay_Us(10);
    	
    		/**************************************
    		*		ENVOIE DES DONNEES AU PC	  *
    		**************************************/
    		UART1_SendByte('P');
    		UART1_SendInt(valeur1);
    		UART1_SendByte('P');
    		UART1_SendInt(valeur2);
    		UART1_SendByte('P');
    		UART1_SendInt(valeur3);
    	}
    }
    Si quelqu'un a déjà réalisé ce genre d'application ou a une idée pour enlever ce delay pour que ça fonctionne correctement, je suis preneur.

    Merci pour vos réponses.

    -----

  2. #2
    invite7a49d0d5

    Cool

    Bonsoir,

    je connais pas les ds30, mais je dirais que c'est normal...
    il faut "un certain temps" au PIC pour faire la "conversion"...

    avec un 16F88, c'est minimum 19,7µs...
    c'est détaillé, en français, pour un 16F88, ici :
    http://pagesperso-orange.fr/fabrice..../ADC_16F88.htm
    (calcul et optimisations des temps de conversions pour un 16F88,
    ça donne une "idée", pour n'importe quel PIC... 16F... en tout cas...)

    vede
    ;O]

    re ;O]

    moi, ce que je fais souvent, c'est lancer la conversion (ADCON.GO=1),
    executer le programme normal, puis récupérer le resultat et relance conversion...
    si le programme "dure" plus de 20µs... c'est cool...
    sinon j'ajoute une var "flag_compteur_pour_adc".. . qui attend/compte qq cycles
    dans le programme principal pour aprés aller récupérer le resultat et re-demander
    une conversion...

    c'est pas clair je sais... mais je fais comme ça... pour ne pas "voir" ce temps...
    un exemple là, ou je lis une entrée ADC, tout en multiplexant des leds...
    http://soj.mesdiscussions.net/soj/El...jet_5555_2.htm
    (pas question d'attendre 10µs... je suis un puriste ;O])

    re re ;O]

    oui, en regardant ton code...

    il y à aussi une phase ou il faut "attendre" pour pouvoir
    re-utiliser l'ADC... presque égale au temps de conversion...
    sur un 16F...

    c'est une histoire de charge/décharge de condo... si je n'm'abuse...

    re re re :
    en enlevant le delai aprés la conversion sur RB11...
    déjà ça devrait continuer à fonctionner...
    vu que les envoi UART doivent "prendre" plus que 10µs...

    voilà, et en "entrelaçant" les conversions et envois...
    tu peux y arriver... ou gagner qq µs sur...

    style :
    Code:
    		/**************************************
    		*		CONVERSION PIN RB9			  *
    		**************************************/
    		ADCHS = 0x0009;			// Selection de la broche RB9
    		ADCON1bits.SAMP = 1; 		// demarrer l'échantillonnage
    						// Après 31 Tad faire la conversion
    		while (!ADCON1bits.DONE);	// Attend la fin de la conversion
    		valeur1 = ADCBUF0; 		// lecture de la valeur converti
    		UART1_SendByte('P');
    		UART1_SendInt(valeur1);
    
    		/**************************************
    		*		CONVERSION PIN RB10			  *
    		**************************************/
    		ADCHS = 0x000A;			// Selection de la broche RB10
    		ADCON1bits.SAMP = 1; 		// demarrer l'échantillonnage
    						// Après 31 Tad faire la conversion
    		while (!ADCON1bits.DONE);	// Attend la fin de la conversion
    		valeur2 = ADCBUF0; 		// lecture de la valeur converti
    		UART1_SendByte('P');
    		UART1_SendInt(valeur2);
    
    		/**************************************
    		*		CONVERSION PIN RB11			  *
    		**************************************/
    		ADCHS = 0x000B;			// Selection de la broche RB11
    		ADCON1bits.SAMP = 1; 		// demarrer l'échantillonnage
    						// Après 31 Tad faire la conversion
    		while (!ADCON1bits.DONE);	// Attend la fin de la conversion
    		valeur3 = ADCBUF0; 		// lecture de la valeur converti
    		UART1_SendByte('P');
    		UART1_SendInt(valeur3);
    Dernière modification par gienas ; 22/01/2010 à 15h21. Motif: Fusion de cinq réponses consécutives rapprochées

  3. #3
    RISC

    Re : Aide CAN sur dsPIC30f

    Salut,

    Plusieurs points à vérifier pour pouvoir améliorer le temps de conversion :
    1/ Quel référence exacte de dsPIC30 utilises-tu ?
    2/ A quelle fréquence (Fcycle) fais-tu fonctionner ton dsPIC30 ? (30MIPS ?)
    3/ Quelle est l'impédance source de tes 3 entrées analogiques ?
    (c'est important pour le calcul du temps de conversion). Tu as choisis 31 Tad mais il serait sans doute possible de réduire cette valeur.
    4/ Ou sont les bits de configuration ? Je ne les ai pas vus dans ton programme...

    Il existe de nombreux exemples de code pour les périphériques des dsPIC et autres PICs ici.

    Tu pourrais enchainer automatiquement les conversions si tu travaillais sous interruption...


    a+

  4. #4
    invite25df009a

    Re : Aide CAN sur dsPIC30f

    Bonjour,

    Merci pour vos réponses !!

    Du coup, j'ai essayé ta solution (vede) et le fait d'envoyer les données au PC entre chaque conversion me permet d'avoir des résultats corrects.
    Sinon pour les bits de configuration, ils sont tout au début du premier bout de code que j'ai mis (RISC).

    Pour plus d'information :
    J'utilise donc un dsPIC30f6014 avec la carte de développement dsPICDEM 1.1 plus. Il fonctionne avec l'oscillateur interne de 8 MHz.
    Le but est de convertir 3 tensions analogiques variant de 0 à 5V provenant d'un capteur dont je n'ai aucune documentation et de transmettre ces données à un PC.

    Je pense aussi que le fait d'utiliser les interruptions me permettrait d'enchainer directement les 4 conversions mais je n'ai pas encore eu le temps de tester cette solution.

    Sinon j'ai une autre question :
    Parce que sur la doc du dsPIC, on me dit que l'horloge de conversion Analog->Digital(TAD) ne doit pas avoir une période inférieur à 667 nsec.

    Hors je viens de m'apercevoir que mon temps de cycle est définit par la fonction
    TAD = Tcy * (0,5 * (ADCS<5:0> + 1))
    Ce qui donne avec ADCS = 2 :
    => Pour une horloge de 8 MHz : 187,5 ns
    => Pour une horloge de 4 MHz : 375 ns
    => Pour une horloge de 2 MHz : 750 ns

    J'ai juste un doute sur mon fréquence Fcy, parce que pour les Timers la valeur Fcy = Fosc / 4 mais je ne sais pas si c'est le même temps de cycle pour le CAN.

    Voila, Merci pour vos réponses

  5. A voir en vidéo sur Futura

Discussions similaires

  1. dsPIC30F SMPS - Réalisation d'une conversion A/N
    Par invite3c35244f dans le forum Électronique
    Réponses: 14
    Dernier message: 24/11/2009, 21h35
  2. laibrairie de dspic30f pour aigl
    Par invitec99a3210 dans le forum Électronique
    Réponses: 0
    Dernier message: 12/11/2009, 18h28
  3. Aide sur les bus de données : fonctionnement, et réalisation sur Eagle
    Par invite7e815baa dans le forum Électronique
    Réponses: 4
    Dernier message: 18/10/2009, 14h24
  4. Problème programmation filtre sur Dspic30F
    Par invite0fffe0df dans le forum Électronique
    Réponses: 11
    Dernier message: 27/08/2008, 21h35
  5. Dspic30f --- I2c --- Cmps03
    Par invite018af9d8 dans le forum Électronique
    Réponses: 1
    Dernier message: 11/10/2007, 14h06
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...