PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ADC des PIC12F675



Shibbius
05.01.2006, 17:52
Hallo!
In einem Projekt für die Schule benötigen wir den PIC12F675 zum Abgleich einer Messbrücke, dazu wird ein digitales Potentiometer damit angesteuert. Er hat einen 10 Bit ADC und zum Programmieren verwende ich den PIC-C Compiler, weil ich mich mit Assembler nicht wirklich auskenne. Weil ich mich mit PICs selber noch nicht auskenne habe ich erst einmal ein paar simple Programme geschrieben um zu testen wie was ungefähr funktioniert. Und da hänge ich jetzt bei dem ADC.
Als Takt verwende ich den internen RC-Oszillator und sonst gibt es meines Wissens nichts mehr bei der Beschaltung also vermute ich den Fehler im Programm.



#include <12F675.h>
#device ADC=10
#include <STDLIB.H>
#fuses INTRC_IO, NOWDT, NOMCLR, NOPUT, NOBROWNOUT, NOCPD, NOPROTECT

int wert;

init()
{

setup_adc_ports(AN0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_tris_a(0x09);

}


void main()
{

init();

while (1)
{
wert=Read_ADC();
if (wert<=0x1FF)
Output_low(PIN_A2);
else
Output_high(PIN_A2);
}

}

Meine Probleme sind, dass ich nicht genau weiß, welche Fuses ich brauche und was der Rückgabewert von Read_ADC() ist. In der Hilfe steht eine 8 oder 16 Bit Integer, abhängig von #device ADC= . Weiters ist dann noch ein Tabelle in der der Bereich von 0-3FF steht.
Wenn ich dieses Programm auf den PIC brenne und die Schaltung teste, tut sich überhaupt nichts.
Ich hoffe ihr könnt mir helfen und bedanke mich schon im Voraus

mfg Shibbius

Fritzli
05.01.2006, 18:55
Hallo

Welche Compiler-Version hast Du? (Die haben manchmal ziemlich blöde Fehler)

1) ADC_CLOCK_INTERNAL sollte man normalerweise nur verwenden, wenn man während des sleep-Modus sampelt. Sonst einen der abgeleiteten (_DIV_xx) Takte verwenden. Der taktet nämlich etwas zeitversetzt zum normalen CPU-Takt, d.h. man hat weniger schaltbedingtes Rauschen auf dem ADC (siehe Datenblatt)

2) NOMCLR - ich weiss jetzt nicht auswendig, ob diese fuse int. oder ext. reset bedeutet. Schau das nochmals nach.

3) init: da fehlt ein set_adc_channel(0);

4) ADC Resultat: Das Resultat ist, wie schon gesagt, 16bit oder 8bit, abhängig vom #device.
ABER: Um die 16Bit zu speichern braucht man ein long int (16Bit) und nicht nur ein int (8Bit)
Da müsste also long stehen, ausser Du willst nur 8Bit, dann reicht aber auch ein ADC=8.

5) Lass dem Ding in der Schleife doch etwas Zeit: Der ADC sollte zwischen zwei Messungen eine Pause haben, damit sich die Spannung im internen Sampling-Kondensator an die Eingangsspannung angleichen kann (Datenblatt) Ausserdem wirst Du sowieso keine 20kHz Samplingrate brauchen.

6) Haben die vorherigen Programme funktioniert? Blinklicht?

Gruess
Fritzli

Mobius
05.01.2006, 20:26
2) NOMCLR heißt, der MCLR Pin wird als ein IO-Pin initialisiert und damit steht dem PIC keine Reset-möglichkeit zur Verfügung (die 12F und 16F haben keinen wirklichen Software-reset). Also, damit dein PIC neustartet musst du schon den stecker ziehen. Aber dadurch entfällt nat, dass du den Pin über einen ~10k Widerstand auf high ziehen musst ;).

zum Programm: Ich würde das ADC-Sampling außerhalb der Schleife legen und danach eine Wait-Schleife aufbauen, die so lange nichts tut, bis der ADC seinen interrupt-Flag setzt (das geht irgendwie, bin aber zu Faul, um das Datenblatt hervorzukramen). Danach die LEDs setzten und den PIC mit einer Unendlichschleife einfrieren.

MfG
Mobius

Fritzli
05.01.2006, 20:49
Hallo Mobius

Warten auf das Flag ist hier eher nicht nötig, verkompliziert das Ganze nur; das macht die Funktion von alleine. Und sleep-Modus geht nicht, wenn er eine Dauermessung will - macht auch mehr Sinn.

Sorry, wenn das jetzt etwas 'von oben herab' klingt, aber ich nehme an, Du kennst den entsprechenden Compiler nicht (?)

Gruess
Fritzli

Shibbius
09.01.2006, 18:04
Ich bin leider erst jetzt dazugekommen mich wieder damit zu beschäftigen. Danke für die Antworten, es war tatsächlich das set_adc_channel(0); und das ärgert mich eigentlich ein wenig. Viiiieeelen Dank! Ich werde das jetzt versuchen in unserem Programm richtig einzubauen und hoffe das es dort auch funktioniert :) .
Nochmals vielen Dank!!!!!!!

mfg Shibbius