Moin,
ich teste gerade den MCP4921. Um eine Rampe zu erzeugen, lasse ich einen
Counter bis 4095 zählen und übergebe das Ergebnis dem Chip.
Merkwürdigerweise habe ich große Sprünge in den Werten, manchmal um 1V
nach oben oder kleinere (0,1V-0,2V nach unten). Auch würde ich erwarten,
dass ich bei einem eingegeben Wert von 2047 ca. Vref/2 erreichen müsste.
Ich bekomme aber bereits an der Stelle fast voll Vref (Vref = VCC = 5V).
Ich lasse mir die Werte des Counters auch anzeigen, um sie zu
kontrollieren.
Hier mal mein Code:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<stdlib.h>
4
#include"avr.h"
5
#include"mcp4921.h"
6
#include"UART.h"
7
#include"SPI.h"
8
9
charbuffer1[15],buffer2[15],buffer3[15];
10
intcounter=0;
11
intcounter_high=0;
12
inttest=0;
13
14
intmain(void)
15
{
16
17
avr_init();
18
UART_Init();
19
20
while(1)
21
{
22
23
counter++;
24
counter_high=(counter>>8);// | 0b00110000;
25
test=counter_high|0b00110000;
26
27
MCP4921_setdata(test,counter);
28
_delay_ms(50);
29
30
31
if(counter>=4095)
32
{
33
counter=0;
34
}
35
36
itoa(counter_high,buffer1,2);
37
itoa(counter,buffer3,2);
38
itoa(test,buffer2,2);
39
uart_puts("Input: ");
40
Send_UART_Char(buffer3);
41
uart_puts("counter_high: ");
42
Send_UART_Char(buffer1);
43
uart_puts("test: ");
44
Send_UART_Char(buffer2);
45
Send_UART_Char(" ");
46
_delay_ms(100);
47
}
48
}
Vielleicht fällt jemanden etwas an dem Code auf, was die Sprünge und die
nicht zusammenpassenden Werte (Input -> Voltage)erklären könnten.
Gruß
Hallo Marco,
ich setze den MCP4921 / MCP4922 auch ein, ohne Probleme. Bin mir nicht
sicher, ob das Problem am Code liegt, bin nur im Assembler tätig.
Markierst Du mit der Zeile
"counter_high = (counter >> 8);// | 0b00110000;"
das obere Halbbyte aus, um das Highbyte fix auf B'0011xxxx' zu setzen ?
Damit sendest Du dann gesamt 16 Bits '0011xxxx xxxxxxxx', wobei die
12mal 'x'
der eigentliche 12Bit-Wert ist.
Müßte es vielleicht (counter >> 15) lauten ?
Wie gesagt, kenne die Syntax nicht wirklich.
Hier könnte das Problem liegen. Kannst Du die beiden Bytes, die Du via
SPI zum MCP4921 schickts vorab nochmals ausgeben und kontrollieren ?
Außerdem fällt mir noch der Hardwarepin LDAC# ein, der sollte für Deinen
Versuch dauerhaft auf GND sein, da sonst der Ausgang abgeschaltet wird.
Gruß, Günther
Hallo Günther,
nein mit der Zeile verschiebe ich alle Bits die größer als 2^8 sind um
acht Stellen nach rechts, sodass sie wieder bei 2^0 starten. Das brauche
ich, um die Daten zu übertragen.
Marco G. schrieb:> test = counter_high | 0b00110000;
Mit dieser Zeile ver-oder dann das Ergebnis, sodass es immer wie folgt
aussieht: 0b0011xxxx. Die x stellen dabei die ober vier Bit der zwölf
Datenbits dar.
Die Zwischenwerte gebe ich auch aus, und die stimmen mit meiner
Erwartung auch überein.
Der /LDAC Pin liegt bei mir auch dauerhaft auf GND, daran sollte es also
nicht liegen.
Hi Marco.
Wo ist denn der Code für die Funktion MCP4921_setdata? Ohne den kann man
nicht wirklich sagen, was falsch läuft.
Aber ich wage man einen Schuss ins Blaue: Du hast Parameter von
MCP4921_setdata vertauscht.
Die Funktion sollte richtig sein. Zumindest wenn ich den Wert einmal
(vor der while schleife auf 2048 setze, bekomme ich ca. 2.5V als
Ausgabe. Das stimmt also soweit. Trotzdem hier noch einmal der Code:
Marco G. schrieb:> Die Funktion sollte richtig sein. Zumindest wenn ich den Wert einmal> (vor der while schleife auf 2048 setze, bekomme ich ca. 2.5V als> Ausgabe. Das stimmt also soweit. Trotzdem hier noch einmal der Code:>
1
>voidMCP4921_setdata(intbyte1,intbyte2)
2
>{
3
>SS_low();
4
>SPI_MasterTransit(byte1);
5
>SPI_MasterTransit(byte2);
6
>_delay_us(1);
7
>SS_high();
8
>//MCP4921_latchdata();
9
>
10
>}
11
>
Kann sein, dass ich total blind bin, aber ich glaube, dass ich mit
meinem "Schuss ins Blaue" richtig lag.
Zum Test habe ich die gesendeten Bytes mal umgedreht. Dann bekomme ich
kein Ergebnis, ich denke meine Senderichtung stimmt schon. Ich lasse
mich aber auch gerne etwas bessern belehren wenn noch irgendjemand Idee
hat, oder eine Verbesserung des Codes weiß.
Meine Sendereihenfolge ist richtig, das Problem war die Zuordnung der
Flanken bei der Datenübernahme. Der MCP4921 erwartet eine steigende
Flanke, mein uC sendete mit fallender Flanke.
Jetzt funktioniert die Kommunikation mit dem Chip, das einzige "Problem"
ist noch, dass der ausgegebene Wert immer um ca. 0,1V höher als der
erwartete/errechnete Wert ist. Vermutlich liegt dies aber an dem Aufbau
auf einem Steckbrett. Oder könnte das noch andere Gründe haben?
Gruß
Marco G. schrieb:> Meine Sendereihenfolge ist richtig,
Hm ja, ich war wohl zu sehr abgelenkt (Frau hat mich von der Seite
zugetextet), als ich einen kurzen Blick ins Datasheet geworfen habe. Das
MSB wird zuerst gesendet, und das LSB zuletzt.
Möglich wären noch Timing-Probleme. Nutzt du Hardware-SPI oder wird das
Protokoll in Software emuliert? Davon unabhängig kannst du auch
versuchen, den SPI-Takt reduzieren. Oder sende immer die gleichen Wert,
und schaue ob die Spannung dann auch springt. Wenn Oszi vorhanden, dann
SPI-Daten prüfen. (Trigger auf die fallende Flanke von /CS.)
Mehr fällt mir grad nich ein, hoffe, die Ideen bringen dich irgendwie
weiter.
Grüße.
Ist doch nicht so schlimm ;)
Ich habe ja auch eine gewisse Zeit gebraucht um festzustellen, dass das
Hauptproblem dabei die Flanken waren. Auf dem Scope sah alles gut aus,
nur hat die Datenübernahme im Chip anders begonnen. da ich dort nicht
reinsehen kann, ist mir das auch nicht aufgefallen.
Ich nutze "richtiges" hardware-Spi, mit der niedrigsten möglichen
Frequenz (Fcpu/16 = 8MHz/16 = 500kHz).
Die springende Spannung hat sich durch eine Änderungen gegeben, wenn ch
einen Zähler als Eingabewert nutze kann ich eine Rampe erzeugen, das
einzige Problem ist im Moment ein Offset von 0,1V. Dieser erscheint mir
etwas zu hoch.