- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 89

Thema: 3-Achs Beschleunigungssensor - sensationell günstig !

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    18.03.2011
    Beiträge
    6
    Hallo.

    Erstmal wollte ich mich bedanken, da ich mit hilfe euer Codes erstmal einigermaßen verstanden habe wie der Sensor anzusprechen ist. Leider ist es mir nach einer Woche noch nicht gelungen die Kommunikation zwischen meinem TI 28016, welcher auf nem Olimex Development Board sitzt, und dem BMA020 auf die Beine zu stellen.
    Meine µC-Kenntnis sind eher rudimentär und mit dem TI arbeite ich erst seit 3 Wochen. Deshalb habe ich versucht ein fertiges Snippet anzupassen, geschrieben von Brad Griffis 2008.
    Das ist dabei rausgekommen:
    Code:
    //I2C test 
    
    #include "DSP280x_Device.h"     // DSP280x Headerfile Include File
    #include "DSP280x_Examples.h"   // DSP280x Examples Include File
    
    // Prototype statements for functions found within this file.
    void   I2CA_Init(void);
    Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length);
    Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length);
    
    Uint16 Values[6];
    
    void main(void)
    {
       InitSysCtrl();	// Step 1. Initialize System Control:
       InitI2CGpio();	// Step 2. Initalize GPIO only for I2C functionality
       I2CA_Init();		// Step 4. Initialize all the Device Peripherals
    
       for(;;)		// Application loop
       {   
    	I2C_Write(0x70,0x02,2);
       	I2C_Read(0x71,Values,6);
       }   // end of for(;;)
    }   // end of main
    
    
    void I2CA_Init(void)
    {
    //   I2caRegs.I2CSAR = 0x38;		// Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;		// Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
       I2caRegs.I2CCLKL = 4200;		// NOTE: must be non zero
       I2caRegs.I2CCLKH = 4200;		// NOTE: must be non zero
       I2caRegs.I2CIER.all = 0x3E;		// Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
    //   I2caRegs.I2CMDR.all = 0x0020;	// Take I2C out of reset, Stop I2C when suspended
    //   I2caRegs.I2CFFTX.all = 0x6000;	// Enable FIFO mode and TXFIFO
    //   I2caRegs.I2CFFRX.all = 0x2040;	// Enable RXFIFO, clear RXFFINT,
       return;
    }
    
    Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length)
    {
       Uint16 i;
       while (( I2caRegs.I2CSTR.bit.BB==1 ));	//bus busy?
       if (I2caRegs.I2CSTR.bit.BB == 1)
       {
          return I2C_BUS_BUSY_ERROR;
       }
    	I2caRegs.I2CMDR.all = 0;	//disable I2C during config
    	I2caRegs.I2CCNT = length;	//number of bytes to be send
    	I2caRegs.I2CSAR = slvaddr;	//setup receiver addr
    //	Mode settings
    	I2caRegs.I2CMDR.bit.IRS=1;	//I2C module enable							
    	I2caRegs.I2CMDR.bit.STT=1;	//If master -> start condition generated
    	I2caRegs.I2CMDR.bit.STP=1;	//If master -> stop condition generated if data counter=0
    	I2caRegs.I2CMDR.bit.TRX=1;	//Transmitter mode
    	I2caRegs.I2CMDR.bit.MST=1;	//Master mode
    	I2caRegs.I2CMDR.bit.FREE=1;	//I2C module runs free
    	I2caRegs.I2CMDR.bit.RM=1;	
    	
    	/* Transmission*/
    	for(i=0;i<length;i++)
    	{
    		while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY));	//wait for xdry flag before transmit data or ardy if NACK appears
    		if (I2caRegs.I2CSTR.bit.NACK==1)				//if NACK appears -> SCL=low, STP=0
    		{
    			I2caRegs.I2CMDR.all=0;					//reset I2C -> SCL not held low
    		}
    		I2caRegs.I2CDXR = data;
    	}
    }
    
    Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length)
    {
    	Uint16 i;
    	while (( I2caRegs.I2CSTR.bit.BB==1 ));		//bus busy?
       if (I2caRegs.I2CSTR.bit.BB == 1)
       {
          return I2C_BUS_BUSY_ERROR;
       }
    	I2caRegs.I2CMDR.all = 0;			//disable I2C during config
    	I2caRegs.I2CCNT = length;			//number of bytes to be send
    	I2caRegs.I2CSAR = slvaddr;			//setup receiver addr
    //	Mode settings
    	I2caRegs.I2CMDR.bit.IRS=1;			//I2C module enable							
    	I2caRegs.I2CMDR.bit.STT=1;			//If master -> start condition generated
    	I2caRegs.I2CMDR.bit.STP=1;			//If master -> stop condition generated if data counter = 0
    	I2caRegs.I2CMDR.bit.MST=1;			//Master mode
    	I2caRegs.I2CMDR.bit.FREE=1; 			//I2C module runs free
    	I2caRegs.I2CMDR.bit.NACKMOD=1;
    
    	/* Reception */
    	for(i=0;i<length;i++)
    	{
    		while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY));	//wait for xdry flag before transmit data or ardy if NACK appears
    		if (I2caRegs.I2CSTR.bit.NACK==1)				//if NACK appears -> SCL=low, STP=0
    		{
    			I2caRegs.I2CMDR.all=0;					//reset I2C -> SCL not held low
    		}
    		while(I2caRegs.I2CSTR.bit.RRDY==1);
    		data[i] = I2caRegs.I2CDRR ;
    	}
    }
    
    //EOF
    Das Ergebnis hab ich mir mit nem Oszi angeschaut: Nach dem ersten Senden wird SDI auf low gezogen und SCK bleibt high. Wenn ich die
    Code:
    while (( I2caRegs.I2CSTR.bit.BB==1 ));
    in der Schreib- bzw. Lesefunktion auskommentiere kann ich folgendes Bild sehen:

    http://img24.imageshack.us/img24/7899/bild0027h.jpg

    Meiner laienhaften Meinung nach wird keine Stop Condition erzeugt, weshalb BB immer 1 ist.

    Ein Versuch eine I2C-Minimalversion für diese Sache zu schreiben sah so aus:
    Code:
    //I2C test 
    
    
    #include "DSP280x_Device.h"     // DSP280x Headerfile Include File
    #include "DSP280x_Examples.h"   // DSP280x Examples Include File
    
    // Prototype statements for functions found within this file.
    void   I2CA_Init(void);
    
    Uint16 Values[6],i;
    
    
    void main(void)
    {
       InitSysCtrl();			// Step 1. Initialize System Control:
       InitI2CGpio();			// Step 2. Initalize GPIO only for I2C functionality
       I2CA_Init();				// Step 4. Initialize all the Device Peripherals:
    
    
       for(;;)					// Application loop
       {
       		      //---> Write instruction <--- //
          I2caRegs.I2CMDR.bit.STT = 1;
          I2caRegs.I2CSAR = 0x70;				//Write addr
          I2caRegs.I2CCNT = 3;				//3bytes=2bytes addr + 1 byte instr
          I2caRegs.I2CDXR = 0x02;				//instr
          I2caRegs.I2CMDR.bit.STP = 1; 
    //      I2caRegs.I2CMDR.all = 0x2620;		//Send data to setup EEPROM address
    
          
          //---> Read values <--- //
          I2caRegs.I2CMDR.bit.STT = 1;
          I2caRegs.I2CSAR = 0x71;				//Read addr
          I2caRegs.I2CCNT = 1;				//6bytes=2bytes per coordinate
          Values[0] = I2caRegs.I2CDRR;
          /*for(i=0;i<6;i++)
          {
          	Values[i] = I2caRegs.I2CDRR;
          }*/
          I2caRegs.I2CMDR.all = 0x2C20;			//Send restart as master receiver
       	  I2caRegs.I2CMDR.bit.STP = 1;					
       }   // end of for(;;)
    }   // end of main
    
    
    void I2CA_Init(void)
    {
    //   I2caRegs.I2CSAR = 0x38;			// Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;			// Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
       I2caRegs.I2CCLKL = 4200;			// NOTE: must be non zero
       I2caRegs.I2CCLKH = 4200;			// NOTE: must be non zero
       I2caRegs.I2CIER.all = 0x24;		// Enable SCD & ARDY interrupts
       I2caRegs.I2CMDR.all = 0x0020;	// Take I2C out of reset, Stop I2C when suspended
       I2caRegs.I2CFFTX.all = 0x6000;	// Enable FIFO mode and TXFIFO
       I2caRegs.I2CFFRX.all = 0x2040;	// Enable RXFIFO, clear RXFFINT,
       return;
    }
    
    //EOF
    Führte aber leider auch nicht zum Ergebnis.

    Falls es relevant ist ich nutze das Code Composer Studio V4.
    Falls jemand hier Erfahrungen mit TI DSPs oder Vorschläge jeglicher Art zu meinen beiden Code-Versuchen hat wäre ich sehr dankbar.

    Grüße
    Stephan

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    18.03.2011
    Beiträge
    6
    hallo,

    habs jetzt hinbekommen und falls mal jemand den BMA020 mit TI C2000 DSPs nutzen will poste ich mal meinen, durchaus verbesserungswürdigen, Code, welcher hier bereits gepostete Codeschnipsel enthält.

    Code:
    //I2C test 
    
    #include "DSP280x_Device.h"     // DSP280x Headerfile Include File
    #include "DSP280x_Examples.h"   // DSP280x Examples Include File
    
    // Prototype statements for functions found within this file.
    void   I2CA_Init(void);
    
    int Values[6]={0,0,0,0,0,0};
    Uint16 instr=0x02;
    int i,dx=0,dy=0,dz=0;
    double D2G,gx=0,gy=0,gz=0;
    
    void main(void)
    {
       InitSysCtrl();			// Step 1. Initialize System Control:
       InitI2CGpio();			// Step 2. Initalize GPIO only for I2C functionality
       I2CA_Init();				// Step 4. Initialize all the Device Peripherals
       
       D2G=0.00390625;			// 4g/1024
       
       for(;;)					// Application loop
       	{  
       		I2caRegs.I2CSAR = 0x38; 		//Set slave address
       		I2caRegs.I2CCNT = 1; 			//Set count to 1 Byte for instr 0x02
       		I2caRegs.I2CDXR = 0x02;			//Send instr
       		I2caRegs.I2CMDR.bit.TRX = 1; 		//Set to Transmit mode
       		I2caRegs.I2CMDR.bit.MST = 1; 		//Set to Master mode
       		I2caRegs.I2CMDR.bit.FREE = 1;		//Run in FREE mode
       		I2caRegs.I2CMDR.bit.STP = 1; 		//Stop when internal counter becomes 0
       		I2caRegs.I2CMDR.bit.STT = 1; 		//Send the start bit, transmission will follow
    				
        
       		while(I2caRegs.I2CSTR.bit.XRDY == 0){}; 	//Do nothing till data is shifted out
       		I2caRegs.I2CCNT = 6;				//read 6 bytes from sensor
       		I2caRegs.I2CMDR.bit.TRX = 0; 			//Set to Recieve mode
       		I2caRegs.I2CMDR.bit.MST = 1; 			//Set to Master mode
       		I2caRegs.I2CMDR.bit.FREE = 1;			//Run in FREE mode
       		I2caRegs.I2CMDR.bit.STP = 1; 			//Stop when internal counter becomes 0
       		I2caRegs.I2CMDR.bit.STT = 1; 			//Repeated start, Reception will follow
       		for(i = 0; i < 6; i++)
       			{
       				while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
       				Values[i] = I2caRegs.I2CDRR;
       			}
       		DELAY_US(100);				//wait for new data provided
       		dx=Values[0];				//dataadaptation by malthy & Sternthaler
       		dx=(dx|((Values[1]<<8))>>6);
       		gx=dx*D2G;
       		dy=Values[2];
       		dy=(dx|((Values[3]<<8))>>6);
       		gy=dy*D2G;
    		dz=Values[4];
       		dz=(dx|((Values[5]<<8))>>6);
       		gz=dz*D2G;
       		   	   		 	   
       }   // end of for(;;)
    }   // end of main
    
    
    void I2CA_Init(void)
    {
       I2caRegs.I2CSAR = 0x38;		// Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;		// Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
       I2caRegs.I2CCLKL = 42;		// NOTE: must be non zero
       I2caRegs.I2CCLKH = 21;		// NOTE: must be non zero
       I2caRegs.I2CIER.all = 0x3E;		// Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
       I2caRegs.I2CMDR.bit.IRS = 1;      // Take I2C out of reset, Stop I2C when suspended
       I2caRegs.I2CFFTX.all = 0x0000;	// Enable FIFO mode and TXFIFO
       I2caRegs.I2CFFRX.all = 0x0000;	// Enable RXFIFO, clear RXFFINT,
       return;
    }
    
    //EOF
    An der Stelle nochmals danke an die "Code-Sponsoren".

    Das einzige was mich im Betrieb stört ist, dass die Ergebnisse nicht konstant bleiben selbst wenn ich den Sensor fest einspanne. Dabei treten manchmal Sprünge von bis zu 0.5g auf, was für meine anschließende Aufgabe tötlich sein wird. Hat schon mal jemand in dem Zusammenhang mit den Filtern rumgespielt ?

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    18.03.2011
    Beiträge
    6
    Hallo,

    ich weiß nicht ob dass hier noch relevant ist, aber falls nochmal jemand auf schwankende Werte kommt kann ich empfehlen die Einstellung des im Sensor befindlichen Tiefpasses zu checken. Bei mir war die Einstellung für "bandwidth" (14h,bits 2-0) nämlich auf 750Hz, abweichend von der Standardbelegung mit 25Hz. Dadurch hatte ich bei einem Wertebereich von +/-256 einen Fehler von ca. +/-10. Mit 25Hz komm ich auf +/-2 und bin für meine Anwendung ausreichend schnell.

    In dem Sinne fröhliches Beschleunigen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests