-schumi-
05.03.2012, 21:38
Hallo zusammen,
ich versuche gerade einen DAC per SPI anzusteuern (erster Kontakt mit SPI :)). Aber natürlich gehts nich so wie ich das will...
Der DAC ist ein MCP4812 von Microchip (2x10Bit). Das Datenblatt gibts hier (http://www.reichelt.de/index.html?;ACTION=7;LA=3;OPEN=0;INDEX=0;FILENAME= A200%2FMCP4802-4812-4822.pdf;SID=10TuS1ln8AAAIAAGZ@dZg66204c4c071ca167 ef22763f6669f148). Eigentlich klingt die Ansteuerung sehr simpel:
The write command is initiated by driving the CS pin low, followed by clocking the four Configuration bits and
the 12 data bits into the SDI pin on the rising edge of SCK. The CS pin is then raised, causing the data to be latched into the selected DAC’s input registers.
Sprich man muss CS auf Low legen, dann 4ConfigBits senden und anschließend 12Datenbits die die Ausgangsspg angeben. (Bei mir werden die 2 niederwertigsten Bits vom DAC einfach nicht ausgewertet, weil der ja nur 10Bit hat). Dann wird CS wieder auf High gelegt und der DAC legt den gesendeten Wert als analoge Spannung an den Ausgang (vorausgesetzt LDAC ist auf Low=GND, was bei mir der Fall ist). Alle Bits werden dabei bei der steigenden Flanke von SCK gesendet.
Angeschlossen ist mein DAC folgendermaßen:
DAC Pin:
AVR Pin nr.
AVR Pin Bezeichnung
CS
5
PB4 (SS)
SCK
8
PB7 (SCK)
SDI (=MOSI)
6
PB5 (MOSI)
Mein Programm (Alles SPI ist rot markiert):
#include <avr/io.h>
#include <util/delay.h>
#include "LCD.h"
void SPI_INIT (void)
{
DDRB = DDRB | (1<<DDB5) | (1<<DDB7); // SCK und MOSI als Ausgang
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); // SPE = SPI_Enable; MSTR = Master; SPR0 = f_sck/16 = 1MHz SCK Frequenz (16MHz Quarz), DAC schafft 20MHz
}
void SPI_DATA (char data)
{
SPDR = data; // Daten schicken
while(!(SPSR & (1<<SPIF))); // und warten bis alles gesendet ist
}
int main(void)
{
DDRB = 0b00001111;
PORTB = 0b00000001;
_delay_ms(100);
PORTB = 0b00000010; // Lauflicht, wartet bis die Spannungen an allen Bauteilen stabil stehen
_delay_ms(100);
PORTB = 0b00000100;
_delay_ms(100);
PORTB = 0b00001000;
LCD_INIT();
LCD_STRING(" Labor-Netzteil "); // LC-Display gedudel (Hängt an PortD)
SPI_INIT();
DDRB = DDRB | 0b00010000; // SS als Ausgang (Für CS des DAC)
PORTB = PORTB & 0b11101111; // SS auf Low, weil CS des DAC Lowaktiv
SPI_DATA (0b00111111); // Höherwertiges Nibble senden
SPI_DATA (0b11111100); // Niederwertigeres Nibble senden
PORTB = PORTB | 0b00010000; // SS wieder auf High, damit DAC den Wert analog ausgibt
while(1)
{
}
return 0;
}
Ich sende dem DAC also folgendes:
0011 1111 1111 1100
Das bedeutet Farbgemäß (Datenblatt S. 22):
Config Bits:
0 = Write to DAC_A (Ja, da dran messe ich auch)
0 = Zitat Datenblatt: Don't Care
1 = Output Gain selection Bit, 1 = 1x (VOUT = VREF * D/4096), also auswal der Refferenz
1 = Output Shutdown Control Bit: 1 = Active mode operation, Vout is aviable
Wert der Ausgangsspannung, alles high sollte 5V sein
Nicht Relevant, da mein DAC nur 10Bit hat
Soweit ich das sehe, hab ich doch alles korrekt gemacht, oder? Aber der DAC tut absolut garnichts! (Mit dem DMM mess ich immer ca. 2V, egal was ich sende)
Kann mir bitte jemand helfen? O:)
Vielen herzlichen Dank schonmal
-schumi-
ich versuche gerade einen DAC per SPI anzusteuern (erster Kontakt mit SPI :)). Aber natürlich gehts nich so wie ich das will...
Der DAC ist ein MCP4812 von Microchip (2x10Bit). Das Datenblatt gibts hier (http://www.reichelt.de/index.html?;ACTION=7;LA=3;OPEN=0;INDEX=0;FILENAME= A200%2FMCP4802-4812-4822.pdf;SID=10TuS1ln8AAAIAAGZ@dZg66204c4c071ca167 ef22763f6669f148). Eigentlich klingt die Ansteuerung sehr simpel:
The write command is initiated by driving the CS pin low, followed by clocking the four Configuration bits and
the 12 data bits into the SDI pin on the rising edge of SCK. The CS pin is then raised, causing the data to be latched into the selected DAC’s input registers.
Sprich man muss CS auf Low legen, dann 4ConfigBits senden und anschließend 12Datenbits die die Ausgangsspg angeben. (Bei mir werden die 2 niederwertigsten Bits vom DAC einfach nicht ausgewertet, weil der ja nur 10Bit hat). Dann wird CS wieder auf High gelegt und der DAC legt den gesendeten Wert als analoge Spannung an den Ausgang (vorausgesetzt LDAC ist auf Low=GND, was bei mir der Fall ist). Alle Bits werden dabei bei der steigenden Flanke von SCK gesendet.
Angeschlossen ist mein DAC folgendermaßen:
DAC Pin:
AVR Pin nr.
AVR Pin Bezeichnung
CS
5
PB4 (SS)
SCK
8
PB7 (SCK)
SDI (=MOSI)
6
PB5 (MOSI)
Mein Programm (Alles SPI ist rot markiert):
#include <avr/io.h>
#include <util/delay.h>
#include "LCD.h"
void SPI_INIT (void)
{
DDRB = DDRB | (1<<DDB5) | (1<<DDB7); // SCK und MOSI als Ausgang
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); // SPE = SPI_Enable; MSTR = Master; SPR0 = f_sck/16 = 1MHz SCK Frequenz (16MHz Quarz), DAC schafft 20MHz
}
void SPI_DATA (char data)
{
SPDR = data; // Daten schicken
while(!(SPSR & (1<<SPIF))); // und warten bis alles gesendet ist
}
int main(void)
{
DDRB = 0b00001111;
PORTB = 0b00000001;
_delay_ms(100);
PORTB = 0b00000010; // Lauflicht, wartet bis die Spannungen an allen Bauteilen stabil stehen
_delay_ms(100);
PORTB = 0b00000100;
_delay_ms(100);
PORTB = 0b00001000;
LCD_INIT();
LCD_STRING(" Labor-Netzteil "); // LC-Display gedudel (Hängt an PortD)
SPI_INIT();
DDRB = DDRB | 0b00010000; // SS als Ausgang (Für CS des DAC)
PORTB = PORTB & 0b11101111; // SS auf Low, weil CS des DAC Lowaktiv
SPI_DATA (0b00111111); // Höherwertiges Nibble senden
SPI_DATA (0b11111100); // Niederwertigeres Nibble senden
PORTB = PORTB | 0b00010000; // SS wieder auf High, damit DAC den Wert analog ausgibt
while(1)
{
}
return 0;
}
Ich sende dem DAC also folgendes:
0011 1111 1111 1100
Das bedeutet Farbgemäß (Datenblatt S. 22):
Config Bits:
0 = Write to DAC_A (Ja, da dran messe ich auch)
0 = Zitat Datenblatt: Don't Care
1 = Output Gain selection Bit, 1 = 1x (VOUT = VREF * D/4096), also auswal der Refferenz
1 = Output Shutdown Control Bit: 1 = Active mode operation, Vout is aviable
Wert der Ausgangsspannung, alles high sollte 5V sein
Nicht Relevant, da mein DAC nur 10Bit hat
Soweit ich das sehe, hab ich doch alles korrekt gemacht, oder? Aber der DAC tut absolut garnichts! (Mit dem DMM mess ich immer ca. 2V, egal was ich sende)
Kann mir bitte jemand helfen? O:)
Vielen herzlichen Dank schonmal
-schumi-