AD-Wandlung mit mehreren Kanälen
Dienstag, 22. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  CCS Compiler  |  AD-Wandler (CCS)  |  AD-Wandlung mit mehreren Kanälen « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: AD-Wandlung mit mehreren Kanälen  (Gelesen 2487 mal)
 
axel
Newbie
*
Offline Offline

Beiträge: 24


Profil anzeigen
« am: Mai 08, 2007, 19:51:09 »

Hallo zusammen!

Ich hätte da mal wieder ein Problem...
Und zwar soll mein PIC 16F88 die Daten von 6 Sensoren möglichst schnell von analog nach digital wandeln und ausgeben. Das funktioniert bis jetzt leider nur bedingt. Mein Problem ist, dass wenn ich nur einen Sensor betätige, dieser zwar brav einen passenden Wert ausgibt, aber der im nächsten Zyklus abgefragte Sensor davon beeinflußt wird. Sprich ich Sensorwert 0 beeinflußt Sensorwert 1 usw.
Hat jemand ne Ahnung, was ich da abändern muß?

Code:
//+++++++++++++++++ Generall settings +++++++++++++++++++++++++++++++++++++++++++++++++

#include "16F88.h"

#device ADC=10 //set for 10 bit A/D
#device *=16
#use delay(clock= 11059200)
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOPUT

#use rs232(baud=115200,parity=N,xmit=PIN_B5, rcv=PIN_B2, stream=RS232, bits=8) //define UART connection

#define ON_OFF PIN_B0 //Pin to check fsr-sensor
#define POWER PIN_B1 //Pin to control power supply




int16 counter=0; //variable for power supply algorthm
int16 DATA1 = 0; //variable for reading out A/D values
int8 channel=0; //variable for selecting A/D channel
int16 msec = 0; //variable for time counter

//+++++++++++++++++++++++++++++ Define interrupt +++++++++++++++++++++++++++

#INT_TIMER2
timer_routine(void)
{

//+++++++++++++++++++++++++++ Set Chanel 1-6 ++++++++++++++++++++++++++++++++++++++++++++++++++

channel++;
if (channel == 6)
{
channel = 0;
}

//+++++++++++++ Set chanel to read +++++++++++++++++++++++++++++

set_adc_channel(channel);

delay_us(10);

//+++++++++++++++++++++++++ Time counter +++++++++++++++++++++++++++++++++++++++

msec++; //Zählen der Zykluszahl, entspticht nur dann ms Zahl wenn timer auf 1ms eingestellt ist
if (msec ==10000)
{
msec = 1; //zeitstempel wird nach 999 Zyklen auf 1 gesetzt
}

//+++++++++++++++++++++++++++++ Reading out A/D values ++++++++++++++++++++++++++++++++++++++++++++++

DATA1 = read_adc(); //Get A/D reading and save to DATA1

printf("l%D_%04lu_%05lu\n\r",channel,DATA1,msec); //send Data
DATA1=0;

}


//++++++++++++++++++++++++++++++++ Main programm +++++++++++++++++++++++++++++++++++++++++++++++

void main()
{
output_high(POWER); //ensure power supply after first switching on


setup_adc_ports (sAN5|sAN4|sAN3|sAN2|sAN1|sAN0); //activate the used analog chanels

setup_adc(ADC_CLOCK_DIV_32); //divide Fosc by 32 to get below clock maximum

delay_ms(3000);

//setup_timer_2(T2_DIV_BY_1, 173, 16); //Timer2 set to 1ms
setup_timer_2(T2_DIV_BY_16, 173, 2); //Timer2 set to 2ms
//setup_timer_2(T2_DIV_BY_16, 247, 7); //Timer2 set to 10ms

enable_interrupts(INT_TIMER2); //timer2 interrupt zulassen
enable_interrupts(GLOBAL); //interrupts allgemein zulassen

//++++++++++++++++++++++++++++++++ Power supply algorithm ++++++++++++++++++++++

do
{
/*delay_ms(1000);

if(counter > 10) //checking power Button
{
output_low(POWER); //Power off
delay_ms(5000); //to make sure ltc switches off
}

if(input(ON_OFF)) //checking power Button
{
output_high(POWER); //Power on
counter=0; //set counter to 0 to avoid unwanted switching off
}
else
{
counter++;
}*/
}
 while(1);

}

schon mal Danke...

ps: wenn irgendjemand sonst noch was auffällt, was man eleganter lösen könnte bzw. was das Auslesen der Aaten noch beschleunigt, bin ich auch für jeden Tipp dankbar
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #1 am: Mai 08, 2007, 20:27:59 »

Zitat
Mein Problem ist, dass wenn ich nur einen Sensor betätige, dieser zwar brav einen passenden Wert ausgibt, aber der im nächsten Zyklus abgefragte Sensor davon beeinflußt wird. Sprich ich Sensorwert 0 beeinflußt Sensorwert 1 usw.

Dann ist die "acquisition time" (also die Zeit zwischen der Umschaltung des AD-Kanals und dem Start der Wandlung) zu klein. Im wesentlichen hängt die dafür benötigte Zeit von der Quellimpedanz (RS) der auszuwertenden Sensoren ab (siehe EQUATION 12-1 im Datenblatt des PICs). Wie hoch sind bei Dir diese Quellimpedanzen? Falls Du die Frage nicht beantworten kannst, poste mal die Schaltung.

Zitat
ps: wenn irgendjemand sonst noch was auffällt, was man eleganter lösen könnte bzw. was das Auslesen der Aaten noch beschleunigt, bin ich auch für jeden Tipp dankbar

Gerade bei der timergesteuerten Erfassung in festen Intervallen ist es immer günstiger, den Kanal direkt nach dem Ende der Wandlung umzuschalten und nicht davor.

Code:
        DATA1 = read_adc();
channel++;
if (channel == 6)
{
   channel = 0;
}

        set_adc_channel(channel);

Damit ist die Zeit zwischen "set_adc_channel" und dem nächsten auftretenden Interrupt bereits die nötige "acquisition time". Durch das darauf folgende printf wäre diese Zeit bereits um ein vielfaches größer als der offenbar nicht ausreichenden Delay von 10µs (der dann nicht mehr benötigt wird).


Viele Grüße

Bernd
Gespeichert

axel
Newbie
*
Offline Offline

Beiträge: 24


Profil anzeigen
« Antworten #2 am: Mai 08, 2007, 21:00:40 »

Hallo Bernd

von den Quellimpedanzen hab ich leider keine Ahnung.
ABER:
Ich hab den Code entsprechend deines Vorschlags abgeändert und jetzt funzt alles. :yahoo: (und ist durch das weggelassene delay auch noch einen Tick schneller...)

Vielen Dank für deine schnelle und vor allem hilfreiche Antwort!!!  Schockiert:

schöne Grüße,
Axel
Gespeichert
Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.035 Sekunden mit 19 Zugriffen.
 
Top! Top!