Forum: Mikrocontroller und Digitale Elektronik DAC (TLV5616) gibt nichts aus


von HerrPitillo (Gast)


Lesenswert?

Hallo,
ich habe hier einen TLV5616 (ein Digital -> Analog Wandler), ich habe 
jedoch das Problem das er sich nicht ansteuern lässt. Um ihn zu testen 
hab ich ein Testprogramm für einen AVR geschrieben jedoch funktioniert 
es nicht. Am Ausgang des DAC´s ist bisher bis auf mein Multimeter nichts 
angeschlossen. Die Restliche verkabelung ist so ausgebaut:
MOSI ---- DIN
SCLK ---- SCLK
GND ----- CS
GND ----- GND
REFIN --- Spannungsteiler -> 2,6V
OUT ----- Multimeter
VDD ----- 5,2V

Das Datenblatt findet ihr hier:
http://www.ti.com/lit/ds/slas152d/slas152d.pdf

Und mein Code sieht wie folgt aus:
1
#define F_CPU 4000000UL
2
3
4
#include "spi.h"
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
int main(void)
9
{
10
  DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5);//ausgänge für SPI setzen
11
  setup_spi(SPI_MODE_2,SPI_MSB,SPI_NO_INTERRUPT,SPI_MSTR_CLK16);
12
  send_spi(0b01001111);// 4bit daten + control bits
13
  _delay_us(100);
14
  send_spi(0b11111111);// restlichen daten
15
  while(1)
16
    {
17
    }
18
}

Die SPI Lib sieht wie folgt aus (sie ist nicht von mir) :
SPI.h
1
/* 
2
 * Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to deal
6
 * in the Software without restriction, including without limitation the rights
7
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
 * copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 * 
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 * 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
 * THE SOFTWARE.
21
 */
22
#ifndef _spi_h__
23
#define _spi_h__
24
25
#include <avr/io.h>
26
27
#ifdef __cplusplus
28
extern "C"{
29
#endif
30
31
// create alias for the different SPI chip pins - code assumes all on port B
32
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__))
33
 #define SPI_SS_PIN PORTB0
34
 #define SPI_SCK_PIN PORTB1
35
 #define SPI_MOSI_PIN PORTB2
36
 #define SPI_MISO_PIN PORTB3
37
#elif (defined(__AVR_ATmega48__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega8__))
38
 #define SPI_SS_PIN PORTB2
39
 #define SPI_SCK_PIN PORTB5
40
 #define SPI_MOSI_PIN PORTB3
41
 #define SPI_MISO_PIN PORTB4
42
#else
43
 #error unknown processor - add to spi.h
44
#endif
45
46
// SPI clock modes
47
#define SPI_MODE_0 0x00 /* Sample (Rising) Setup (Falling) CPOL=0, CPHA=0 */
48
#define SPI_MODE_1 0x01 /* Setup (Rising) Sample (Falling) CPOL=0, CPHA=1 */
49
#define SPI_MODE_2 0x02 /* Sample (Falling) Setup (Rising) CPOL=1, CPHA=0 */
50
#define SPI_MODE_3 0x03 /* Setup (Falling) Sample (Rising) CPOL=1, CPHA=1 */
51
52
// data direction
53
#define SPI_LSB 1 /* send least significant bit (bit 0) first */
54
#define SPI_MSB 0 /* send most significant bit (bit 7) first */
55
56
// whether to raise interrupt when data received (SPIF bit received)
57
#define SPI_NO_INTERRUPT 0
58
#define SPI_INTERRUPT 1
59
60
// slave or master with clock diviser
61
#define SPI_SLAVE 0xF0
62
#define SPI_MSTR_CLK4 0x00 /* chip clock/4 */
63
#define SPI_MSTR_CLK16 0x01 /* chip clock/16 */
64
#define SPI_MSTR_CLK64 0x02 /* chip clock/64 */
65
#define SPI_MSTR_CLK128 0x03 /* chip clock/128 */
66
#define SPI_MSTR_CLK2 0x04 /* chip clock/2 */
67
#define SPI_MSTR_CLK8 0x05 /* chip clock/8 */
68
#define SPI_MSTR_CLK32 0x06 /* chip clock/32 */
69
70
71
72
// setup spi
73
void setup_spi(uint8_t mode,   // timing mode SPI_MODE[0-4]
74
         int dord,             // data direction SPI_LSB|SPI_MSB
75
         int interrupt,        // whether to raise interrupt on recieve
76
         uint8_t clock); // clock diviser
77
78
// disable spi
79
void disable_spi(void);
80
81
// send and receive a byte of data (master mode)
82
uint8_t send_spi(uint8_t out);
83
84
// receive the byte of data waiting on the SPI buffer and
85
// set the next byte to transfer - for use in slave mode
86
// when interrupts are enabled.
87
uint8_t received_from_spi(uint8_t out);
88
89
#ifdef __cplusplus
90
} // extern "C"
91
#endif
92
93
#endif
SPI.c
1
/* 
2
 * Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to deal
6
 * in the Software without restriction, including without limitation the rights
7
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
 * copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 * 
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 * 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
 * THE SOFTWARE.
21
 */
22
23
#include "spi.h"
24
25
#ifdef __cplusplus
26
extern "C"{
27
#endif
28
29
#ifdef __ARDUINO__
30
#include <wiring.h>
31
#endif
32
33
void setup_spi(uint8_t mode, int dord, int interrupt, uint8_t clock)
34
{
35
  // specify pin directions for SPI pins on port B
36
  if (clock == SPI_SLAVE) { // if slave SS and SCK is input
37
    DDRB &= ~(1<<SPI_MOSI_PIN); // input
38
    DDRB |= (1<<SPI_MISO_PIN); // output
39
    DDRB &= ~(1<<SPI_SS_PIN); // input
40
    DDRB &= ~(1<<SPI_SCK_PIN);// input
41
  } else {
42
    DDRB |= (1<<SPI_MOSI_PIN); // output
43
    DDRB &= ~(1<<SPI_MISO_PIN); // input
44
    DDRB |= (1<<SPI_SCK_PIN);// output
45
    DDRB |= (1<<SPI_SS_PIN);// output
46
  }
47
  SPCR = ((interrupt ? 1 : 0)<<SPIE) // interrupt enabled
48
    | (1<<SPE) // enable SPI
49
    | (dord<<DORD) // LSB or MSB
50
    | (((clock != SPI_SLAVE) ? 1 : 0) <<MSTR) // Slave or Master
51
    | (((mode & 0x02) == 2) << CPOL) // clock timing mode CPOL
52
    | (((mode & 0x01)) << CPHA) // clock timing mode CPHA
53
    | (((clock & 0x02) == 2) << SPR1) // cpu clock divisor SPR1
54
    | ((clock & 0x01) << SPR0); // cpu clock divisor SPR0
55
  SPSR = (((clock & 0x04) == 4) << SPI2X); // clock divisor SPI2X
56
}
57
58
void disable_spi()
59
{
60
  SPCR = 0;
61
}
62
63
uint8_t send_spi(uint8_t out)
64
{
65
  SPDR = out;
66
  while (!(SPSR & (1<<SPIF)));
67
  return SPDR;
68
}
69
70
uint8_t received_from_spi(uint8_t data)
71
{
72
  SPDR = data;
73
  return SPDR;
74
}
Ich hoffe ma ich hab alles erwähnt was wichtig ist und ihr könnt mir 
weiterhelfen :)

DANKE:)

von Dieter Werner (Gast)


Lesenswert?

CS fest an GND ist keine gute Idee. Viele SPI Bausteine benötigen die CS 
Flanke von aktiv (meistens low) zu inaktiv für die interne 
Datenübernahme.

von Ich (Gast)


Lesenswert?

Notes on SPI and Microwire: Before the controller starts the data 
transfer, the software has to generate a falling edge on the I/O pin 
connected to FS.


FS erwähnst Du zwar nicht direkt im Text, da Du aber drei Pins als 
Ausgang setzt, wird einer davon wohl mit FS verbunden sein.

Nur das Datenrichtungsregister zu setzen ist mindestens schlechter Stil.
Die Pins sollten von Hochohmig auf Null gehen weil für die AVRs die 
meisten Register beim Reset ja mit Null beschrieben werden.

Aber selbst wenn das wie gedacht funktioniert, erzeugt das eben keine 
Flanke.


Um was messen zu können würde ich den Rest dann eher so schreiben:

  while(1)
    {
     send_spi(0b01001111);// 4bit daten + control bits
     send_spi(0b11111111);// restlichen daten
     _delay_us(10);
    }

von Ich (Gast)


Lesenswert?

Ach ja, mit weiterem Umschalten von FS in der Schleife natürlich. :-)

von HerrPitillo (Gast)


Lesenswert?

Hallo,
also soll ich jetzt FS einmal am anfang toggeln und einmal am ende 
richtig?
zudem soll ich jetzt pulldown widerstände hinzu fügen oder wie ist das 
gemeint?

Danke schon ma bis hier hin;)
echt ein super Forum hier:)

von Ich (Gast)


Lesenswert?

Nein, FS wird nicht am Anfang getoggelt und dann noch mal.

FS wird auf High gesetz.
Direkt vor dem Transfer wird FS auf Low gesetzt.
Nach dem Transfer wird FS auf High gesetzt.

 ...
 PORTB |= (1<< xx); // FS auf High setzen
  _delay_us(10);
 ...

  while(1)
    {
     PORTB &= ~(1<< xx); // FS auf Low setzen
     send_spi(0b01001111);// 4bit daten + control bits
     send_spi(0b11111111);// restlichen daten
     PORTB |= (1<< xx); // FS auf High setzen
     _delay_us(10);
    }

Folge dem Datenblatt. :-)

von HerrPitillo (Gast)


Lesenswert?

Danke:)
es funktioniert endlich:D
bei dem IC kriegt man nicht bei 0xFFF dem höchst möglichen wert sondern 
bei 0x00.


echt nen riesengroßes Danke:)
kann mir vllt noch jemand helfen eine Funktion zu schreiben der ich 
nurnoch den Wert den ich ahben will übergeben muss und der dann das an 
den Dac sendet?

DANKE c:

von HerrPitillo (Gast)


Lesenswert?

Sorry ich hab eben vergessen meine überlegung des Codes anzuhängen:D
1
int DAC_write(uint16_t Value, uint8_t SS_PIN)
2
{
3
  Value = Value * -1;
4
  
5
  uint8_t MSB = 0;
6
  uint8_t LSB = 0;
7
  uint8_t CTRL = 0b01000000;
8
  
9
  MSB = CTRL;
10
  MSB = Value << 4;
11
  LSB = Value << 8;
12
  PORTB &= ~(1<< SS_PIN); // FS auf Low setzen
13
  send_spi(MSB);// 4bit daten + control bits
14
  send_spi(LSB);// restlichen daten
15
  PORTB |= (1<< SS_PIN); // FS auf High setzen
16
  _delay_us(10);
17
  
18
  return 0;
19
}

von HerrPitillo (Gast)


Lesenswert?

Ich muss jetzt hier zum dritten mal hintereinander schreiben
Aber bei mir aht das phänomen wer misst misst mist zugeschlagen und ich 
hab ausversehen den ausgang gegen VCC anstatt gegen GND gemessen 
:facepalm:

Sorry:/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.