Forum: Mikrocontroller und Digitale Elektronik I2C MCP4725 Wert Übertragen


von Michael H. (h_m)


Lesenswert?

Guten Tag,

ich möchte gerne einen Wert in das Register des DAC MCP4725 schreiben. 
Zu Anfang 0V also 0x00.

Aber irgendwie bekomme ich das nicht hin wie ich das gerade versuche und 
mir vorstelle habe ich in den Header von nachfolgendem Code geschrieben.

Vielleicht kann mir bitte jemand behilflich sein das ich zumindest mal 
etwas übertragen kann. Denn ich bin I2C Anfänger
1
/*
2
 * MCP4725_DAC.c
3
 *
4
 * Created: 28.02.2019 09:11:19
5
 * Author : USER
6
 *
7
 * hier soll ein Wert mit I2C in das Register des DAC MCP4725 geschrieben werden, dieser soll dann eine Spannung
8
 * an Vout ausgeben. Ich Stelle mir das in der Whileschleife so vor 
9
 *
10
 * 1. Startbedingung Senden
11
 * 2. Übertragung der Adresse des MCP4725 (hier 11000000) + Write + ACK    Adresse A0 ist auf GND gelegt
12
 * 3. Übertragen des Wertes der in das Register geschrieben werden soll mit MT_DATA_ACK 0x00 
13
 * 4. Stopbedingung Senden jetzt soll der DAC soll 0V ausgeben
14
 * 
15
 * 
16
 * Ein möglicher Übertragungsfehler (ERROR) wird durch eine LED an PB1 angezeigt
17
 *
18
 * CPU: ATmega88, FCPU = 16MHz
19
 * die nachfolgende Rechnung mit 62,5kHz wurde mit 8Mhz berechnet, das habe ich noch nicht verstanden wie dies funktioniert
20
 * I²C CLK Frequency = 62,5kHz, --> CLK Frequency = FCPU/(16 + 2*(TWBR)*Prescaler Value)
21
 */
22
#define F_CPU 16000000UL
23
#include <avr/io.h>
24
#include <util/delay.h>
25
26
#define START           0x08    // A START condition has been transmitted
27
#define R_START         0x10    // A REPEATED START condition has been transmitted
28
#define SLA_W           0xC0    // Slave Address & Write 1100 0000 A0 ist auf GND gelegt
29
#define SLA_R           0xC1    // Slave Address & Read 1100 0001
30
#define MT_SLA_ACK      0x18    // Master Transmit SLA + W has been transmitted & ACK has been received
31
#define MT_DATA_ACK     0x00    // Master Transmit Data byte has been transmitted & ACK has been received
32
#define MR_SLA_ACK      0x40    // Master Receive SLA + R has been transmitted & ACK has been received
33
#define MR_SLA_NACK     0x48    // Master Receive SLA + R has been transmitted & ACK has been received
34
#define MR_DATA_ACK     0x50    // Master Receive Data byte has been transmitted & ACK has been returned
35
#define MR_DATA_NACK    0x58    // Master Receive Data byte has been transmitted & NACK has been returned
36
#define BIT_RATE        56      // Set value for the bit rate register TWBR
37
38
void ERROR(void);               // Prototyping of function "ERROR"
39
40
/*** Function to send a START Condition ***/
41
void TWI_START(void)
42
{
43
  // Send a START condition
44
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
45
  // Wait for TWINT Flag set. This indicates that the START condition has been transmitted
46
  while (!(TWCR & (1<<TWINT)));
47
  // Check value of TWI statusregister. Mask prescaler bits. If status different from START go to ERROR if ((TWSR & 0xF8) != START)
48
  ERROR();
49
}
50
51
/*** Function to send the Slave Address with ACK in Master Transmit Mode ***/
52
void TWI_MT_SLA_ACK(void)
53
{
54
  // Load Slave Address + Write into TWDR Register
55
  TWDR = SLA_W;
56
  // Clear TWINT bit in TWCR to start transmission
57
  TWCR = (1<<TWINT) | (1<<TWEN);
58
  // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
59
  while (!(TWCR & (1<<TWINT)));
60
  // Check value of TWI status register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR
61
  if ((TWSR & 0xF8) != MT_SLA_ACK)
62
  ERROR();
63
}
64
65
/*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
66
void TWI_MT_DATA_ACK(uint8_t data)
67
{
68
  // Load DATA into TWDR register
69
  TWDR = data;
70
  // Clear TWINT bit in TWCR to start transmission
71
  TWCR = (1<<TWINT) | (1<<TWEN);
72
  // Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
73
  while (!(TWCR & (1<<TWINT)));
74
  // Check value of TWI status register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
75
  if ((TWSR & 0xF8) != MT_DATA_ACK)
76
  ERROR();
77
}
78
79
/*** Function to send a REPEATED START condition **/
80
void TWI_R_START(void)
81
{
82
  // Send a START condition
83
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
84
  // Wait for TWINT Flag set. This indicates that the START condition has been transmitted
85
  while (!(TWCR & (1<<TWINT)));
86
  // Check value of TWI statusregister. Mask prescaler bits. If status different from R_START go to ER-ROR
87
  if ((TWSR & 0xF8) != R_START)
88
  ERROR();
89
}
90
91
/*** Function to send the Slave Address in Master Receive Mode with Acknowledge **/
92
void TWI_MR_SLA_ACK(void)
93
{
94
  // Load Slave Address + Read into TWDR Register
95
  TWDR = SLA_R;
96
  // Clear TWINT bit in TWCR to start transmission
97
  TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
98
  // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
99
  while (!(TWCR & (1<<TWINT)));
100
  // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_ACK go to ERROR
101
  if ((TWSR & 0xF8) != MR_SLA_ACK)
102
  ERROR();
103
}
104
105
/*** Function to send the Slave Address in Master Receive Mode without Acknowledge **/
106
void TWI_MR_SLA_NACK(void)
107
{
108
  // Load Slave Address + Read into TWDR Register
109
  TWDR = SLA_R;
110
  // Clear TWINT bit in TWCR to start transmission
111
  TWCR = (1<<TWINT) | (1<<TWEN);
112
  // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
113
  while (!(TWCR & (1<<TWINT)));
114
  // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_NACK go to ERROR
115
  if ((TWSR & 0xF8) != MR_SLA_NACK)
116
  ERROR();
117
}
118
119
/*** Function to read one Databyte in Master Receive Mode and send NACK ***/
120
uint8_t TWI_READ_DATABYTE_NACK(void)
121
{
122
  // Clear TWINT bit in TWCR to start transmission with NACK
123
  TWCR = (1<<TWINT) | (1<<TWEN);
124
  // Wait for TWINT flag set. This indicates that the DATA has been received
125
  while (!(TWCR & (1<<TWINT)));
126
  // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_NACK go to ERROR
127
  if ((TWSR & 0xF8) != MR_DATA_NACK)
128
  ERROR();
129
  return TWDR; // Return the value of data register
130
}
131
132
/*** Function to read one Databyte in Master Receive Mode and send ACK ***/
133
uint8_t TWI_READ_DATABYTE_ACK(void)
134
{
135
  // Clear TWINT bit in TWCR to start transmission with ACK
136
  TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
137
  // Wait for TWINT flag set. This indicates that the DATA has been received
138
  while (!(TWCR & (1<<TWINT)));
139
  // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_ACK go to ERROR
140
  if ((TWSR & 0xF8) != MR_DATA_ACK)
141
  ERROR();
142
  return TWDR; // Return the value of data register
143
}
144
145
/*** function to send a STOP condition ***/
146
void TWI_STOP(void)
147
{
148
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Transmit STOP condition
149
}
150
151
/*** function to show a bus error ***/
152
void ERROR(void)
153
{
154
  PORTB |= (1<<PB1); // ERROR LED ON
155
}
156
157
uint8_t LSByte, MSByte;
158
uint16_t data_16bit, lux_value, high_byte, low_byte;
159
160
int main(void)
161
{
162
  //DDRD = 0xFF;            // PORTD = output
163
  //DDRC = 0x3F;            // PC0 ... PC5 = output
164
  DDRB = 0x03;            // PB0 and PB1 = output
165
  TWBR = BIT_RATE;        // Set the TWI clock-frequency in bit rate register
166
  //TWI_START();            // Send START condition
167
  //TWI_MT_SLA_ACK();       // Master Transmit Slave Address with Acknowledge
168
  //TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 for Register Command with Acknowledge
169
  //TWI_STOP();             // Send STOP condition
170
  //_delay_ms(10);          // Delaytime between STOP and next START contition
171
  
172
  while(1)
173
  {
174
    TWI_START();            // Send START condition
175
    TWI_MT_SLA_ACK();       // Master Transmit Slave Address with ACK
176
    TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 to start with Register 0x00 with ACK
177
    TWI_STOP();                         // Send STOP condition
178
    
179
    _delay_ms(200);                     // wait 200ms 
180
  }
181
}

von Da Huaba Bene (Gast)


Lesenswert?

Michael H. schrieb:
> Vielleicht kann mir bitte jemand behilflich sein das ich zumindest mal
> etwas übertragen kann. Denn ich bin I2C Anfänger

Du müsstest schon deinen Schaltplan und deinen Aufbau zeigen.
Denn wir trauen einem "Anfänger" nur selten.
Eher trauen wir einem "Anfänger" alles zu, und das geht oft
schief.

Und deine Source wird so lang dass sie in einen Anhang gehört!

Das Beispiel das du hier

http://www.ne555.at/2014/index.php/bilder-zum-buch/520-lm75_tempsensor.html

kopiert hast ist auch sicherlich kein gutes Vorbild.
(nur als Beispiel: Grossbuchstaben verwendet man nur für
Konstanten, um sie von Variablen und Funktionen leicht
unterscheiden zu können)

Michael H. schrieb:
> * die nachfolgende Rechnung mit 62,5kHz wurde mit 8Mhz berechnet, das
> habe ich noch nicht verstanden wie dies funktioniert

Die Formel steht doch im Datenblatt, was ist daran nicht
zu verstehen? Es gibt zwei Variablen (Variationsmöglichkeiten),
die eine ist das TWBR (Baudraten-Register) und die andere ist
der Prescaler für den Prozessor Clock zum groben Voreinstellen.

Also, bis später.

von Michael H. (h_m)


Angehängte Dateien:

Lesenswert?

Danke schon ein mal für die Antwort.


Also der Schaltplan ist real genau so aufgebaut wie im Bild.
Jetzt bitte keine Diskussion :-) warum ich das mit der Schablone 
gezeichnet habe und nicht mit dem PC.

Da Huaba Bene schrieb:
> Das Beispiel das du hier
>
> http://www.ne555.at/2014/index.php/bilder-zum-buch/520-lm75_tempsensor.html
>
> kopiert hast ist auch sicherlich kein gutes Vorbild.
> (nur als Beispiel: Grossbuchstaben verwendet man nur für
> Konstanten, um sie von Variablen und Funktionen leicht
> unterscheiden zu können)

Das stimmt, nur ich habe das Originale Buch Davon. Und da ist alles sehr 
gut erklärt, wenn ich die Schaltung mit dem LM75 Aufbaue und mit 8Mhz 
betreibe funktioniert das ja einwandfrei und mit dem Lightsensor auch. 
Da sind die Schaltpläne alles im Buch dabei. Und ich kann es auch 
relativ gut nachvollziehen, Nur ich habe den Code von dem nächsten 
kopiert von dem Light_Sensor_ISL29020.c der unterscheidet sich das hier 
keine Pointeradresse verwendet wird.

Aber ich will ja nicht mehr nur den Lm75 Auslesen sondern ich will 
einmal mit dem in den Code verwendeten Funktionen Selbstständig eben den 
MCP4725 ansteuern. Bzw. einen Wert in das Register schreiben und ein 
Ergebnis am Vout sehen.


Um besseres Grundverständnis zu bekommen.

Datenblatt 4725
[[http://ww1.microchip.com/downloads/en/DeviceDoc/22039d.pdf]]



Da Huaba Bene schrieb:
> Michael H. schrieb:
>> * die nachfolgende Rechnung mit 62,5kHz wurde mit 8Mhz berechnet, das
>> habe ich noch nicht verstanden wie dies funktioniert
>
> Die Formel steht doch im Datenblatt, was ist daran nicht
> zu verstehen? Es gibt zwei Variablen (Variationsmöglichkeiten),
> die eine ist das TWBR (Baudraten-Register) und die andere ist
> der Prescaler für den Prozessor Clock zum groben Voreinstellen.
>
> Also, bis später.

Die Theorie verstehe ich natürlich dahinter, nur kann ich es Praktisch 
irgedwie in Bits makieren nicht umsetzen. Wenn die Berechnung jetzt erst 
einmal für die Funktion nicht so wichtig ist. Würde ich mich gerne auf 
das beschreiben des DAC konzentrieren, das ich mal etwas im Vout in 
Bewegung bekomme.

von Da Huaba Bene (Gast)


Lesenswert?

Michael H. schrieb:
> Also der Schaltplan ist real genau so aufgebaut wie im Bild.

Dann hast du schon ein Problem.

In deiner Source initialisierst du Port B (vermutlich wegen
des TWI), aber dein Schaltplan zeigt die (korrekte) Anbindung
an PortC, Pin 4, 5.    Klingelt's?

Michael H. schrieb:
> Die Theorie verstehe ich natürlich dahinter, nur kann ich es Praktisch
> irgedwie in Bits makieren nicht umsetzen.

Den Wert den du ins Register schreibst entpricht hier einfach
dem Teilerwert der in der Formel steht.

Und beim TWSR gibt es zwei Bits die die vier Möglickeiten
Prescaler 1/2/16/64  repräsentieren.

von Da Huaba Bene (Gast)


Lesenswert?

Da Huaba Bene schrieb:
> Dann hast du schon ein Problem.
>
> In deiner Source initialisierst du Port B (vermutlich wegen
> des TWI), aber dein Schaltplan zeigt die (korrekte) Anbindung
> an PortC, Pin 4, 5.    Klingelt's?

Bin mir nicht sicher ob das so sein muss.
Finde leider momentan den Abschnitt für die Pin Initialisierung
nicht im Datenblatt ...

von Da Huaba Bene (Gast)


Lesenswert?

Da Huaba Bene schrieb:
> Bin mir nicht sicher ob das so sein muss.

In der Source die du als Vorbild genommen hast wird jedenfalls
Port C als Ausgang gesetzt.

von Michael H. (h_m)


Lesenswert?

Da Huaba Bene schrieb:
> Michael H. schrieb:
>> Also der Schaltplan ist real genau so aufgebaut wie im Bild.
>
> Dann hast du schon ein Problem.
>
> In deiner Source initialisierst du Port B (vermutlich wegen
> des TWI), aber dein Schaltplan zeigt die (korrekte) Anbindung
> an PortC, Pin 4, 5.    Klingelt's?

Also Port B ist wegen des ERROR Lämpchen initialisiert, Das kann ich 
auch weglassen.

D.H. ich muss für SDA und SDL auch zumindest PC4 und 5 initialisieren ?

ich dachte das wäre geschehen als der I2c bus im Register eingestellt 
wurde. Denn mit dem Analogen Oszi habe ich zumindest Takte an SDA und 
SCL messen können.


Dann werde ich jetzt als erstes mal Port B ausklammern und PC4 und 5 als 
Ausgang setzen.

: Bearbeitet durch User
von Michael H. (h_m)


Lesenswert?

Also Vout steht immer noch auf 2,5V. Und erwarten Tu ich das er mit 
meinem gesendeten nach 0V geht. Macht er aber nicht

das habe ich jetzt verändert bzw, gesendet
1
int main(void)
2
{
3
  //DDRD = 0xFF;            // PORTD = output
4
    DDRC = (1<<PC4) | (1<<PC5); // PC4 und PC5 = output
5
  //DDRB = 0x03;            // PB0 and PB1 = output
6
  TWBR = BIT_RATE;        // Set the TWI clock-frequency in bit rate register
7
  //TWI_START();            // Send START condition
8
  //TWI_MT_SLA_ACK();       // Master Transmit Slave Address with Acknowledge
9
  //TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 for Register Command with Acknowledge
10
  //TWI_STOP();             // Send STOP condition
11
  //_delay_ms(10);          // Delaytime between STOP and next START contition
12
  
13
  while(1)
14
  {
15
    TWI_START();            // Send START condition
16
    TWI_MT_SLA_ACK();       // Master Transmit Slave Address with ACK
17
    TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 to start with Register 0x00 with ACK
18
    TWI_STOP();                         // Send STOP condition
19
    
20
    _delay_ms(200);                     // wait 200ms 
21
  }
22
}

von Da Huaba Bene (Gast)


Angehängte Dateien:

Lesenswert?

Michael H. schrieb:
> Also Port B ist wegen des ERROR Lämpchen initialisiert, Das kann ich
> auch weglassen.

Muss man ja nicht - ist davon unabhängig ...

Michael H. schrieb:
> TWI_MT_DATA_ACK(0x00);
Du hast einen 12-Bit Wandler, der braucht auch 12 Bit als Datenwort.
Auch hier ist die Protokoll-Beschreibung im Datenblatt hilfreich.

von Michael H. (h_m)


Lesenswert?

Ok das Stimmt, das ändert aber immer noch nichts an Vout.


ich habe jetzt Praktisch in der Funktion uint_8 data in uint_16 geädert

1
/*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
2
void TWI_MT_DATA_ACK(uint16_t data)
3
{
4
  // Load DATA into TWDR register
5
  TWDR = data;
6
  // Clear TWINT bit in TWCR to start transmission
7
  TWCR = (1<<TWINT) | (1<<TWEN);
8
  // Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
9
  while (!(TWCR & (1<<TWINT)));
10
  // Check value of TWI status register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
11
  if ((TWSR & 0xF8) != MT_DATA_ACK)
12
  ERROR();
13
}

und in der While dann 4 NIBBLE
1
while(1)
2
  {
3
    TWI_START();            // Send START condition
4
    TWI_MT_SLA_ACK();       // Master Transmit Slave Address with ACK
5
    TWI_MT_DATA_ACK(0x0000);  // Transmit 0x00 to start with Register 0x00 with ACK
6
    TWI_STOP();                         // Send STOP condition
7
    
8
    _delay_ms(200);                     // wait 200ms 
9
  }

von Da Huaba Bene (Gast)


Angehängte Dateien:

Lesenswert?

Michael H. schrieb:
> Also der Schaltplan ist real genau so aufgebaut wie im Bild.

Finde den Unterschied!

Ist nicht kriegsentschedend, aber einen Meckerer auf jeden
Fall wert.

Denn die Aussage "also bei mir geht's auch ohne" haben wir
oft genug gehört.

von Da Huaba Bene (Gast)


Lesenswert?

Michael H. schrieb:
> void TWI_MT_DATA_ACK(uint16_t data)

Auf dem I2C Bus kann man nur Bytes senden oder empfangen.

von Michael H. (h_m)


Lesenswert?

Und das Bild von dem Datenblatt das habe ich mir Schon 10mal angeschaut, 
da träume ich heute noch davon,

Und genau das versuche ich in der Whileschleife umzusetzen, wenn es dann 
einmal funktioniert hat verstehe ich es auch.

von Da Huaba Bene (Gast)


Lesenswert?

Da Huaba Bene schrieb:
> Auf dem I2C Bus kann man nur Bytes senden oder empfangen.

und deine Funktion

Michael H. schrieb:
> /*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
> void TWI_MT_DATA_ACK(uint16_t data)

kann nur 8 Bit senden (es steht sogar im Kommentar, und die
AVR Register sind auch nur 8 Bit breit), auch wenn du ihr 173
Bits übergibst.

von Florian P. (ol1cr0n)


Lesenswert?

Ganz klarer Fall von Datenblatt nicht gelesen. Schaue dir Figure 6-1 
nochmal an. Das ist das was du übertragen musst. Laut deiner 
Beschreibung sendet dein Master ein ACK. Soll das so?

Wie wäre es wenn du Byte für Byte so sendest wies im Datenblatt steht?


Start();
SendAdr();
Wait4ACK();
SendHighByte();
Wait4ACK();
SendLowByte();
Wait4ACK();
Stop();

: Bearbeitet durch User
von Michael H. (h_m)


Lesenswert?

Also die Kondensatoren habe ich nachgerüstet. keine Änderung.

Da Huaba Bene schrieb:
> Da Huaba Bene schrieb:
>> Auf dem I2C Bus kann man nur Bytes senden oder empfangen.
>
> und deine Funktion
>
> Michael H. schrieb:
>> /*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
>> void TWI_MT_DATA_ACK(uint16_t data)
>
> kann nur 8 Bit senden (es steht sogar im Kommentar, und die
> AVR Register sind auch nur 8 Bit breit), auch wenn du ihr 173
> Bits übergibst.


Das hatte ich schon irgendwie im Hinterkopf, das ist das was ich eben 
jetzt noch nicht so ganz verstehe.

Müsste ich im dann die 2 Bytes nach einander senden? das ist ja das was 
in dem Bild beschrieben ist ? die 4bits für den Fast Modus etc und 4bit 
für den Wert, und das nächste Byte mit 8bit noch einmal für den Wert.


Aber wie Sende ich das jetzt zweimal nacheinander ?

1
  while(1)
2
  {
3
    TWI_START();            // Send START condition
4
    TWI_MT_SLA_ACK();       // Master Transmit Slave Address with ACK
5
    TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 to start with Register 0x00 with ACK
6
    TWI_R_START();
7
    TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 to start with Register 0x00 with ACK
8
    TWI_STOP();                         // Send STOP condition
9
    
10
    _delay_ms(200);                     // wait 200ms 
11
  }

So dann habe ich auch noch gleich die Funktion wieder in den Original 
Zustand gebracht
1
/*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
2
void TWI_MT_DATA_ACK(uint8_t data)
3
{
4
  // Load DATA into TWDR register
5
  TWDR = data;
6
  // Clear TWINT bit in TWCR to start transmission
7
  TWCR = (1<<TWINT) | (1<<TWEN);
8
  // Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
9
  while (!(TWCR & (1<<TWINT)));
10
  // Check value of TWI status register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
11
  if ((TWSR & 0xF8) != MT_DATA_ACK)
12
  ERROR();
13
}


Allerdings hat sich noch nichts geändert. An Vout

von Michael H. (h_m)


Lesenswert?

DANKE, DANKE ES KLAPPT !!!

Zwei Byte direkt nacheinander Senden (hinschreiben) und Gut ist, ich 
dachte da muss man dazwischen die Konversation neu starten

von Da Huaba Bene (Gast)


Lesenswert?

Michael H. schrieb:
> TWI_R_START();

Wo ist im Datenblatt an bereits gezeigter Stelle ein
Repeated Start zu finden?

Michael H. schrieb:
> Aber wie Sende ich das jetzt zweimal nacheinander ?

Entweder Troll und unfähig.

Ich bin dann mal weg.

von Kopf Schüttel (Gast)


Lesenswert?

Michael H. schrieb:
> ich habe jetzt Praktisch in der Funktion uint_8 data in uint_16 geädert
>
> /*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
> void TWI_MT_DATA_ACK(uint16_t data)
> {
>   // Load DATA into TWDR register
>   TWDR = data;
>   // Clear TWINT bit in TWCR to start transmission
>   TWCR = (1<<TWINT) | (1<<TWEN);
>   // Wait for TWINT flag set. This indicates that the DATA has been
> transmitted, and ACK/NACK has been received.
>   while (!(TWCR & (1<<TWINT)));
>   // Check value of TWI status register. Mask prescaler bits. If status
> different from MT_DATA_ACK go to ERROR
>   if ((TWSR & 0xF8) != MT_DATA_ACK)
>   ERROR();
> }

Ich frage mich schon was man im Kopf haben muss um anzunehmen
dass die Änderung eines Datentyps von 8 auf 16 Bit im Übergabe-
Parameter das innere der Funktion gleich so ändert wie man es
gerne haben möchte.

Manchmal kann man einfach nicht glauben was da alles daherkommt.

von Michael H. (h_m)


Lesenswert?

Jetzt habe ich noch eine Frage, und zwar gibt es die Möglichkeit die 
12bit die ja nacheinander gesendet werden. Auch in eine Variable zu 
packen damit man praktisch in dezimal von 0-4095 senden kann ?

und jetzt nicht gleich wieder unfähig etc. ich hab gesagt das ich das 
erst am anfang mache, ich habe mich auch bei huaba bedankt und war Froh 
das er sich die Zeit überhaupt genommen hat

von Da Huaba Bene (Gast)


Lesenswert?

Michael H. schrieb:
> und zwar gibt es die Möglichkeit

Das klingt nach Alternative, aber es gibt keine.

Der 16-Bit Wert, von dem 12 genutzt werden ist in zwei Bytes
aufzuteilen (oberes Byte mit den Steuerbits verknüpft) und
nacheinander zu senden.

Das Bild vom Protokoll stellt doch ganz klar dar wie es zu
machen ist. Oder habe ich ein "alternatives" Protokoll
übersehen?

von Michael H. (h_m)


Lesenswert?

Nö Nö das ist alles richtig.


wenn ich es zb. so sende stellet er sich auf null ein, alles gut.
1
while(1)
2
  {
3
    TWI_START();            // Send START condition
4
    TWI_MT_SLA_ACK();       // Master Transmit Slave Address with ACK
5
    TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 to start with Register 0x00 with ACK
6
    //TWI_R_START();
7
    TWI_MT_DATA_ACK(0x00);  // Transmit 0x00 to start with Register 0x00 with ACK
8
    TWI_STOP();                         // Send STOP condition
9
    
10
    _delay_ms(200);                     // wait 200ms 
11
  }


aber was mache ich jetzt wenn ich zb.
1
 Zaehlwert = 4095 ;

also die Variable übergebn will bzw. ins Register schreiben will, das 
müsste man ja dann auch aufteilen

von Da Huaba Bene (Gast)


Lesenswert?

Michael H. schrieb:
> das müsste man ja dann auch aufteilen

Du hast es erfasst!

Was heisst da "auch", ja man muss es aufteilen. Das ist
immer so, wenn ein Wert nicht in ein Byte hineinpasst.

Oh man ....

von Michael H. (h_m)


Lesenswert?

Das 4095 nicht in ein Byte passt ist mir auch Klar,

mal angenommen ich lese ein Poti über den Adc ein, und mache einen Wert 
von 0-4095 in ein Variable, wie würde man das dann mit I2C übergeben. 
Oder ist das dann gar nicht möglich, und man kann das nur binär 
übergeben ?

von Einer K. (Gast)


Lesenswert?

Michael H. schrieb:
> wie würde man das dann mit I2C übergeben.
> Oder ist das dann gar nicht möglich, und man kann das nur binär
> übergeben ?
EDV funktioniert grundsätzlich binär...
(in 99,9999% aller Fälle)

Du musst dein Datenwort in Byte aufteilen und diese Bytes dann senden.


Wurde aber schon gesagt:
Da Huaba Bene schrieb:
> Der 16-Bit Wert, von dem 12 genutzt werden ist in zwei Bytes
> aufzuteilen (oberes Byte mit den Steuerbits verknüpft) und
> nacheinander zu senden.

von Sherlock Holmes (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Wurde aber schon gesagt:

Ab jetzt gilt wirklich höchster Troll-Verdacht!

Aber warum die Leute sowas machen ist mir schleierhaft .....

von Michael H. (h_m)


Lesenswert?

Arduino Fanboy D. schrieb:
> Du musst dein Datenwort in Byte aufteilen und diese Bytes dann senden.
>
> Wurde aber schon gesagt:
> Da Huaba Bene schrieb:
>> Der 16-Bit Wert, von dem 12 genutzt werden ist in zwei Bytes
>> aufzuteilen (oberes Byte mit den Steuerbits verknüpft) und
>> nacheinander zu senden.

Das weiß ich ja, das hat er mir im Datenblatt schon gezeigt, und so 
funktioniert es ja auch.

es gibt aber auch eine Dezimale Schreibweise ,und das will ich wissen ob 
das dann hier überhaupt möglich ist?

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Michael H. schrieb:
> es gibt aber auch eine Dezimale Schreibweise
Die ist nur für Menschen.

Unterscheide zwischen Daten und Präsentation.

von Sherlock Holmes (Gast)


Lesenswert?

Michael H. schrieb:
> es gibt aber auch eine Dezimale Schreibweise

Ohhh man, ob du dem I2C Bus zweimal 0 und 0 sendest oder
zweimal 0x00 und 0x00 ist vollkommen egal, das ist eine
unterschiedliche Schreibweise sonst nichts.

von Sherlock Holmes (Gast)


Lesenswert?

Michael H. schrieb:
> es gibt aber auch eine Dezimale Schreibweise

Was hast du eigentlich in den zwei Jahren in denen du hier
online bist (äääähj dein Unwesen treibst) gelernt ausser
Copy&Paste Operationen auszuführen?

von Michael H. (h_m)


Lesenswert?

ÄHH.. was soll den sowas jetzt, sie haben sich natürlich hingesetzt und 
sofort alles verstanden und ihre Fragen die aufkamen, perfekt 
zielführend formulieren können.Danke, Glück gehabt.


dann versuche ich es jetzt noch einmal ich weise einer Variablen zb.

Wert = 4000 zu, das passt jetzt natürlich nicht in ein Byte, wenn ich 
das jetzt mit dem I2c an den Wandler senden will

TWI_MT_DATA_ACK(Wert); dann stimmt das ja nicht, das meine ich wie ich 
das hier umsetzen kann ?

von Sherlock Holmes (Gast)


Lesenswert?

Du teilst <Wert > in zwei Bytes auf und sendest die Bytes
hintereinander. So einfach ist das.

von Bastian W. (jackfrost)


Lesenswert?

Michael H. schrieb:
> ÄHH.. was soll den sowas jetzt, sie haben sich natürlich hingesetzt und
> sofort alles verstanden und ihre Fragen die aufkamen, perfekt
> zielführend formulieren können.Danke, Glück gehabt.
>
>
> dann versuche ich es jetzt noch einmal ich weise einer Variablen zb.
>
> Wert = 4000 zu, das passt jetzt natürlich nicht in ein Byte, wenn ich
> das jetzt mit dem I2c an den Wandler senden will
>
> TWI_MT_DATA_ACK(Wert); dann stimmt das ja nicht, das meine ich wie ich
> das hier umsetzen kann ?

Das obere Byte kannst mit (Wert >> 8) senden. Für das untere machst Dir 
einfach bitweises und mit 0xff (Wert & 0xff).

Beides am besten noch mit (uint8_t) casten.

Gruß JackFrost

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.