Forum: Mikrocontroller und Digitale Elektronik Temperaturmessen mit UTI03 und Atmega128


von Andreas M. (chillymu)


Lesenswert?

Hi Leute,

ich möchte mit einem UTI03 von Smartec und einem ATMega128 die 
Temperatur eines PT100 messen. Die Schaltung ist fertig und sollte 
gehen. Nun frag ich mich wie ich das am besten im Controller realisiere.

Hat da vielleicht jemand schon ein paar Erfahrungen damit gemacht und 
kann mir bei der Umsetzung ein paar Tipps geben?

Ich dachte da an den Input Capture Pin für das auslesen. Weiß leider 
noch nicht so recht wie das funktioniert.

Da muss man bestimmt auch auf das Zeitmanagment achten.

Ihr würdet mir sehr helfen.

Danke.

Gruß Andreas

von Andreas M. (chillymu)


Lesenswert?

Hi Leute,

nachdem sich keiner so richtig meldet, habe ich mal etwas ausprobiert 
und komme der Lösung nahe.

Ich nutze nun den Input Capture Pin PortD Pin 4 der mit dem Timer 1 
zusamen hängt.

globale Variblen
1
static int icnt = 0;
2
static unsigned int RestPh0L = 0;
3
static unsigned int RestPh0H = 0;
4
static unsigned int RestPh1L = 0;
5
static unsigned int RestPh1H = 0;
6
static unsigned int RestPh2L = 0;
7
static unsigned int RestPh2H = 0;
8
static unsigned int RestPh3L = 0;
9
static unsigned int RestPh3H = 0;

die Initialisierung des ICP-Timers:
1
cli();
2
// Timer1 initialisieren:
3
TCCR1A = 0x00; //stop
4
TCCR1B = 0x00; //stop
5
TCNT1H = 0x00; // Clearing 
6
TCNT1L = 0x00; // Clearing
7
TCCR1A = 0x00; // OpMode: Normal
8
TCCR1B |= (1<<ICNC1)|(1<<ICES1); //enable Noise Canceler, rising edge
9
TIMSK |= (1<<TICIE1); //enable input capture interrupt
10
icnt = 0;
11
sei();


Die Interruptroutine
1
ISR(TIMER1_CAPT_vect)      //  Flanke an ICP pin
2
{
3
  if (icnt == 0){    
4
    RestPh0L = ICR1L;
5
    RestPh0H = ICR1H;
6
    icnt++;
7
    return;
8
  }  
9
  if (icnt == 1){
10
    RestPh1L = ICR1L;
11
    RestPh1H = ICR1H;
12
    icnt++;
13
    return;
14
  }
15
  if (icnt == 2){
16
    RestPh2L = ICR1L;
17
    RestPh2H = ICR1H;
18
    icnt++;
19
    return;
20
  }
21
  if (icnt == 3){
22
    RestPh3L = ICR1L;
23
    RestPh3H = ICR1H;
24
    TIMSK &= ~((1<<TICIE1));//disable input capture interrupt
25
    icnt = 0;  
26
    return;
27
  }    
28
 return;
29
}

Starte ich den Timer und lasse mir danach die Werte RestPh0L bis 
RestPh3H ausgeben steht überall Null.

Mach ich irgendetwas falsch?

von Hubert G. (hubertg)


Lesenswert?

Das Problem wird sein das nicht sehr viele den UTI03 kennen und niemand 
deinen Schaltplan.

von Andreas M. (chillymu)


Angehängte Dateien:

Lesenswert?

Im Prinzip ist das doch egal ob UTI oder nicht.

Ich nutze den ICP-Timer um die Zeit zwischen zwei steigenden Flanken zu 
messen.

Im angehängten Bild sehe ich (lila) das UTI-Signal und durch das 
auslösen des Timers setze ich einen Pin auf high und beim nächsten event 
wieder auf low.( im Code nicht vorhanden) So komme ich bei dem zweiten 
Impuls auf 31ms das müsste theoretisch die Zeit RestPh3 sein.

Warum bekomme ich dann aber Null?

von Erich (Gast)


Lesenswert?

Hier mal ein Link zu einer Wetterstation, die das auch benutzt, mit 
Quelltext im dort zu findender .PDF
http://www.technik.dhbw-ravensburg.de/~lau/wetterstation.html

Siehe auch  Beitrag "Geeigneter Mikrocontroller für Messung mit SMT160-30"

von Andreas M. (chillymu)


Lesenswert?

Hi Leute,

danke für eure Hilfe. Sieht ganz gut jetzt aus. Sobald ich komplett 
fertig bin werde ich den Code komplett posten.

Eine Frage hätte ich da noch.

Ich habe zwei Timer initialisiert. Mein Takt beträgt 12,288MHz
1
void sys_timer_timer1_init(void){
2
   cli();
3
   icnt = 0;
4
   icnt2 = 0;
5
   cmp_counter1 = 0;
6
   // Timer1 initialisieren:
7
   TCCR1A = 0x00; //stop
8
   TCCR1B = 0x00; //stop
9
   TCNT1H = 0x00; // Clearing
10
   // Timer für 1ms  1ms/((12.288M)^-1) = 12288 = 0x3000
11
   OCR1A = 0x3000;
12
   //enable Noise Canceler, rising edge, 1 prescale, OpMode: CTC
13
   TCCR1B |= (1<<ICNC1)|(1<<ICES1)|(1<<CS10)|(1<<WGM12);
14
   TIMSK |= (1<<TICIE1); //enable input capture interrupt
15
   TIMSK |= (1<<OCF1A);  // Output Compare    
16
   
17
   sei();
18
   return;
19
}

Einen Compare Timer der jede ms auslöst und die Variable cmp_counter1 
hochzählt.
Und einen Capture Timer der auslöst wenn das Signal eine high Flanke 
generiert. Dort lese ich das ICR1-Register aus und warte dann wieder auf 
die nächste high Flanke.

Nun meine Frage(n).

Wie verhält sich das ICR1-Register? Zählt das bis 65536 mit dem 
CPU-Takt, was bei 5,333ms überläuft? Wird es nach dem auslesen 
zurückgesetzt?

die Berechnung der Zeit ist derzeit so.

// ((12.288M)^-1) = 0,00008138
Time = cmp_counter1 + ((ICR1H * 256 + ICR1L) * 0,00008138);

Damit gehe ich davon aus, dass das ICR1- Register nur jede ms 
hochgezählt wird. Stimmt das?

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.