-         

Ergebnis 1 bis 5 von 5

Thema: Benötige Programmierhilfe zum Auslesen eines Maussensors

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    14.04.2010
    Beiträge
    10

    Benötige Programmierhilfe zum Auslesen eines Maussensors

    Anzeige

    Hallo Liebe Community,
    ich würde gerne einen Maussensor ADNS2610 mit Hilfe eines ATMegas32 auslesen und die Info's per UART an den PC senden. Ich habe den Maussensors als Einzelteil mit nem 24MHZ Quarz, LED, 5V und MOSI und SCK vom ATmega32 bestückt. Der uC sitzt auf nem STK500 Programmierboard.
    Die UART-Verbindung habe ich soweit schon zum laufen bekommen. Nun stockt es aber bei meinen Programmierkenntnissen zum Auslesen des Maussensors über die SPI Verbindung.

    Beispielhaft habe ich schonmal ein Programmtext zum auslesen der delta x und y Werte geschrieben.
    Ich weiß eben nur nicht wie mein Write und Read dazu aussehen muss. Ich hoffe mir kann da geholfen werden und das ich kein hoffnungsloser Fall bin
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    
    #define F_CPU 4000000UL
    #define ADNS_PORT	PORTB
    #define ADNS_DDR	DDRB
    #define ADNS_PIN	PINB
    #define ADNS_SCK	7	// Pinnumber für SCK vom ATMega32
    #define ADNS_MISO	6	// Pinnumber für MISO vom ATMega32
    #define ADNS_MOSI	5	// Pinnumber für MOSI vom ATMega32
    	
    #define ADNS_CONFIG				0x00
    #define ADNS_STATUS				0x01
    #define ADNS_DY					0x02
    #define ADNS_DX					0x03
    #define ADNS_SQUAL				0x04
    #define ADNS_MAX_PIXEL			0x05
    #define ADNS_MIN_PIXEL			0x06
    #define ADNS_PIXEL_SUM			0x07
    #define ADNS_PIXEL_DATA			0x08
    #define START_OF_FRAME			0x80
    #define VALID_DATA				0x40
    
    void USART_Init (void) ;
    void USART_Transmit (unsigned char data) ;
    
    void ADNS_Init (void) ;
    void ADNS_Transmit (unsigned char data1) ;
    char ADNS_Receive(void);
    void ADNS_Write (unsigned char adr, unsigned char data) ;
    char ADNS_Read (unsigned char adr) ;
    void ADNS_Pulse (void) ;
    void Delay1ms (unsigned int time) ;
    void Delay1us (unsigned int time) ;
    
    
    //*********************Def's für die UART Verbindung
    void USART_Init (void)
    {
      
      UBRRL = F_CPU / (16 * 9600UL) - 1; 
      UCSRB = (1<<RXEN) | (1<<TXEN) ;
      UCSRC = (1<<URSEL) | (1<<USBS) | (3<<UCSZ0) ;
    }
    
    void USART_Transmit (unsigned char data0)
    {
      while ( !(UCSRA & (1<<UDRE)) ) ;
      UDR = data0 ;
    }
    
    //*******************Def's für die SPI Verbindung zum ADNS
    void ADNS_Init (void)
    {
      ADNS_DDR |= (1<<ADNS_SCK) | (1<<ADNS_MOSI); 	//Setzt PortB auf 0b10100000 also PB7 und PB5 als Ausgang => für Read?
      SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);		//Müssen CPOL und CPHA gesetzt werden?
    }											
    
    void ADNS_Transmit (unsigned char data1)		// überträgt data1 per spi an den adns
    {
      SPDR = data1;
      while(!(SPSR & (1<<SPIF)));
    }
    
    char ADNS_Receive (void)
    {
      while(!(SPSR & (1<<SPIF)));
      return SPDR;
    }
    
    void ADNS_Pulse (void)
    {
      ADNS_PORT &=~(1<<ADNS_SCK);
      ADNS_PORT &=~(1<<ADNS_SCK);
      ADNS_PORT |= (1<<ADNS_SCK);
      ADNS_PORT |= (1<<ADNS_SCK);
    }
    
    void ADNS_Write (unsigned char adr, unsigned char data) // Hier weiß ich leider überhaupt nicht mehr weiter	
    {
     
    }
    
    
    
    char ADNS_Read (unsigned char adr)			
    {
     char temp;
     
     return temp;
    }
    
    
    
    void Delay1ms (unsigned int time)				
    {
     while(time--) _delay_ms(1);
    }
    
    
    void Delay1us (unsigned int time)
    {
     while(time--) _delay_us(1);
    }
    
    
    
    int main (void)
    {
      char send;
      
      USART_Init ();
      Delay1ms(500);
      ADNS_Init ();
      Delay1ms(500);
      ADNS_Write (ADNS_CONFIG , 0x80); //SOFT RESET
      Delay1ms(200);
      ADNS_Write (ADNS_CONFIG , 0x01); //Always AWAKE
      Delay1ms(200);
    
      while(1)
      {
    	send = ADNS_Read (ADNS_DY);
    	USART_Transmit (send);
    	send = ADNS_Read (ADNS_DX);
    	USART_Transmit (send);
      }
    }

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Eine software-SPI-Kommunikation hatte ich dir schon hier gezeigt:

    Code:
     // RP6 liest optischen Maussensor aus (nur x/y)(Maussensor: ADNS-2051) 22.1.09 mic
    
    #include "RP6RobotBaseLib.h"
    
    #define clk_h DDRC |= 1; PORTC |= 1    // Für Anschluss an SDA/CLK am XBUS
    #define clk_l DDRC |= 1; PORTC &= ~1   // clk - Pin 10
                                           // data= Pin 12
    #define data_h DDRC |= 2; PORTC |= 2   // Vcc - Pin 3
    #define data_l DDRC |= 2; PORTC &= ~2  // GND - Pin 1
    #define data_z DDRC &= ~2; PORTC &= ~2
    #define data_in (PINC & 2)
    
    /*
    #define clk_h DDRA |= 1; PORTA |= 1    // Für Anschluss an ADC0/1
    #define clk_l DDRA |= 1; PORTA &= ~1   // clk - ADC0
                                           // data- ADC1
    #define data_h DDRA |= 2; PORTA |= 2
    #define data_l DDRA |= 2; PORTA &= ~2
    #define data_z DDRA &= ~2; PORTA &= ~2
    #define data_in (PINA & 2)
    */
    
    void init( void)
    {
       data_z;       // Datenpin auf Eingang ohne Pullup (Status Z)
       clk_h;        // Dummyclockimpuls erzeugen
       sleep(5);
       clk_l;        // Maus wartet nun bis zum Timeot auf den nächsten Takt
       mSleep(2000); // timeout adnr2051 erzwingen => reset
    }
    
    void write_data(uint16_t data)
    {
       uint8_t bit=16;
       while(bit--)
       {
          if(data & (1<<bit)) {data_h;} else {data_l;} // {}-Klammern sind hier muss!
           sleep(5);
          clk_h;       // Datenbit für Maus steht bereit
            sleep(5);  // Maus liest Datenbit
          clk_l;
           sleep(5);
       }
       data_z;
       sleep(20);
    }
    
    uint8_t read_data(uint8_t adr)
    {
       uint8_t bit, data;
    
       bit=8;
       while(bit--)
       {
          if(adr & (1<<bit)) {data_h;} else {data_l;} // Datenbit ausgeben
           sleep(5);                                  // warten bis Pegel stabil
          clk_h;                                      // Maus darf Daten lesen
           sleep(5);                                  // warten bis Maus gelesen hat
          clk_l;                                      // Bit fertig
            sleep(5);
       }
       clk_l;
       data_z;
       sleep(20);
       bit=8;
       data=0;
       while(bit--)
       {
          clk_h;
    		sleep(5);                       // Bit anforden und warten bis Pegel stabil
          if(data_in) {data |= (1<<bit);} // Bit einlesen
          clk_l;                          // Bit gelesen
    		sleep(5);
       }
       sleep(20);
       return(data);
    }
    
    int main(void)
    {
       uint8_t status;
    
       initRobotBase();
       init();
    
       writeString_P("Produkt-ID: ");
       writeInteger(read_data(0), 16);
       writeString_P("\n\n\r");
       while(1)
       {
          status=read_data(2);
          if(status & 128) // Bewegung erkannt?
          {
             writeString_P("Status: ");       // wenn Bit7 gesetzt ist
             writeInteger(status, 16);
             writeString_P(" x:  ");
             writeInteger(read_data(3), 10);  // können die eingefrorenen Deltawerte
             writeString_P(" y:  ");          // für x und y ausgelesen werden.
             writeInteger(read_data(4), 10);
             writeString_P("\n\r");
          }
          sleep(255);
       }
       return(0);
    }
    (Aus http://www.roboternetz.de/phpBB2/zei...=421130#421130)

    Mit write_data() sendet man einen 16bit-Wert, Bit15-8 sind die Schreibadresse, Bit15 muss bei einem Kommando zusätzlich gesetzt sein. Bit7-0 ist das Datenbyte. Mit read_data() wird ein Wert von einer Adresse gelesen.

    Wenn der Takt low ist werden die jeweiligen Daten bereitgestellt, mit einem high auf dem Takt werden sie gelesen.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Hier erstmal die schnelle Antwort ohne großes Überprüfen deines Codes:
    Code:
      for (i=0; i<8; i++)
      {
        SCK_Low();
       Delay1us(2);
       if (data1 & mask)
       {
         SCK_High();
       }
       else
       {
         SCK_Low();
       }
       Delay1us(2);
       mask >>= 1;
      }
    SPI ist eine synchrone Datenübertragung bei der ein Partner (der Master?) den gemeinsamen Takt vorgibt. Wenn der Takt low ist kann der sendende Partner das ensprechende Datenbit an seinem Ausgang bereitstellen, der Takt soll solange low bleiben bis der Sender seinen Datenpegel (high oder low)sicher ausgibt. Die minimale Zeit steht im Datenblatt, größere Werte verlangsamen die Übertragung, machen sie aber sicherer. Wenn das Taktsignal ausbleibt oder zu langsam ist erzeugt der Mauschip einen Reset!

    Die Übertragung startet, wenn der Master den Takt auf high schaltet. Dann wird das Datenbit gelesen, der Empfängerpin muss dabei auf Eingang geschaltet sein. Nachdem das Bit gelesen und gespeichert wurde, wird der Takt wieder auf low gelegt, ein Bit wurde nun übertragen. Für die Länge des High-Takt gilt das selbe wie fürs Low. Am Ende der Übertragung ist der Takt immer low.

    In deiner Sendefunktion wird der Takt aus dem Datenbyte erzeugt, das ist natürlich nicht richtig. Schau dir nochmal meine Funktion an:
    Code:
    void write_data(uint16_t data)
    {
       uint8_t bit=16;
       while(bit--) 	  // 16 Datenbits nacheinander Senden (MSB zuerst)
       {
          if(data & (1<<bit)) {data_h;} else {data_l;} // Datenbit an Ausgang ausgeben
           sleep(5);   // Warten bis Datenpegel sicher ausgegeben wird
          clk_h;       // Maus darf jetzt lesen
            sleep(5);  // Maus liest Datenbit
          clk_l;       // fertig, nächstes Datenbit vorbereiten
           sleep(5);   // warten bis Taktpegel sicher low ist
       }
       data_z;         // Datenpin als Eingang ohne internen PullUp
       sleep(20);      // Angstverzögerung
    }
    Gruß

    mic

    [Edit]
    Ähm, das ist die Anwort auf den von dir inzwischen wieder gelöschten Beitrag. Ich lasse es aber trotzdem mal so stehen ;)

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    14.04.2010
    Beiträge
    10
    [Edit]
    Ähm, das ist die Anwort auf den von dir inzwischen wieder gelöschten Beitrag. Ich lasse es aber trotzdem mal so stehen
    Ja Sry, kurz nach dem POST hatte ich einen großen Fehler schon entdeckt (das ich ja gar nicht mein MISO ein und ausschalte...das habe ich jetzt fix korrigiert und ich denke der WRITE ist jetzt so richtig (hoffentlich) an den Reead muss ich gefühlt nochmal ran...weil ich da auch immernoch nix bekomme.



    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    
    #define F_CPU 4000000UL
    #define ADNS_PORT	PORTB
    #define ADNS_DDR	DDRB
    #define ADNS_PIN	PINB
    #define ADNS_SCK	7	// Pinnumber für SCK vom ATMega32
    #define ADNS_MISO	6	// Pinnumber für MISO vom ATMega32
    #define ADNS_MOSI	5	// Pinnumber für MOSI vom ATMega32
    	
    #define ADNS_CONFIG				0x00
    #define ADNS_STATUS				0x01
    #define ADNS_DY					0x02
    #define ADNS_DX					0x03
    #define ADNS_SQUAL				0x04
    #define ADNS_MAX_PIXEL			0x05
    #define ADNS_MIN_PIXEL			0x06
    #define ADNS_PIXEL_SUM			0x07
    #define ADNS_PIXEL_DATA			0x08
    #define START_OF_FRAME			0x80
    #define VALID_DATA				0x40
    
    void SCK_High (void);
    void SCK_Low (void);
    
    void USART_Init (void) ;
    void USART_Transmit (unsigned char data) ;
    
    void ADNS_Init (void) ;
    void ADNS_Transmit (unsigned char data1) ;
    unsigned char ADNS_Receive(void);
    void ADNS_Write (unsigned char adr, unsigned char data) ;
    unsigned char ADNS_Read (unsigned char adr) ;
    void ADNS_Pulse (void) ;
    void Delay1ms (unsigned int time) ;
    void Delay1us (unsigned int time) ;
    
    
    void SCK_High (void)
    {
      ADNS_PORT |= (1<<ADNS_SCK);
    }
    
    void SCK_Low (void)
    {
      ADNS_PORT &=~ (1<<ADNS_SCK);
    }
    
    //*********************Def's für die UART Verbindung
    void USART_Init (void)
    {
      
      UBRRL = F_CPU / (16 * 9600UL) - 1; 
      UCSRB = (1<<RXEN) | (1<<TXEN) ;
      UCSRC = (1<<URSEL) | (1<<USBS) | (3<<UCSZ0) ;
    }
    
    void USART_Transmit (unsigned char data0)
    {
      while ( !(UCSRA & (1<<UDRE)) ) ;
      UDR = data0 ;
    }
    
    //*******************Def's für die SPI Verbindung zum ADNS
    void ADNS_Init (void)
    {
      ADNS_DDR |= (1<<ADNS_SCK) | (1<<ADNS_MOSI); 	//Setzt PortB auf 0b10100000 also PB7 und PB5 als Ausgang => für Read?
      SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);		//Müssen CPOL und CPHA gesetzt werden?
    }											
    
    /*
    void ADNS_Transmit (unsigned char data1)		// überträgt data1 per spi an den adns
    {
      SPDR = data1;
      while(!(SPSR & (1<<SPIF)));					//brauch ich angeblich gar nicht?
    }
    
    char ADNS_Receive (void)
    {
      while(!(SPSR & (1<<SPIF)));
      return SPDR;									//Stattdessen soll das so aussehen
    }
    */
    void ADNS_Transmit (unsigned char data1)
    {
      unsigned char i,mask;
      mask=0b10000000;
    
      for (i=0; i<8; i++)
      {
        SCK_Low();						// Clock Low= Sensor bereit zum beschreiben
    	Delay1us(2);
    	if (data1 & mask)				// Wenn Datenbit und Datenstelle (mask) 1 wird MOSI auf High gesetzt
    	{								// Datenstelle startet mit bit 0 und läuft bis bit 7
    	  ADNS_PORT |= (1<<ADNS_MOSI);
    	}
    	else
    	{
    	  ADNS_PORT &=~ (1<<ADNS_MOSI);
    	}
    	SCK_High();
    	Delay1us(2);
    	mask >>= 1;						// Datenstelle wird um 1 nach oben versschoben 0b00000001 wird zu 0b00000010
      }
      
    }
    
    unsigned char ADNS_Receive (void)
    {
      unsigned char i,mask,result;
      result = 0;
      ADNS_PORT |= ADNS_MOSI; //Setzt Mosi port auf 1, aber ist das nicht sowieso von der Init auf 1??? brauch ich das?
      mask = 0b10000000;
      for (i=0; i<8; i++)
      {
        SCK_Low();
    	Delay1us(2);
    	SCK_High();
    	Delay1us(2);
    	if (bit_is_set(ADNS_PIN,ADNS_MOSI))
      	{
          result |= mask;
      	}
      	mask>>=1;
      }
      Delay1us(1);
      return result;
    }
     
    void ADNS_Pulse (void)
    {
      ADNS_PORT &=~(1<<ADNS_SCK);
      ADNS_PORT &=~(1<<ADNS_SCK);
      ADNS_PORT |= (1<<ADNS_SCK);
      ADNS_PORT |= (1<<ADNS_SCK);
     
    }
    
    void ADNS_Write (unsigned char adr, unsigned char data) 
    {
      ADNS_Transmit(adr | 0b10000000); 	//setzt bit 8 auf 1 zum schreiben zur adresse (bit0-3)
      Delay1us(150);
      ADNS_Transmit(data);
      Delay1us(150);
    }
    
    
    
    unsigned char ADNS_Read (unsigned char adr)			
    {
     char temp;
     ADNS_Transmit(adr);
     Delay1us(150);
     temp = ADNS_Receive();
     Delay1us(150);
     return temp;
    }
    
    
    
    void Delay1ms (unsigned int time)				
    {
     while(time--) _delay_ms(1);
    }
    
    
    void Delay1us (unsigned int time)
    {
     while(time--) _delay_us(1);
    }
    
    
    
    int main (void)
    {
      char send;
      USART_Transmit('A');
      USART_Init ();
      USART_Transmit('B');
      Delay1ms(500);
      ADNS_Init ();
      ADNS_Pulse (); 
      USART_Transmit('C');
      Delay1ms(500);
      ADNS_Write (ADNS_CONFIG , 0x80);
      USART_Transmit('D');				 //SOFT RESET
      Delay1ms(1000);
      ADNS_Write (ADNS_CONFIG , 0x01); //Always AWAKE
      USART_Transmit('E');
      Delay1ms(1000);
    
      while(1)
      {
      	USART_Transmit ('Y');
    	send = ADNS_Read (ADNS_DY);
    	USART_Transmit (send);
    	USART_Transmit ('X');
    	send = ADNS_Read (ADNS_DX);
    	USART_Transmit (send);
      }
    }

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    14.04.2010
    Beiträge
    10
    Komme leider trotz rumtüfteln und einigen Hilfestellungen von mare_crisium leider immernoch nicht zu meinem gewünschten Ergebniss. Muss ich eigentlich nicht dafür sorgen, das mein SCK Pegel lange gennug auf High bzw. Low steht? Oder muss ich nur beachten, das zwischen den übertragungen mindestens 100us liegen. Im Datenblatt steht, das SCK 250ns jeweils auf High dann auf low stehen soll, aber wie setzte ich das um?, Naja 250ns sind nicht grade lang
    Ich denke/hoffe das der Rest eigentlich ganz ok/brauchbar ist.

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    
    #define F_CPU 4000000UL
    #define ADNS_PORT	PORTB
    #define ADNS_DDR	DDRB
    #define ADNS_PIN	PINB
    #define ADNS_SCK	7	// Pinnumber für SCK vom ATMega32
    #define ADNS_MISO	6	// Pinnumber für MISO vom ATMega32 nicht benötigt
    #define ADNS_MOSI	5	// Pinnumber für MOSI vom ATMega32
    	
    #define ADNS_CONFIG				0x00
    #define ADNS_STATUS				0x01
    #define ADNS_DY					0x02
    #define ADNS_DX					0x03
    #define ADNS_SQUAL				0x04
    #define ADNS_MAX_PIXEL			0x05
    #define ADNS_MIN_PIXEL			0x06
    #define ADNS_PIXEL_SUM			0x07
    #define ADNS_PIXEL_DATA			0x08
    #define START_OF_FRAME			0x80
    #define VALID_DATA				0x40
    
    void SCK_High (void);
    void SCK_Low (void);
    
    void USART_Init (void) ;
    void USART_Transmit (unsigned char data) ;
    
    void ADNS_Init (void) ;
    void ADNS_Transmit (unsigned char data1) ;
    unsigned char ADNS_Receive(void);
    void ADNS_Write (unsigned char adr, unsigned char data) ;
    unsigned char ADNS_Read (unsigned char adr) ;
    void Delay1ms (unsigned int time) ;
    void Delay1us (unsigned int time) ;
    
    
    void SCK_High (void)
    {
      ADNS_PORT |= (1<<ADNS_SCK);
    }
    
    void SCK_Low (void)
    {
      ADNS_PORT &=~ (1<<ADNS_SCK);
    }
    
    //**************************************************Def's für die UART Verbindung
    void USART_Init (void)
    {
      
      UBRRL = F_CPU / (16 * 9600UL) - 1; 
      UCSRB = (1<<RXEN) | (1<<TXEN) ;
      UCSRC = (1<<URSEL) | (1<<USBS) | (3<<UCSZ0) ;
    }
    
    void USART_Transmit (unsigned char data0)
    {
      while ( !(UCSRA & (1<<UDRE)) ) ;
      UDR = data0 ;
    }
    
    //******************************************Def's für die SPI Verbindung zum ADNS
    void ADNS_Init (void)
    {
      ADNS_DDR |= (1<<ADNS_SCK);				//Setzt SCK als Ausgang
      ADNS_DDR &=~ (1<<ADNS_MOSI);				//Setzt MOSI als Eingang
      ADNS_PORT |= (1<<ADNS_SCK);				//Setzt SCK signal auf High
      ADNS_PORT &=~ (1<<ADNS_MOSI);				//Setzt Mosi Port nauf 0 also Hi-Z
      //SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);	//Müssen CPOL und CPHA gesetzt werden?
    }											//SPI wird ja voll simuliert also INIT nur für erste											
    											//DDR und PORT Einstellung
    
    void ADNS_Transmit (unsigned char data1) 
    {						//Nach Transmit SCK=High MOSI=Input MOSIPORT=0 ==> HI-Z
      unsigned char i,mask;
      mask=0b00000001;				  //Start der Übertragung mit Bit 0<<<
      ADNS_DDR |= (1<<ADNS_MOSI);	  //Stellt sicher das DDR vom MOSI als Output ist
      ADNS_PORT &=~ (1<<ADNS_MOSI);	  //und kein Strom am Ausgang anliegt (low)
      for (i=0; i<8; i++)
      {
        SCK_Low();					  //Clock Low
    	Delay1us(2);
    	if (data1 & mask)			  //Wenn Datenbit und Datenstelle (mask) 1 wird
    	{							  //MOSI auf High gesetzt
    	  ADNS_PORT |= (1<<ADNS_MOSI);//Datenstelle startet mit bit0 und läuft bis bit7
    	}
    	else
    	{
    	  ADNS_PORT &=~ (1<<ADNS_MOSI);
    	}
    	SCK_High();					  //ADNS holt Daten bei Steigender SCK Flanke
    	Delay1us(2);				
    	mask >>= 1;					  //Datenstelle wird versschoben 0x01 wird zu 0x02
      }
      ADNS_DDR &=~ (1<<ADNS_MOSI);	  //Setzt DDR_MOSI als Input also MOSI->MISO zum Ende
      ADNS_PORT &=~ (1<<ADNS_MOSI);	  //PORT vom Mosi auf 0 ==> Hi-Z
    }
    
    unsigned char ADNS_Receive (void) 
    {						//Nach Receive SCK= High   MOSI=Input  MOSIPORT=1
      unsigned char i,mask,result;
      result = 0;
      ADNS_DDR &=~ (1<<ADNS_MOSI); 	  //Setzt DDR vom MOSI als INPUT -> MISO Empfang
      ADNS_PORT |= (1<<ADNS_MOSI);	  //Setzt Port auf 1->als Eingang und nicht als Hi-Z
      mask = 0b00000001;			  //Initialisiert die Maske auf Bit0
      for (i=0; i<8; i++)
      {
    	SCK_High();						   //uC Ließt Daten ein
    	if (bit_is_set(ADNS_PIN,ADNS_MOSI))//wenn an MOSI(MISO) 5v anliegen schreibt die 
      	{								   //schleife an Bitpositionder Maske eine 1 result
          result |= mask;
      	}
    	SCK_Low();					//ADNS stellt jetzt neue Daten bereit
      	mask>>=1;
      }
      Delay1us(1);
      SCK_High();					//Setzt Clock zum Ende hin auf High? Ist das ok so?
      ADNS_PORT &=~ (1<<ADNS_MOSI);	//So ist nach jedem Receive oder Transmit immer gleich
      return result;				//SCK auf High Mosi auf Input und Hi-Z da MosiPort auf 0
    }
     
    
    
    void ADNS_Write (unsigned char adr, unsigned char data) 
    {
      ADNS_Transmit(adr | 0b10000000); 	//SETZT MSB auf 1 und somit R/W auf 1 und Verbindet dies mit der Registeradresse
      Delay1us(150);					//oder müssen bit8 und bit7 auf 1 also 0b11000000
      ADNS_Transmit(data);				//Also sollte die Maus jetzt bereit sein ein Datenbyte zu empfangen
      Delay1us(150);					//Datenbyte wird genauso übermittelt, wie schon vorher das Registeradressbyte
    }									//nur das jetzt volle 8Bits für DAten zu verfügung stehen und kein R/W und MSB
    									//Lieber einmal zuviel Pause als einmal zu wenig
    
    
    unsigned char ADNS_Read (unsigned char adr)			
    {
     char temp;
     ADNS_Transmit(adr); 				//Die Adressen alleine haben immer MSB auf 0, jetzt sollte also der ADNS
     Delay1us(150);						//die Daten bereitstellen (eigentlich nur 100us aber 150 sind wir auf der sicheren)
     temp = ADNS_Receive();				//Im Receive wird jetzt der MOSI Pin als Eingang konfiguriert und mittels wechselndem SCK
     Delay1us(150);						//von High auf Low (Fallende Flanke) vom uC eingelesen.
     return temp;
    }
    
    
    
    void Delay1ms (unsigned int time)				
    {
     while(time--) _delay_ms(1);
    }
    
    
    void Delay1us (unsigned int time)
    {
     while(time--) _delay_us(1);
    }
    
    
    
    int main (void)
    {
      unsigned char send;
      USART_Init ();
      Delay1ms(100);
      ADNS_Init ();	    //wird bis auf DDR vom SCK eigentlich nicht benötigt da SPI simuliert wird
      Delay1ms(100);
      ADNS_Write (ADNS_CONFIG , 0x80);
      Delay1ms(500);
      ADNS_Write (ADNS_CONFIG , 0x01); //Always AWAKE
      Delay1ms(500);
    
      while(1)
      {
      	USART_Transmit ('Y');
    	send = ADNS_Read (ADNS_DY);
    	USART_Transmit (send);
    	USART_Transmit ('X');
    	send = ADNS_Read (ADNS_DX);
    	USART_Transmit (send);
      }
    }

Berechtigungen

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