-
        

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 23

Thema: ATmega > DAC (SPI Problem)

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    21.08.2011
    Beiträge
    18

    Frage ATmega > DAC (SPI Problem)

    Anzeige

    Seid gegrüßt,

    im Rahmen eines Projektes beschäftige ich mich derzeit mit der
    Ansteuerung eines AD5624R mit Hilfe eines ATmega168 über die SPI
    Schnittstelle.

    An sich soll das Ganze ja sehr einfach gehen mit SPI, jedoch beiße ich
    mir derzeit einwenig die Zähne daran aus.

    Die Signale auf den SPI bekomme ich schon (mittels Oszi überprüft), aber
    eine Reaktion seitens des DAC bleibt leider aus.

    Die beiden Bilder zeigen das Oszibild für eine SPI Übertragung. Einmal
    CLK+Data und einmal SS+Data.

    Hier nun vllt die Codeschnipsel, die jeden interessieren sollten:

    Code:
    void PORTS_init() 
    {
      DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB5);      // LED , SPI::MOSI/CLK
      DDRC |= (1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4);  // SPI::SS1...4 outputs
      PORTC |= (1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4);  // all high
    }
    
    void SPI_MasterInit(void) 
    {
      SPCR |= (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0) | (0<<CPOL) | (0<<DORD) | (1<<CPHA);
    }
    
    void SPI_Master_to_DAC_send(uint8_t mode, uint8_t dac, uint16_t wert) 
    {
      uint8_t byte0 = 0x0;
      uint8_t byte1 = 0x0;
      uint8_t byte2 = 0x0;
     
      switch( mode ) 
      {               
        case 0: byte0 |= 0x0; break;  // write to input register n
        case 1: byte0 |= 0x8; break;  // update dac register n  
        case 2: byte0 |= 0x10; break;  // write to input register n, update all
        case 3: byte0 |= 0x18; break;  // write to and update dac channel n
      }
      switch( dac ) 
      {                 
        case 0: byte0 |= 0x0; break;  // DAC A
        case 1: byte0 |= 0x1; break;  // DAC B
        case 2: byte0 |= 0x2; break;  // DAC C
        case 3: byte0 |= 0x3; break;  // DAC D
        case 4: byte0 |= 0x7; break;  // ALL DAC    
      }
    
      byte1 = (wert>>4);
      byte2 = (wert<<4);
    
      PORTC &= ~(1<<PC4);
      SPI_MasterSend( byte0, byte1, byte2 );
      _delay_us(5);
      PORTC |= (1<<PC4);
    }
    
    void SPI_MasterSend(char cData0, char cData1, char cData2) 
    {  
      cli();
      SPDR = (uint8_t)cData0; 
      while(!(SPSR & (1<<SPIF)));
      SPDR = (uint8_t)cData1; 
      while(!(SPSR & (1<<SPIF)));
      SPDR = (uint8_t)cData2; 
      while(!(SPSR & (1<<SPIF)));
      sei();
    }
    Initialisieren tu ich den DAC mit einem kompletten Reset, einschalten
    der internen Referenz sowie setzen des LDAC für alle Outputs auf 1.

    Sende ich nun ein SPI_Master_to_DAC_send() mit einem Wert, so passiert
    nichts. Habe nun schon alle Modi durchprobiert.

    Kann mir jemanden eine Hilfestellung liefern?

    Beste Grüße,
    Robert
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken IMG_0753.jpg   IMG_0752.jpg  
    Geändert von rrobert (21.08.2011 um 00:49 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Hast Du schon mal nachgeguckt ob Deine Clock Polarity Clock Phase und Data Order einstellungen für den AD5624 Chip passen?
    Hast Du in deiner Routine das /SS Signal per Software! bedient ( Bei der Einstellung als Master muss das per Software erledigt werden ) .
    Wenn ich probleme mit der SPI hab, dann schreib ich mal schnell de software SPI routine - ist ja nicht besonders schwierig.
    Wenn Die dann geht, dann weiß ich zumindest, das es von der Hardware her passt und der Fehler nur noch bei den Einstellwerten für die SPI liegen kann.
    Dann kann man mit den Parametern der SPI noch mal rumspielen und kriegt es dann meistens auch hin.
    Manche Chips lassen sich überhaupt nicht per Hardware SPI ansprechen, z.B. wenn Sie eine vom 8 Bit Raster ( also 8, 16, 24, 32Bit ) abweichende Bitbreite am SPI Bus haben ( ja es gibt so was! ).
    Wenn man mal die richtigen einstellungen für die SPI gefunden hat, funktioniert es in der Regel problemlos.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    21.08.2011
    Beiträge
    18
    Ich bin mittlerweile der Meinung so ziemlich jede Einstellung ausprobiert zu haben, jedoch ohne Erfolg.

    Welche SPI Einstellung würdest du Anhand des Datasheet des AD5624 denn wählen? (Das Datasheet habe ich der Modellbezeichnung angehängt (einfach auf den Link klicken)

    Und zum /SS. Den habe ich standardmäßig als Output definiert und dann zusätzlich vor jeder Übertragung noch auf high gesetzt (was laut Datasheet des ATmega168 aber nicht nötig sein soll, da es keine Auswirkung haben soll, wenn der SS/ als Output definiert ist). An dem SS/ Pin des ATmega168 ist bei meinem Crumb128 auch eine LED angeschlossen, die leuchtet, wenn in den Pin auf 0 setze,

  4. #4
    Moderator Roboter Genie
    Registriert seit
    26.08.2004
    Beiträge
    1.228
    Hallo rrobert,

    im Prinzip schaut die Ansteuerung des "SYNC" Pins gut aus. Er muss auf Low gezogen werden, bevor die Ausgabe an "SCLK" beginnt und dann erst nach dem letzten Clock-Impuls wieder auf High gebracht werden.
    Es kann sein, dass die Zeit zwischen dem Wechsel an SYNC und dem ersten Clock-Impuls zu kurz ist. Wobei die min. Zeit mit 13ns angegeben ist und der Fall daher unwahrscheinlich.

    Ich mache bei der SPI-Kommunikation immer erst einen Versuch über eine Software-SPI bevor ich auf Hardware-SPI umsteige. Das hat den Vorteil, dass du alle Pins so wackeln kannst, wie im Datenblatt vorgegeben. Die Verwirrung mit CPOL usw. kann man so erstmal umgehen und weiß, dass der Chip und Kommunikation funktioniert.

    Gruß
    Basti

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    21.08.2011
    Beiträge
    18
    Wie genau erziele ich mit dem Software SPI eine Vorteil gegenüber dem Hardware SPI? Hast du vllt einen Link zu einem Software SPI?

    Zu den Timings. Der ganze uC läuft bei 8MHz und die SPI Clock Rate ist bei fck/128. Also wirklich das Langsamste, was irgendwie möglich ist (hatte die Überlegung, dass so vllt die wenigsten Probleme auftreten).

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.544
    Wie sieht die Schaltung aus? Hast du die Referenz angeschlossen bzw kannst du da eine Spannug messen? Eventuell hast du keine Verbindung (vergessen bzw kalte Lötstelle,...)

    MfG Hannes

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    21.08.2011
    Beiträge
    18
    Ich habe keine Referenz angeschlossen. Habe diese jedoch in der Initialisierung auf "Intern ON" gestellt und kann sie messen (2,48V).

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    21.08.2011
    Beiträge
    18

    Frage

    Wie schaut es mit der Übertragung der einzelnen Byte des 24bit Wortes aus? Wie verhält sich so ein Shiftregister da? Ich sende ja das erste Byte, dann das Zweite, dann das Dritte. Jeweils mit dem MSB "links".

    Derzeit versende ich ja das Paket mit dem MSB first und das Byte_high zuerst. Das könnte mit dem Datenblattinfos kollidieren, oder?

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.544
    Du hast zwar das falsche DB vom DAC gepostet, habe aber das richtige schon gefunden. Du hast das DB vom AD5624 nicht vom 5624R gepostet.

    Ich habe im DB vom Atmega geschaut. Laut diesem DB steht das CPHA Bit für die Phase der Clockimpulse (Rising oder Falling Edge). Du hast dieses Bit auf 1 gestellt, laut DB ist das für rising edge. Beim DAC steht aber drinnen das die Daten bei falling edge übernommen werden. Versuche einmal in der Init Routine das CPHA auf 0 zu schalten (bzw lassen).

    Hier ist das richtige DB vom DAC http://www.analog.com/static/importe...644R_5664R.pdf

    MfG Hannes

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    21.08.2011
    Beiträge
    18
    Okay. Das habe ich nun versucht.

    Mein SPI schaut wie folgt aus:

    Code:
    void SPI_MasterInit(void) {
    	// Set /SS, MOSI and SCK output, all others input 
    	DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);				// SS, MOSI, CLK are Outputs
    	//PORTB &= ~(1<<PB2);								// LED on (PB2 low)
    	
    	DDRC = (1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4);		// SPI::SS1...4 outputs
    	PORTC = (1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4);	// all high
    	// Enable SPI, Master, MSB first, SPI Mode 1, set clock rate fck/128
    	SPCR |= (1<<SPE) | SPI_MSB_1 | (1<<MSTR) | SPI_MODE_0 | SPI_SPEED_128;
    }
    Code:
    void SPI_MasterSend(char high, char mid, char low) {
    	
    	PORTB |= (1<<PB2);				// SS is set high, effects that LED is off				
    	cli();
    	_delay_us(5);
    	SPDR = high; 
    	while(!(SPSR & (1<<SPIF)));
    	SPDR = mid; 
    	while(!(SPSR & (1<<SPIF)));
    	SPDR = low; 
    	while(!(SPSR & (1<<SPIF)));
    	_delay_us(5);
    	sei();
    	PORTB &= ~(1<<PB2);				// SS is set low, effects that LED is on
    }
    Code:
    void SPI_Master_to_DAC_send(uint8_t mode, uint8_t dac, uint16_t wert) {
    	
    	uint8_t byte_high = 0x0;
    	uint8_t byte_mid = 0x0;
    	uint8_t byte_low = 0x0;
    	char dac_buf[128];					// Buffer für Konsolenausgabe-String
    
    	switch( mode ) 
    	{ 							
    		case 0: byte_high |= 0x0; break;	// write to input register n
    		case 1: byte_high |= 0x8; break;	// update dac register n	
    		case 2: byte_high |= 0x10; break;	// write to input register n, update all
    		case 3: byte_high |= 0x18; break;	// write to and update dac channel n
    	}
    	switch( dac ) 
    	{ 								
    		case 0: byte_high |= DAC_A; break;
    		case 1: byte_high |= DAC_B; break;
    		case 2: byte_high |= DAC_C; break;
    		case 3: byte_high |= DAC_D; break;
    		case 4: byte_high |= DAC_ALL; break;
    	}
    
    	byte_mid = (wert>>4);
    	byte_low = (wert<<4);
    
    	PORTC &= ~(1<<PC1);
    	SPI_MasterSend( byte_high, byte_mid, byte_low );
    	PORTC |= (1<<PC1);
    	sprintf( dac_buf, "## SYSTEM ## DAC Data send (%d)(%d[%d][%d])\n\r", byte_high,wert,byte_mid,byte_low);
    	UART_puts(dac_buf);
    }
    Code:
    #define SPI_MODE_0		( (0<<CPOL) | (0<<CPHA) )
    #define SPI_MODE_1		( (0<<CPOL) | (1<<CPHA) )
    #define SPI_MODE_2		( (1<<CPOL) | (0<<CPHA) )
    #define SPI_MODE_3		( (1<<CPOL) | (1<<CPHA) )
    #define SPI_MSB_1		( (0<<DORD) )
    #define SPI_LSB_1		( (1<<DORD) )
    #define SPI_SPEED_64	( (1<<SPR1) | (0<<SPR0) )
    #define SPI_SPEED_128	( (1<<SPR1) | (1<<SPR0) )

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. ATMEGA 8 - Problem!
    Von mikro-VIIV im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 30.10.2008, 14:02
  2. PWM problem mit Atmega 8
    Von Enterprise im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 22.08.2008, 01:56
  3. I2C/TWI und ATmega 8 Problem
    Von cpinkle im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 25.10.2006, 21:02
  4. ATMEGA 128 SPI Problem
    Von schmidtkoe im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 01.10.2006, 20:23
  5. Atmega 16 Problem
    Von Ringo im Forum Elektronik
    Antworten: 10
    Letzter Beitrag: 07.05.2005, 19:42

Berechtigungen

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