logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[BASCOM] PAN3101 oblsuga (tlumaczenie z c)

wader_669 16 Sie 2009 21:29 3118 6
REKLAMA
  • #1 6900427
    wader_669
    Poziom 28  
    Pisze obsluge czujnika pan3101DB z myszki optycznej.
    Z tego powodu, ze dokladnie nie wiem jaka to transmisja staralem sie sam napisac obsluge.
    Pomogly mi te strony:
    http://www.rn-wissen.de/index.php/Maussensor (tlumaczylem prawie 1 w 1 na bascom)
    i nota:
    http://www.pixart.com.tw/upload/PAN3101_V10_20051121170653.pdf

    lecz program nadal nie dziala.
    Moze ma ktos juz doswiadczenie z tymi ukladami w bascomie
    lub chociaz znajdzie sie ktos kto zna bascom i c ?

    
    $regfile = "m32def.dat"
    $crystal = 8000000
    
    $swstack = 200
    $hwstack = 200
    $framesize = 200
    
    Config Lcdpin = Pin , Db4 = Porta.5 , Db5 = Porta.4 , Db6 = Porta.3 , Db7 = Porta.2 , E = Porta.6 , Rs = Porta.7
    
    Config Pinc.1 = Output                                      'sda jak output
    Config Pinc.0 = Output                                      'scl jak outpu
    
    Sda Alias Portc.1                                           'portc.1 =sda
    Scl Alias Portc.0                                           'portc.0=scl
    
    
    Sda = 1                                                     'sda stan wysoki
    Scl = 1                                                     'scl stan wysoki
    
    Declare Sub Pan_write(byval Address As Byte , Byval Zmienna As Byte)
    Declare Sub Pan_read(byval Address1 As Byte , Zmienna1 As Byte)
    
    Declare Sub Pan_writebyte(byval I2c_write As Byte)
    Declare Sub Pan_readbyte(i2c_read As Byte)
    
    Dim Status As Byte
    Dim X As Byte
    Dim Y As Byte
    
    Cursor Off
    Cls
    Locate 1 , 1
    Lcd "0"
    Call Pan_write(&H00 , &H80)
    Call Pan_write(&H00 , &H01)
    
    Do
    
    Call Pan_read(&H16 , Status)
    
    If Status.7 = 1 Then
    
     Call Pan_read(&H17 , X)
     Call Pan_read(&H18 , Y)
    
    Cls
    Locate 1 , 1 : Lcd "X: " : Lcd X
    Locate 2 , 1 : Lcd "y: " : Lcd Y
    
    End If
    
    Loop : End
    
    Sub Pan_write(byval Address As Byte , Byval Zmienna As Byte)
    
    Address.7 = 1                                               ' ustaw bit 7 wysylanego bitu jako 1 zeby bylo wiadomo ze bedziemy zapisywac
    Call Pan_writebyte(address)
    Call Pan_writebyte(zmienna)
    
    End Sub
    
    Sub Pan_read(byval Address1 As Byte , Zmienna1 As Byte)
    
    Call Pan_writebyte(address1)
    Call Pan_readbyte(zmienna1)
    
    End Sub
    
    Sub Pan_writebyte(byval I2c_write As Byte)
    Local I As Byte
    
       For I = 7 To 0 Step -1                                   'petla zeby odebrac 8 bitow
       Scl = 0                                                  'scl ustaw jako 0
       Sda = I2c_write.i                                        'ustaw na wyjscie sda taki stan jak jest zapisany w bicie
       Scl = 1                                                  'scl ustaw jako 1
       Waitus 1                                                 'poczekj 1 mikrosekunde
       Next
    
    End Sub
    
    
    Sub Pan_readbyte(i2c_read As Byte)
    Local I As Byte
    
       Config Pinc.1 = Input                                    'sda ustak jako wejscie
       Sda = 1                                                  'ustaw pull up
       Waitus 3                                                 'poczekaj 3 mikrosekundy
    
    For I = 7 To 0 Step -1                                      'petla zeby odebrac 8 bitow
    
       Scl = 0                                                  'scl na 0
       Waitus 1                                                 'czekaj 1 mikrosekunde
       Scl = 1                                                  ' scl na 1
       I2c_read.i = Pinc.1                                      'zapisz w zmiennej stan jaki jest na pinc.1 (sda)
    
    Next
    
    Config Pinc.1 = Output                                      ' ustaw znowu jako wyjscie
    Sda = 0                                                     ' ustaw sda na 0
    
    End Sub
    


    kod w c

    
    #define DDR_SCK 	DDRB			/*!< DDR fuer Maus-SCLK */
    #define DDR_SDA 	DDRA			/*!< DDR fuer Maus-SDA  */
    
    #define PORT_SCK	PORTB			/*!< PORT fuer Maus-SCK  */
    #define PORT_SDA	PORTA			/*!< PORT fuer Maus-SDA  */
    #define PIN_SDA		PINA			/*!< PIN fuer Maus-SDA  */
    
    #define SCK_PIN		(1<<PB0)		/*!< PIN nummer fuer Maus-SCK  */
    #define SDA_PIN		(1<<PA0)		/*!< PIN nummer fuer Maus-SDA  */
    
    
    /*!
     * Uebertraegt ein Byte an den Sensor
     * @param data das Byte
     */
    void pan_writeByte(unsigned char data){
    	signed char i;
    	
    	DDR_SDA|= SDA_PIN; 		        // SDA auf Output
    	
    	for (i=7; i>=0; i--){
    	
    		PORT_SCK &= ~SCK_PIN;		//SCK auf Low, Daten vorbereiten
    		
    		if(data&(1<<i)){		//Bit rausschieben
    			PORT_SDA|=SDA_PIN;
    		}else{
    			PORT_SDA&=~SDA_PIN;		
    		}
    		
    		PORT_SCK |= SCK_PIN;		// SCK =1 Sensor uebernimmt auf steigender Flanke
    		
    		_delay_us(1);			//Sensor Zeit lassen um Bit zu holen
    	}
    
    	DDR_SDA &=~ SDA_PIN;			//HI-Z state
    	PORT_SDA &=~ SDA_PIN;
    		
    }
    
    /*!
     * Liest ein Byte vom Sensor
     * @return das Byte
     */
    unsigned char pan_readByte(void){
    signed char i;
    unsigned char data=0;
    	
    	_delay_us(3);				//Sensor Zeit lassen um die Daten aus dem Register zu holen
    
    	for (i=7; i>-1; i--){
    		PORT_SCK &= ~SCK_PIN;		// SCK =0 Sensor bereitet Daten auf fallender Flanke vor !
    			
    		_delay_us(1);			//Sensor kurz Zeit lassen
    		
    		
    		PORT_SCK |= SCK_PIN;		// SCK =1 Daten lesen  auf steigender Flanke		
    		
    		if(PIN_SDA&SDA_PIN){ 		//BIT einlesen
    			data |= (1<<i);			
    		}else{
    			data &=~ (1<<i);			
    		}			
    
    	}
    	return data;
    }
    
    /*!
     * Uebertraegt ein write-Kommando an den Sensor
     * @param adr Adresse
     * @param data zu schreibendes byte
     */
    void pan_write(unsigned char adr, unsigned char data){
    	adr|=(1<<7);
    	pan_writeByte(adr);  //rl MSB muss 1 sein für Write Operation
    	pan_writeByte(data);
    }
    
    
    
    /*!
     * Schickt ein Lesekommando an den Sensor
     * und liest ein Byte zurueck
     * @param adr die Adresse
     * @return der registerwert
     */
    unsigned char pan_read(unsigned char adr){
    
    	pan_writeByte(adr);
    	return pan_readByte();
    }
    
    
    /*! 
     * Initialisiere PAN3101
     
     !! Muss unbedingt ganz am ANFANG von main stehen, sonst gibts FEHLER !!
     (wenn der PAN3101 sich initialisiert hat, bevor der Controler SCK und 
     SDA auf Output gestellt hat)
     Deshalb kann es auch sinnvoll sein die Powerup Zeit in den Config Bits 
     auf 4ms zu stellen oder noch besser mit Boden zu arbeiten.
     
     */ 
    void pan_init(void){
    
    	DDR_SCK  |= SCK_PIN; 	// SCK auf Output
    	DDR_SDA |= SDA_PIN;		//SDA auf Output
    
    	PORT_SCK |= SCK_PIN;	// SCK auf high	
    	PORT_SDA|= SDA_PIN;		//SDA auf high
    
    // hier muessen bei Umstellung auf PAN101 die entsprechenden Register gesetzt werden
    //Reset PAN3101
    	pan_write(0x00,0x80);
    // kein Sleep modus
    	pan_write(0x00,0x01);	
    }
    
    
    int main(void){
    
    unsigned char ino;
    signed char x,y;
    signed short posx=0,posy=0;
    
    //ganz an den Anfang damit der Controller schneller asl der PAN ist um Fehler zu vermeiden
    pan_init();
    //Individuelle Port Configuration und Initialisierung
    initialisierung();
    
    lcd_init(LCD_DISP_ON);
    lcd_clrscr();
    
    while(1){
    
            //Endlosschleife
    
    	ino=pan_read(0x16);
    
    	//wenn 7tes bit vom Register 0x16 gesetzt ist wurde die Maus bewegt => Bewegungsdaten abfragen
    	if(ino&(1<<7)){		
    		//Deltax Register auslesen
    		x=pan_read(0x17);
                    //und zu der Positionvariable addieren
    		posx=posx+x;
    	        
                    /* Nachschaun ob das Ueberlauf-Bit im Register 0x16 gesetzt ist 
                       wenn das der Fall ist muss je nach Vorzeichen der Deltax Variable x
                       noch 128 (Ueberlauf nach oben) dazugezaehlt oder eben 128 abgezogen werden
                    */
    		if(ino&(1<<3)){
    			if(x<0){
    				posx-=128;
    			}else{
    				posx+=128;
    			}
    		}
    		
                    //ab hier nochmal das Gleiche fuer die yRichtung
    
    		y=pan_read(0x18);
    		posy=posy+y;
    		
    		if(ino&(1<<4)){
    			if(y<0){
    				posy-=128;
    			}else{
    				posy+=128;
    			}
    		}
    	
    	}
    	
                    //hier kann jeder seine Ausgabevariante selber waehlen ;) 
                    
    		lcd_ausgabe_int(0,3,posx);
    		lcd_ausgabe_int(7,3,posy);
    	
    }
    
    return 0;
    }
    


    Zdjecia z noty.
    Tu jak wyglada transmisja:

    [BASCOM] PAN3101 oblsuga (tlumaczenie z c)

    Jak powino wygladac zapisywanie (pierw leci rejestr ktory chcemy zapisac. Bit 7 tego rejestru musib byc 1, wtedy pan3103 wie, ze chcemy cos zapisac)

    [BASCOM] PAN3101 oblsuga (tlumaczenie z c)

    Tu jest odbior.

    [BASCOM] PAN3101 oblsuga (tlumaczenie z c)

    Dodano po 19 [minuty]:

    Pare pytan na koniec:
    czy to jest i2c?
    musze podlaczyc rezystory podciagajace?
    potrzebny jest pullup jak odbieram dane?
  • REKLAMA
  • REKLAMA
  • #3 6900672
    wader_669
    Poziom 28  
    znam. Porownaj nazwy userow.
    Ten temat jeszcze tutaj zalozylem, bo jestem zdania, ze na elektrodzie sa bardziej kompetentne osoby jak chodzi o programowanie.
  • REKLAMA
  • #4 6900675
    gothye
    Poziom 33  
    mi to wygląda na interfeis SPI
  • #5 6900697
    wader_669
    Poziom 28  
    No jest to niemozliwe.W Spi odbieranie i wysylanie jest na osobnych liniach. Tutaj jest to jedna i ta sama linia.
  • #6 6900714
    gothye
    Poziom 33  
    hmm ,wiać wyraznie że aby odczytać wysłasz pierwszy bit =1 i aby odczytać bit ten = 0 ,dalej mi to wygląda na SPI ,z tym ze jedna linia jest jednoczesnie I/O (in / out)
  • REKLAMA
  • #7 6902134
    wader_669
    Poziom 28  
    Jedna sprawa inicjalizacje i tym samym reset czujnika zrobilem w petli glownej. Poprawilem juz to w kodzie.
    2. sprawa pomylilem kabelki i wszystko dziala. :D
    Dziekuje za pomoc.
    Jak by ktos chcial kod to spokojnie moze go uzywac.
REKLAMA