Ich hoffe ich bekomme keine krititk da ich extra dafür ein neues Thread eröffne aber ich komme da nicht weiter und denke mir es würde anderen auch helfen. Also ich versuche mein Problem oder meine Wissenlücke mal zu schildern: ich versuche einen TLC7620 anzusprechen das ist ein 8 bit DAC aber man muss 11 bit übertragen (3 bit für Parameter) von einem ATMEGA 8 in C habe spi soweit verstanden aber komme da einfach nicht weiter? Vielen dank im voraus für konstruktive vorschläge.
Das Schluesselwort heisst Soft SPI. Ist nicht weiter schwierig, man muss die Pin per Software anteuern. Gemaess Datenblatt.
Gibts da vielleicht ein Beispiel in C will nicht copy und past machen aber zum verstehen würde es mir helfen? Weil auf die Idee bin ich auch schon gekommen aber nicht so richtig was gefunden und wenn war es nicht grade so nach vollziebar.
Habe schon mal sowas versucht aber habe auch andere gefragt aber die sagten versuchs besser mit der SPI Schnittstelle von ATmega8 Hier der Code oder verstehe ich da was falsch? #include <avr/io.h> #include <util/delay.h> #define DAC_PORT PORTC #define DAC_LOAD 1 #define DAC_CLOCK 0 #define schiebeum 5 void dac_data(unsigned char temp1); void dac_enable(void); void dac_data(unsigned char temp1) { unsigned char a1dac=0x00; a1dac = a1dac & 0x04; unsigned char a0dac=0x00; a0dac = a0dac & 0x04; unsigned char rngdac=0x00; rngdac = rngdac & 0x04; unsigned char d7dac=temp1<<2; d7dac = d7dac & 0x04; unsigned char d6dac=temp1<<1; d6dac = d6dac & 0x04; unsigned char d5dac=temp1; d5dac = d5dac & 0x04; unsigned char d4dac=temp1>>1; d4dac = d4dac & 0x04; unsigned char d3dac=temp1>>2; d3dac = d3dac & 0x04; unsigned char d2dac=temp1>>3; d2dac = d2dac & 0x04; unsigned char d1dac=temp1>>4; d1dac = d1dac & 0x04; unsigned char d0dac=temp1>>5; d0dac = d0dac & 0x04; DAC_PORT |= (1<<DAC_LOAD); //a1 DAC_PORT &= 0x04; DAC_PORT |= a1dac; dac_enable(); //a0 DAC_PORT &= 0x04; DAC_PORT |= a0dac; dac_enable(); //rng DAC_PORT &= 0x04; DAC_PORT |= rngdac; dac_enable(); //d7 DAC_PORT &= 0x04; DAC_PORT |= d7dac; dac_enable(); //d6 DAC_PORT &= 0x04; DAC_PORT |= d6dac; dac_enable(); //d5 DAC_PORT &= 0x04; DAC_PORT |= d5dac; dac_enable(); //d4 DAC_PORT &= 0x04; DAC_PORT |= d4dac; dac_enable(); //d3 DAC_PORT &= 0x04; DAC_PORT |= d3dac; dac_enable(); //d2 DAC_PORT &= 0x04; DAC_PORT |= d2dac; dac_enable(); //d1 DAC_PORT &= 0x04; DAC_PORT |= d1dac; dac_enable(); //d0 DAC_PORT &= 0x04; DAC_PORT |= d0dac; dac_enable(); //DAC_PORT &= (1<<DAC_LOAD); } void dac_enable(void) { DAC_PORT |= 0x01; _delay_us(150); // nicht zu knapp warten, sonst drohen Kompatbilitätsprobleme! DAC_PORT &= ~0x01; } int main(void) { DDRC=0x07; PORTC=0x00; dac_data(1); while (1) { } return 0; } danke für jede hilfe!
CS=0; for (i=0;i<11;i++){ if ((Data && 0x01)==0x01) { DO=1; } else (DO=0;} SCLK=1; data >>= 1; { CS=0; So etwa. Kommt nun drauf an, of MSB first, oder LSB first.
Hab was vergessen : CS=0; for (i=0;i<11;i++){ if ((Data && 0x01)==0x01) { DO=1; } else (DO=0;} SCLK=1; data >>= 1; SCLK=0; { CS=0;
Scheinst ja eine menge darüber zu wissen danke erst mal. Die Pins wären da ja frei wähl paar so weit ich das verstehe CS wäre das Load bit data wäre für die Daten SCKL für die Clock. aber wie mache ich das mit dem Clock signal dies ist laut datenblatt bei 1 MHZ für den DAC tue ich da mit delay arbeiten da der Atmega8 an einen 3686000 MHZ quarz angeschlossen ist? Aber nochmal kurz zum Hardware SPI ne andere Idee wenn ich nun 16 bit zum DAC schicke und nach 16 bits haufhöre schreibt der da die 5 bit am anfang wieder rein oder bei einem solchen fall da verhalten undefiniert?
Übrigens: Nur weil der Wandler 11Bits erwartet, heißt das nicht unbedingt, dass man exakt 11 Bits senden muss. Das ist ein Trugschluss! Stell dir vor du hast ein 11-Bittiges Schieberegister und schiebst 16Bits herein. Na, welche Bits liegen jetzt an den Ausgängen? Meistens* läuft es so, dass die 11 letzten Bits, die du hineingeschoben hast bei einer fallenden/steigenden Flanke von CS die für das On-Chip-Processing relevanten Daten sind. Sprich: Die Bits, die du zuerst hineingeschoben hast, sind schon wieder "herausgefallen". *Ich weiß nicht, ob das bei deinem Baustein auch der Fall ist, aber ich könnte es mir sehr gut vorstellen. PS: Sieh es erstmal andersherum: Wie sollte der Chip reagieren, wenn du mehr Bits vor dem CS hineinschiebst? In Rauch aufgehen? Wohl kaum.
Das habe ich ausprobiert aber die reaktion war nahe null wenn ich 16 bits reingeschoben habe mit ensprechender +5 Bitverschiebung. Siehe Code Master_Transmit #include <avr/io.h> #include <stdint.h> #define DD_MOSI PB3 #define DD_SCK PB5 #define DD_LOAD PB0 void SPI_MasterInit(void) { /* Set MOSI and SCK output, all others input */ DDRB = (1<<DD_MOSI)|(1<<DD_SCK); /* Enable SPI, Master, set clock rate fck/64 */ SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1); } void SPI_MasterTransmit(char cData) { /* Start transmission */ SPDR = 15; /* Wait for transmission complete */ while(!(SPSR & (1<<SPIF))) ; /* Start transmission */ SPDR = cData; /* Wait for transmission complete */ while(!(SPSR & (1<<SPIF))) ; } int main(void) { SPI_MasterInit(); SPI_MasterTransmit(200); for(;;) ; return 0; } PS.: will hier keinen verärgern mit zuviel dummen fragen hoffe ihr nehmt mir das nich übel. Danke für jede hilfe
Wenn der DAC 1MBit als maximum vorsieht, kann das SPI auch langsamer sein. Der genannte Code wird 1MBit kaum ueberbieten, Im Loop wohlgemerkt.
Wenn ich nochmal vom Hardware SPI ausgehe und noch mal von vorne anfange habe mir auf seite 3 unten die Zeichnung genommen und das versucht nachzubauen. Habe folgendes verbunden: - 5 Volt spannungsquelle angeschlossen an vdd und gnd ist ein extra Spannungswandler mit verbindung mu mit gnd - ref angeschlossen Spannungsquelle - Data mit Mosi verbunden von mc - CLK mit SCK verbunden von mc - LOAD mit PIN2 verbunden von mc (ist im Quelltext nicht berücksichtigt habe aber dies auch mit bedacht in anderen Quelltext den ich jetzt nicht zur hand habe da auf Arbeit) Liegt vielleicht dort der Fehler hier das Datenblatt dazu. http://www.datasheetcatalog.com/datasheets_pdf/T/L/C/5/TLC5620.shtml danke für jede Hilfe
Ich lese das Datasheet so, dass du da einfach zwei Bytes reinschieben kannst, MSB zuerst:
1 | void dac_put_data(uint8_t channel, uint8_t data) |
2 | {
|
3 | spi_put_byte(channel<<1); |
4 | spi_put_byte(data); |
5 | CLR_LOAD(); |
6 | _delay_us(0.3); /* min. 250ns warten, |
7 | klappt so aber nur MIT aktivierter Optimierung */
|
8 | SET_LOAD(); |
9 | }
|
Und LDAC einfach (erst mal) auf low lassen. Und das SPI auf "Mode 1" (s. AVR-Datenblatt) initialiseren. hth. Jörg
Danke für deine Funktion sieht sehr interresant aus ich nehme die jetzt mal auseinander: mit dac_channel meinst du einen der 4 Ausgänge des DAC Frage 1. Schiebe ich durch "spi_put_byte(channel<<1); " nur eine bestimmte anzahl von Bits aus der Channel Variablen raus also in dem vom DAC nur 3 Bits? Frage 2. "spi_put_byte(data);" ist der Parameterwert für den Ausgang des Kanals oder? Frage 3. CLR_LOAD() setzte ich das Load bit auf 0 warte 0,3 us und setzte es dann wieder mit SET_LOAD(); aber im Datenblatt steht doch das während der übertragung der Load auf High sein soll und danach erst wieder auf Low? Frage 4. das ganze ist jetzt Hardware SPI oder? Sorry meine Fragen aber versuche es zu verstehen und nicht einfach zu kopieren. Danke für deine Hilfe mfg Alex
> spi_put_byte(channel<<1); bedeutet dass die Nummer des DAC-Ausgange gesendet wird, aber nicht so: > 0b 0 0 0 0 0 0 n n sondern so > 0b 0 0 0 0 0 n n 0 also einer (2er-)Stelle verschoben, weil das LSB ("Least Sigificant Byte") eine andere Bedeutung hat ("RNG"), damit man "Kanal 0" bis Kanal 3 schreiben kann, z.B. für Arrays ;) Ich häng dir mal an, was ich inzwischen zusammengetippt hab -> du musst aber auf jeden Fall die #defines in der .h-Datei überprüfen/ausfüllen hth. Jörg
Alexander Schreiber wrote: > Das habe ich ausprobiert aber die reaktion war nahe null wenn ich 16 > bits reingeschoben habe mit ensprechender +5 Bitverschiebung. Ja, das würde mich nicht wundern:
1 | #include <avr/io.h> |
2 | #include <stdint.h> |
3 | #define DD_MOSI PB3
|
4 | #define DD_SCK PB5
|
5 | #define DD_LOAD PB0
|
6 | |
7 | void SPI_MasterInit(void) |
8 | {
|
9 | |
10 | /* Set MOSI and SCK output, all others input */
|
11 | DDRB = (1<<DD_MOSI)|(1<<DD_SCK); |
12 | /* Enable SPI, Master, set clock rate fck/64 */
|
13 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1); |
14 | }
|
15 | |
16 | |
17 | |
18 | void SPI_MasterTransmit(char cData) |
19 | {
|
20 | |
21 | /* Start transmission */
|
22 | SPDR = 15; |
23 | /* Wait for transmission complete */
|
24 | while(!(SPSR & (1<<SPIF))) |
25 | ;
|
26 | |
27 | /* Start transmission */
|
28 | SPDR = cData; |
29 | /* Wait for transmission complete */
|
30 | while(!(SPSR & (1<<SPIF))) |
31 | ;
|
32 | |
33 | |
34 | |
35 | }
|
36 | |
37 | int main(void) |
38 | {
|
39 | SPI_MasterInit(); |
40 | SPI_MasterTransmit(200); |
41 | for(;;) |
42 | ;
|
43 | return 0; |
44 | }
|
Du musst im Master-Mode den /SS-Pin als Ausgang setzen. Außerdem hast du (vermute ich?) vergessen den LOAD-Ausgang als Ausgang zu setzen. Den Rest habe ich garnicht erst überprüft. Btw, du steuerst den LOAD-Ausgang ja auch garnicht an!
zu Simon Küppers: will nicht fresch sein aber muss mal sagen richtig lesen aber trotzdem danke ich überlese auch manchmal sachen! Autor: Alexander Schreiber (alex130) Datum: 24.09.2007 13:50 - LOAD mit PIN2 verbunden von mc (ist im Quelltext nicht berücksichtigt habe aber dies auch mit bedacht in anderen Quelltext den ich jetzt nicht zur hand habe da auf Arbeit) Mal eine zwichenfrage kommt von jemanden der mir geantwortet hat zu fällig jemand aus dresden? PS danke Jörg X. für deine mühe und deine Geduld bisher
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.