Moin Leute,
ich komme mit meinem Code nicht auf einen grünen Zweig. Wenn die Abfrage
des AD-Wandlers nur einmal durchläuft, dann bekomme ich einen sinnvollen
und schwankenden Wert. Daher möchte ich einige Werte mitteln, aber das
klappt einfach nicht. Dann bekomme ich falsche Werte...
1
//TLC4545 Ansteuerung
2
intadc(void)
3
{
4
unsignedintabfrage;
5
//unsigned long int summe;
6
7
//for(int k=0;k<64;k++)
8
//{
9
CLRBIT(PORTD,5);//CS auf 0
10
11
for(inti=0;i<16;i++)
12
{
13
SETBIT(PORTD,7);//CLK auf 1
14
asmvolatile("nop");
15
asmvolatile("nop");
16
asmvolatile("nop");
17
asmvolatile("nop");
18
asmvolatile("nop");
19
asmvolatile("nop");
20
asmvolatile("nop");
21
asmvolatile("nop");
22
asmvolatile("nop");
23
CLRBIT(PORTD,7);//CLK auf 0
24
abfrage=(abfrage<<1);
25
asmvolatile("nop");
26
if(bit_is_set(PIND,6))abfrage|=1;//DATA abfragen
27
}
28
SETBIT(PORTD,5);//CS auf 1
29
//summe = summe + (unsigned long int) abfrage;
30
//abfrage=0;
31
//}
32
//abfrage = (unsigned int) (summe/64);
33
34
//summe=0;
35
return(abfrage);
36
}
So funktioniert es, wenn ich das rauskommentierte aktiviere ergibt es
Blödsinn :-(
Du summierst 16 "abfrage"-Werte und teilst die Summe dann durch 64? Du
solltest mal versuchen durch 16 zu teilen.
By the way: kannst du "Blödsinn" etwas näher definieren?
Gruß,
Magnetus
@Magnus
Nein, weiter oben ist die 64er Schleife. Die 16er Schleife ist das
Bitweise abfragen des ADC.
@pumpkin
Das werde ich mal ändern!
Definition Blödsinn:
Der ausgegeben Wert ist deutlich zu hoch. Es liegt von Drucksensor etwa
4,03 V an. Mit einfacher Wandlung passt der Wert sehr gut. Mit
Mittelwertbildung liege ich bei 4,2 V.
Schreib doch mal Deine gemessenen Werte in ein Array und sieh Dir den
Inhalt dieses Arrays an - vielleicht erkennst Du dann, woran es bei der
Mittelwertbildung scheitert.
Mmmmh, ist schwierig zu sagen. Mein Gedanke ist z.Zt., dass der Wandler
evtl. etwas zu schnell beackert wird:
1
CLRBIT(PORTD,5);//CS auf 0
2
3
for(inti=0;i<16;i++)
4
{
5
6
// ...
Du sagst 'wandle!' und holst sofort deine Daten ab. Was für einen
Wandler nutzt du (Flash, Sigma-Delta, Approx, ...)? Deine
Shiftregisterkonstruktion scheint ja zu funktionieren.
pumpkin
> Du sagst 'wandle!' und holst sofort deine Daten ab. Was für einen> Wandler nutzt du (Flash, Sigma-Delta, Approx, ...)? Deine> Shiftregisterkonstruktion scheint ja zu funktionieren.
Er benutzt scheinbar einen TLC4545 (siehe Beginn des Codes)
Das ist ein TLC4545, 200 kSPS.
Der AVR läuft mit 8 MHz, wie bekomme ich denn raus wie lange der AVR für
das aufsummieren benötigt? Das muss ich wohl mal das genaue Timing
zwischen den Wandlungen berechnen...
Ok, hab' es nicht gesehen. Das Datenblatt sagt ~17ns nach /CS und ~3µs
conversion time. Guck dir mal das datasheet auf Seite 12 (conversion)
an. Dort wird beschrieben wie man ungültige Ergebnisse erkennt.
pumpkin
>> Der AVR läuft mit 8 MHz, wie bekomme ich denn raus wie lange der AVR für>> das aufsummieren benötigt?
Im Debug kannst du dir die clock cycles anschauen (irgendwo linkes
Fenster, Unterpunkt CPU wenn ich mich recht entsinne). Eine 'Stoppuhr'
ist auch eingebaut, aber die braucht das richtige #define F_CPU (auch im
makefile?!?).
pumpkin
Gibt's eigentlich einen Grund, warum du nicht die SPI-Hardware
benutzt?
Je nach Taktfrequenz kann 3 µs lang genug sein, als dass es sich lohnt,
das nächste Auslesen mit einem Timer anzustoßen.
Habe es gerade einmal durchgerechnet. Angenommen du verwendest das
fehlerhafte Wort 0xFF00 63 mal zur Mittelwertbildung, dann rutscht dein
Wert gegen ~4,95V (Referenz 5V). Wahrscheinlich sind nicht alle Werte
fehlerhaft, so dass dein leicht erhöhter Wert plausibel scheint. Ist nur
eine Möglichkeit, aber die würde ich erstmal abklopfen.
pumpkin
Vielen Dank erstmal! Ich werde mal ein paar nops einfügen und sehen ob
es klappt.
Leider muss ich wohl erstmal den SMD-Mega auslöten und ersetzen, er wird
plötzlich nicht mehr erkannt und das obwohl ich nichts an den Fuses
gemacht habe. So ein Mist...
Wenn Du 64 Messungen aufsummierst und dann durch 64 dividierst
vergrößerst Du den Fehler. Das nieder-niederwertigste Bit (das unter
Bit0) könnte bei jeder Messung 0 oder 1 sein da der zu messende Wert ja
analog vorliegt. Statistisch gesehen also 32 mal 0 und 32 mal 1. Addiere
vor der Division durch 64 noch die Hälfte der Anzahl der Messungen (32),
und Du gleichst diesen Fehler wieder aus.
Kurze Rückmeldung:
Manchmal hilft halt Däumchendrehen. Ein paar Nopse eingefügt und schon
stimmt der Wert.
Die 32 addiere ich jetzt auch noch hinzu.
Vielen Dank an Alle...