Pointeur c, pic18 et accélérométre axdl345
Répondre à la discussion
Affichage des résultats 1 à 9 sur 9

Pointeur c, pic18 et accélérométre axdl345



  1. #1
    inviteefe6e4f2

    Unhappy Pointeur c, pic18 et accélérométre axdl345


    ------

    Bonjour,

    Je débute en C, je dispose d'un pic18f4685, d'un pickit2 et de mplab v8.63

    Je tente d'acquérir les données d'un accéléromètre AXDL345 via i2c.

    Cependant, je ne maitrise pas du tout les pointeurs, et je dois stocker les données (x,y,z) dans un tableau, pour ensuite les afficher sur le PORTC et le PORTB à défaut de disposer d'une connexion usb, et/ou d'un écran lcd.





    Voici mon code pour récupérer les données de l'accéléromètre
    Code:
    #define AXDL_W		  		0x3A// Adresse d'écriture
    #define AXDL_devid			        0x00 // Test adresse
    #define AXDL_R		  		0x3B // Adresse de lecture
    #define AXDL_X0			  	0x32 // Lecture Valeur X0
    #define HIGH 1
    #define LOW 0
    
    
    void init (void);
    void init_i2c(void);
    void init_timer(void);
    void init_adc(void);
    void data_cap (void);
    void _DINT(void);
    void _EINT(void);
    
    void adc_conv(int choix);
    int calcul_xyz(int *buff, int num)
    
    unsigned char GetDataByte(unsigned char addW,unsigned char cmd, unsigned char num);
    int GetDataBytes(int addW, int cmd, int num, int buff[]);
    int WriteData(int addW, int reg, int data);
    
    
    
    void main(void)
    {
    	
    	init();
    	init_i2c();
    	init_timer();
    	while(1)
    		{
    		Delay10KTCYx(1000);
    		LED1=HIGH;
    		LED0=HIGH;
    		Delay10KTCYx(1000);
    		LED1=LOW;
    		LED0=LOW;
    		
    		while(PORTD)
    			{
    				Delay10KTCYx(100);
    				switch(PORTD)
    				{
                                              
                                            case 0x40:LATB=calcul_xyz(*buff, 0x03); LEDaxdl=HIGH; 
    break; //  64 - RD6
    				  	case 0x20:LATB=calcul_xyz(*buff, 0x01); LEDaxdl=HIGH;break; // 32 - RD5
    					case 0x10:LATB=calcul_xyz(*buff, 0x02); LEDaxdl=HIGH;break; // 16 - RD4
    					default:Delay10KTCYx(50);LEDaxdl=LOW;LEDhmc=LOW;LATB=0x00;break;
    				}
    			}	
    		
    		
    	}
    }
    
    
    int GetDataBytes(int addW,int cmd,int num, int *buff)
    {
        int i=0;   
    
    
        StartI2C();
        IdleI2C();
    
        WriteI2C(addW);
        IdleI2C();
       
        WriteI2C(cmd);
        IdleI2C();  
    
        StartI2C();
        
        WriteI2C((addW+0x01));
        IdleI2C();
        
        
        for(i=0;i<=num;i++)
        {
    	    
    	    if(!ReadI2C())
    		{
    			LED9=HIGH;
    			Delay10KTCYx(300);
    			LED9=LOW;
    	    }
    	    else
    	    {
    		    LEDread=HIGH;
    			LED8=HIGH;
    	    	buff[i]=ReadI2C();
    	    	AckI2C();
    	    	IdleI2C();
    		    WriteI2C(addW);
    		    IdleI2C();
    			WriteI2C((cmd+i));
        		IdleI2C();
        		StartI2C();
        		WriteI2C((addW+0x01));
        		IdleI2C();
        		LEDread=LOW; 
        		LED8=LOW;
    	    }
        }
        
        NotAckI2C();
        IdleI2C();  
      
        StopI2C();
    	LEDread=LOW; 
    	
    	return *buff;
       
    }
    
    
    int calcul_xyz(int *buff, int num)
    {
    	int x,y,z;
      
       	x = (((int)buff[1]) << 8) | buff[0];
           	y = (((int)buff[3]) << 8) | buff[2];
            z = (((int)buff[5]) << 8) | buff[4];  
       
            switch(num)
    {
         case 0x01:
    	return x;
       break;
        case 0x02:
            return y;
       break;
       case 0x03;
           return z;
       break;
       default:
          return 0;
       break;
    }
    
    
    }
    Voila, a chaque fois que j'appuie sur le bouton associé a la récupération des données, toute mes leds s'allume comme si j'avais un 0xFF

    De plus, je récupère déjà les valeur d'une boussole , et je n'ai aucun problème pour afficher les données sur le portb. Mon code n'est pas en entier, je n'ai pas mit les inits.
    Je démarre l'accéléromètre via un init, qui effectue un reset, le met en standby, le configure et ENSUITE démarre l'acquisition des données.

    -----

  2. #2
    Jack
    Modérateur

    Re : Pointeur c, pic18 et accélérométre axdl345

    Mon code n'est pas en entier, je n'ai pas mit les inits.
    Dommage parce que la ligne suivante est suspecte:
    Code:
    case 0x40:LATB=calcul_xyz(*buff, 0x03); LEDaxdl=HIGH;
    J'aimerais bien voir comment est déclarée la variable buff.

    Le prototype suivant
    Code:
    int calcul_xyz(int *buff, int num)
    laisse penser que buff est un tableau, o^tout au moins un pointeur sur les données d'un tableau.

    Si c'est le cas, il faut oter l'* devant buff lors de l'appel de la fonction:
    Code:
    case 0x40:LATB=calcul_xyz(buff, 0x03); LEDaxdl=HIGH;
    A+

  3. #3
    inviteefe6e4f2

    Re : Pointeur c, pic18 et accélérométre axdl345

    Donc voici le code en entier, toutes critiques sont les bienvenue, je débute en prog !

    Code:
    //Paramétres de configuration//
    
    #pragma config OSC = HS			
    #pragma const config FCMENB = OFF	
    #pragma const config IESOB = OFF	
    #pragma config PWRT = OFF			
    #pragma const config BOR = BOHW 	
    #pragma const config BORV = 45		
    #pragma config WDT = OFF			
    #pragma config DEBUG = OFF			
    #pragma config LVP = OFF			
    #pragma config PBADEN = OFF
    
    #include <p18f4685.h>
    #include <delays.h>
    #include <i2c.h>
    
    //Magnétométre HMC6352//
    #define HMC_W 			  0x42 	// Adresse d'écriture
    #define HMC_R 			  0x43  // Adresse de lecture
    #define HMC_EEPROM_W      0x77 	// Ecriture dans l'EEPROM
    #define HMC_EEPROM_R      0x72 	// Lecture dans l'EEPROM
    #define HMC_EE_VERSION    0x07 	// Adresse de la version dans l'EEPROM
    #define HMC_GETDATA       0x41 	// Commande pour la lecture d'orientation
    #define HMC_CONTROL_BYTE  0x74  // Registre de controle
    #define HMC_CONTROL_SET   0x21	// 00100001
    
    //Accélérométre AXDL345//
    
    #define AXDL_W		  		0x3A// Adresse d'écriture
    #define AXDL_devid			0x00 // Test adresse
    #define AXDL_R		  		0x3B // Adresse de lecture
    #define AXDL_X0			  	0x32 // Lecture Valeur X0
    #define AXDL_X1				0x33 // Lecture Valeur X1
    #define AXDL_Y0			 	0x34 // Lecture Valeur Y0
    #define AXDL_Y1				0x35 // Lecture Valeur Y1
    #define	AXDL_Z0 		  	0x36 // Lecture Valeur Z0
    #define AXDL_Z1				0x37 // Lecteur Valeur Z1
    #define AXDL_bw_rate		0x2C // Registre BW_RATE
    #define AXDL_DF			  	0x31 // Registre DataFormat
    #define AXDL_set_df		  	0x04 // Self_Test off, Spi off, int_invert low, full_res off, justify right, range 2g 00000000
    #define AXDL_M			  	0x2D // Registre controle
    #define AXDL_reset			0x00 // Reset
    #define AXDL_start		  	0x08 // Debut des mesures
    #define AXDL_standby_mode	0x16 // StandBye Mode
    #define AXDL_rate			0x08 // 0b00001000
    
    //Transducteur a ultrason//
    
    #define CAP5				0x14 // Capteur 1 AN5	
    #define CAP6				0x18 // Capteur 2 AN6			
    #define CAP7				0x1C // Capteur 3 AN7			
    
    
    //I2C : SDA - SCL//
    
    #define TRIS_RC3 	TRISCbits.TRISC3
    #define TRIS_RC4 	TRISCbits.TRISC4
    
    //BOUTON POUSSOIR PC4:PC7//
    
    #define PC4			PORTDbits.RD4
    #define PC5			PORTCbits.RC5
    #define PC6			PORTCbits.RC6
    #define PC7			PORTCbits.RC7
    
    //Indicateur valeur Capteur//	
    
    #define LED0 		LATBbits.LATB0
    #define LED1 		LATBbits.LATB1
    #define LED2		LATBbits.LATB2
    #define LED3		LATBbits.LATB3
    #define LED4		LATBbits.LATB4
    #define LED5 		LATBbits.LATB5
    #define LED6		LATBbits.LATB6
    #define LED7		LATBbits.LATB7
    #define LED8		LATAbits.LATA4
    #define LED9		LATAbits.LATA5
    
    
    //Indicateur Capteur//
    
    #define LEDaxdl		LATAbits.LATA0
    #define LEDhmc		LATAbits.LATA1
    #define LEDread		LATAbits.LATA2
    #define LEDwrite	LATAbits.LATA3
    #define LEDdata		LATAbits.LATA6
    
    #define HIGH 		1
    #define LOW	0
    #define X		0x01
    #define Y		0x02
    #define Z		0x03
    #define HMC		0x04
    
    #define uchar unsigned short int  
    
    
    //Prototype//
    void init (void);
    void init_i2c(void);
    void init_timer(void);
    void init_adc(void);
    void data_cap (void);
    void _DINT(void);
    void _EINT(void);
    
    void adc_conv(int choix);
    unsigned char convert_data(unsigned char *buff, unsigned char num);
    
    
    unsigned char GetDataByte(unsigned char addW,unsigned char cmd, unsigned char num);
    unsigned char GetDataBytes(unsigned char addW,unsigned char cmd, unsigned char num, unsigned char buff[]);
    int WriteData(int addW, int reg, int data);
    
    int DataX0=0, DataX1=0, DataY0=0, DataY1=0, DataZ0=0, DataZ1=0,DataHMC=0, version=0, axdl_state=0;
    unsigned char buff[6]={0}, baff[2]={0};
    
    #pragma code highVector=0x008
    void atInterrupthigh(void)
    {
    _asm GOTO data_cap _endasm
    }
    #pragma code
    
    
    
    
    void main(void)
    {
    	
    	init();
    	init_i2c();
    	init_timer();
    	while(1)
    		{
    		Delay10KTCYx(1000);
    		LED1=HIGH;
    		LED0=HIGH;
    		Delay10KTCYx(1000);
    		LED1=LOW;
    		LED0=LOW;
    		
    		while(PORTD)
    			{
    				Delay10KTCYx(100);
    				switch(PORTD)
    				{
    				  	case 0xF0:init();break;
    					case 0xE0:adc_conv(CAP5);break; // 224 - RD7 - RD6 - RD5
    					case 0xD0:adc_conv(CAP6);break; // 208 - RD7 - RD6 - RD4		
    					case 0xC0:adc_conv(CAP7);break;
    					case 0xB0:WriteData(HMC_W,HMC_CONTROL_BYTE,HMC_CONTROL_SET);break; // 176 - RD7 - RD5 - RD4
    					case 0xA0:_DINT();break;// 160 - RD7 - RD5
    					case 0x90:_EINT();break; // 144 - RD7 - RD4
    					case 0x70://LATB=GetDataByte(AXDL_W,AXDL_devid,0);break;
    					case 0x60:WriteData(AXDL_W, AXDL_M, AXDL_reset);WriteData(AXDL_W, AXDL_M, AXDL_standby_mode);axdl_state=0;break;	 // 96 - RD6 - RD5
    					case 0x50:WriteData(AXDL_W, AXDL_M, AXDL_start);axdl_state++; break; // 80 - RD6 - RD4 
    					case 0x30: break; //48 - RD5 - RD4		
    					case 0x80:LATB=convert_data(*baff,HMC); LEDhmc=HIGH;break;// 128 - RD7
    					case 0x40:LATB=convert_data(*buff,X); LEDaxdl=HIGH;break; //calcul_x(*buff); LEDaxdl=HIGH;break; // 64 - RD6
    					case 0x20:LATB=convert_data(*buff,Y); LEDaxdl=HIGH;break; // 32 - RD5
    					case 0x10:LATB=convert_data(*buff,Z); LEDaxdl=HIGH;break; // 16 - RD4
    					default:Delay10KTCYx(50);LEDaxdl=LOW;LEDhmc=LOW;LATB=0x00;break;
    				}
    			}	
    		
    		
    	}
    }
    
    
    
    
    void init (void)
    
    {
    	TRISA=0x00;			// RA7:RA0 sorties - 0b00000000 ;
    	TRISB=0x00;			// RB7:RB0 sorties - 0b00000000	;	
    	TRISC=0x00;			// RC7:RC0 sorties - 0b00000000 ;
    	TRISD=0xFF;			// RD7:RD0 entrées - 0b11111111 ;
    	TRISE=0x07;			// AN5:AN7 entrées analogiques ; 
    
    	LED0=LOW;			// LOW = 0 ;
    	LED1=LOW;
    	LED2=LOW;
    	LED3=LOW;
    	LED4=LOW;
    	LED5=LOW;
    	LED6=LOW;
    	LED7=LOW;
    	LED8=LOW;
    	LED9=LOW;
    	LEDaxdl=LOW;	// Accélérométre
    	LEDhmc=LOW;		// Magnétométre
    	LEDread=LOW;	// Lecture I2C
    	LEDwrite=LOW;	// Ecriture I2C
    
    
    	PORTA=0x00;			// Initialisation des ports - 0 ;
    	PORTB=0x00;
    	PORTC=0x00;
    	PORTD=0x00;
    	PORTE=0x00;
    
    	LATA=0x00;			// Initialisation des latchs - 0 ;
    	LATB=0x00;
    	LATC=0x00;
    	LATD=0x00;
    	LATE=0x00;
    
    }
    
    void init_i2c(void)
    			
    {
    	TRIS_RC3=HIGH;
    	TRIS_RC4=HIGH;
    	OpenI2C(MASTER, SLEW_OFF);						// Maitre, Bus a 100khz;	
    	SSPADD = 49;  									// 100KHz sous 20MHz ((20 000 000 : ( 4 * 100 000 )) - 1 = 49;
    	Delay10KTCYx(10);
    	WriteData(AXDL_W, AXDL_M, AXDL_reset);			// Reset de l'accélérométre
    	WriteData(AXDL_W, AXDL_M, AXDL_standby_mode);	// Mode standby
    	WriteData(AXDL_W, AXDL_DF, AXDL_set_df); 		// Configuration de l'accélérométre
    	WriteData(AXDL_W, AXDL_bw_rate, AXDL_rate);		// Taux de rafraichissement 
    	WriteData(AXDL_W, AXDL_M, AXDL_start); 			// Départ des mesures
    }
    
    void init_timer(void)
    {
    	T0CON=0b10000001; 		//Timer en fonctionnement. Prescaler 1:4
    	INTCONbits.GIE=1;  		//Autorisations des interruptions
    	INTCONbits.PEIE=1; 		//Autorisations des interruptions périphérique
    	INTCONbits.TMR0IE=1; 	//Autorisations d'interruption pour le débordement du TIMER0
    	INTCON2bits.TMR0IP=1; 	//Interruption du TIMER haute priorité.
    
    }
     
    
    unsigned char convert_data(unsigned char *buff, unsigned char num)
    {
    	unsigned char x=0,y=0,z=0,hmc=0;
      
       	x = (((int)buff[1]) << 8) | buff[0];
        y = (((int)buff[3]) << 8) | buff[2];
    	z = (((int)buff[5]) << 8) | buff[4];
    	hmc = ((int)buff[1] << 8) |`buff[0];  
       
    	switch(num)
    	{
        	case 0x01:
    		return x;
       		break;
        	case 0x02:
            return y;
       		break;
       		case 0x03:
           	return z;
       		break;
       		case 0x04:
       		return hmc;
       		break;
       		default:
          	return 0;
       		break;
    	}
    
    
    }
    
    
    void adc_conv(int choix)  
    
    {   
    	 ADCON0=choix;    			// Sélection du can;   
    	 ADCON1=0b00000111;   		//   
    	 ADCON2=0b10110101;  
    	 ADCON0bits.ADON=1;  
    	 ADCON0bits.GO_DONE=1;   	// début convertion  
    	 while(ADCON0bits.GO_DONE); // attente convertion  
    	 ADCON0bits.GO_DONE=0;  	// fin convertion 
    	 LATB=ADRESL;  
    	 LATC=ADRESH;
    	 ADCON0=0x00;    			// can éteint    
    }  
    
    
    void _DINT()
    {
    	INTCONbits.GIE=0; // Desactivations des interruptions
    }
    
    void _EINT()
    {
    	INTCONbits.GIE=1; // Autorisations des interruptions
    }
    
    #pragma interrupt data_cap  
    void data_cap (void)
    {
    	if(!axdl_state==0)
    	{
     		;;
     	}
     	else 
    	{	
    		GetDataBytes(HMC_W,HMC_GETDATA,1,baff);
    		GetDataBytes(AXDL_W,AXDL_X0,5, buff);		
     	}			
    	INTCONbits.TMR0IF=0;//mise à zero du flag d'IT 
    }
    
    
    unsigned char GetDataBytes(unsigned char addW,unsigned char cmd,unsigned char num, unsigned char *buff)
    {
        int i=0;   
    
    
        StartI2C();
        IdleI2C();
    
    	LEDwrite=HIGH;
        WriteI2C(addW);
        IdleI2C();
        LEDwrite=LOW;
       
        LEDwrite=HIGH;
        WriteI2C(cmd);
        IdleI2C();
        LEDwrite=LOW;	    
    
        StartI2C();
        
        LEDwrite=HIGH;
        WriteI2C((addW+0x01));
        IdleI2C();
        LEDwrite=LOW;
        
        LEDread=LOW;
        
        for(i=0;i<=num;i++)
        {
    	    
    	    if(!ReadI2C())
    		{
    			LED9=HIGH;
    			Delay10KTCYx(10000);
    			LED9=LOW;
    	    }
    	    else
    	    {
    		    LEDread=HIGH;
    			LED8=HIGH;
    	    	buff[i]=ReadI2C();
    	    	AckI2C();
    	    	IdleI2C();
    			LEDwrite=HIGH;
    		    WriteI2C(addW);
    		    IdleI2C();
    			WriteI2C((cmd+i));
        		IdleI2C();
        		StartI2C();
        		WriteI2C((addW+0x01));
        		IdleI2C();
        		LEDwrite=LOW;
        		LEDread=LOW; 
        		LED8=LOW;
    	    }
        }
        
        NotAckI2C();
        IdleI2C();  
      
        StopI2C();
    	LEDread=LOW; 
    	
    	return *buff;
       
    }
    
    
     int WriteData(int addW, int reg, int data)
    
    {
    	LEDwrite=HIGH;
    	StartI2C();
    	
    	IdleI2C();
    	WriteI2C(addW);
    	
    	LEDwrite=LOW;
    	IdleI2C();
    	
    	WriteI2C(reg);
    	IdleI2C();
    	
    	LEDwrite=HIGH;	
    	WriteI2C(data);
    	
    	IdleI2C();
    	StopI2C();
    	
    	LEDwrite=LOW;
    }

  4. #4
    Jack
    Modérateur

    Re : Pointeur c, pic18 et accélérométre axdl345

    donc ca confirme ce que je pressentais.

    Code:
    unsigned char buff[6]={0}, baff[2]={0};
    buff est un pointeur, donc en passant *buff comme paramètre, tu passes en fait le 1er élément contenu dans le tableau.

    A+

  5. A voir en vidéo sur Futura
  6. #5
    inviteefe6e4f2

    Re : Pointeur c, pic18 et accélérométre axdl345

    d'accord j'ai oté le *, cependant les valeurs qui s'affichent sur mon port B sont toujours éronné, et pas actualisé

    Par exemple, quand j'attribue des valeurs fixe à mon tableau buff[6] = {1,2,3,4,5,6);
    et que dans mon switch, j'indique directement , LATB=buff[1] etc...
    J'obtient une valeur fixe :/ mais actualisé au même rythme que l'interruption qui demande les données sur mon accélérométre ! Je n'arrive pas a trouver mon erreur, ou peut être m'y suis je mal pris.

  7. #6
    Jack
    Modérateur

    Re : Pointeur c, pic18 et accélérométre axdl345

    pas facile de voir où ça cloche.

    Tu as un debugger interactif? Il faut que tu réussisses à voir jusqu'où ça tourne correctement en posant des points d'arrêt et en visualisant les données.

    A partir du moment où tu as encadré les lignes de code qui sont en cause, ça devient plus facile de localiser l'erreur.

    A+

  8. #7
    inviteefe6e4f2

    Re : Pointeur c, pic18 et accélérométre axdl345

    et bien mon pickit2 permet de directement voir ce qu'il se passe dans le µpic , cependant je l'ai jamais utilisé, sinon dans mplab je dispose d'un simulateur, mais je dois aussi simuler les entrées ce qui n'est pas facile. Je vais essayer de voir ça.
    Cependant je pense que c'est du fait que je ne maitrise pas les pointeurs :/. Grâce a d'autre del, LEDread, LEDwrite, LEDaxdl, (qui sont placé dans mon code I2C) je sais que les données sont bien acquise. (car elles fonctionnent bien avec la bousole)

    Sinon pour information, je tente de faire une centrale inertielle pour aéromodéliste, avec un accélérometre sur trois axes, deux gyroscope analogique (chacun ayant deux axes, x,y pour l'un et x,z pour l'autre), un gps , et 4 transducteur a ultrason (pour connaitre des distance de 50cm jusqu'a 7métre avec une précision de 2.30cm), et je n'ai plus que l'accélérométre et le gps a gerer, et je m'attaque aux divers calculs qui me permettront de connaitre la position de la centrale inertielle exacte dans l'espace.

  9. #8
    umfred

    Re : Pointeur c, pic18 et accélérométre axdl345

    Ton erreur ne viendrait-elle pas du calcul que tu crois faire dans ta fonction convert_data ?

    tu as déclaré x,y,z et hmc dans ta fonction en unsigned char (ainsi que la valeur retournée), donc sauf erreur de ma part, ils ne peuvent prendre que les valeurs de 0 à 255(0x00->x0ff). Or, je pense que tu veux une valeur sur 2 octets (0x0000->0xffff).
    x = (((int)buff[1]) << 8) | buff[0] ==> x=buff[1]*256 + buff[0]

  10. #9
    inviteefe6e4f2

    Re : Pointeur c, pic18 et accélérométre axdl345

    et bien, j'ai au grand maximum une valeur sur 10 bit soit 2^10, selon la configuration de mon accélérometre (maximum 13bits )(AXDL_set_df), et je peux choisir d'avoir les valeurs justifié a gauche (non signé) ou justifié a droite (signé). (soit le msb a gauche, ou soit a droite enfaite)

    Je vais tenter de revoir de ce coté (car il me semble que j'ai essayé), mais les valeurs que j'ai en retour sont fixe toujours 0xFF ou 0x00 (j'affiche le resultat sur un port 8 bit, j'ai donc une led allumé par bit positif).

    Je viens de tourné mes recherche aussi du coté de mon accélérométre, ils semblent que certains sont défaillant... certaines personnes arriveraient a le faire fonctionner, mais non sans difficulter. :// , mais ça serait bien bizzare, car je dispose de deux accélérometre identique (deux axdl345) et je n'arrive pas a faire fonctionner les deux !! Alors je supose que c'est dans mon code !

Discussions similaires

  1. Pointeur laser
    Par invite376b1ad0 dans le forum Physique
    Réponses: 4
    Dernier message: 04/05/2017, 14h49
  2. Pointeur TNT
    Par invite5686121c dans le forum Électronique
    Réponses: 7
    Dernier message: 10/04/2010, 19h20
  3. laser pointeur
    Par invite77601fbb dans le forum Électronique
    Réponses: 9
    Dernier message: 19/09/2009, 23h21
  4. pointeur
    Par invitef6dc9c06 dans le forum Électronique
    Réponses: 3
    Dernier message: 15/01/2008, 21h53
  5. Notion de pointeur
    Par invite5e5ea0fa dans le forum Internet - Réseau - Sécurité générale
    Réponses: 2
    Dernier message: 31/12/2006, 11h21