Forum: Mikrocontroller und Digitale Elektronik Schwellwert AVR ATmega 32u4


von Lukas (Gast)


Lesenswert?

Aufgabe:

Es soll ein einfacher Komparator realisiert werden. Es wird ein 
Schwellwert von 2,5V programmiert und mit dem ADCO-Wert (Potentiometer 
auf Steckbrett) verglichen. Ist der ADC-Wert größer als die Schwelle, 
wird der Ausgang HIGH. Ansonsten LOW. Beide Werte werden auf einem LCD 
20x2 angezeigt.

Hallo Programmierer!

Ich habe diese Aufgabenstellung bekommen und hab große Schwierigkeiten 
sie umzusetzen. Bin noch nicht sehr erfahren und benötige bitte Hilfe.
Danke Lg

von Peter II (Gast)


Lesenswert?

Lukas schrieb:
> Ich habe diese Aufgabenstellung bekommen und hab große Schwierigkeiten
> sie umzusetzen. Bin noch nicht sehr erfahren und benötige bitte Hilfe.
> Danke Lg

dann zeige was du schon gemacht hat, und wo du nicht weiter kommst.

von Ingo L. (corrtexx)


Lesenswert?

Lukas schrieb:
> Ich habe diese Aufgabenstellung bekommen und hab große Schwierigkeiten
> sie umzusetzen. Bin noch nicht sehr erfahren und benötige bitte Hilfe.
Wer gibt dir denn diese Aufgabe, dass du so hoffnungslos überfordert 
bist? Woran scheitert es denn genau?

von Ingo L. (corrtexx)


Lesenswert?

Lukas schrieb:
> Ist der ADC-Wert größer als die Schwelle,
> wird der Ausgang HIGH. Ansonsten LOW
Gibt es keine Hysterese, das wäre dumm...

: Bearbeitet durch User
von Lukas F. (Firma: HTL St.Pölten) (lukas_fery)


Lesenswert?

Bin in der Schule und der Prof. hat mir die Aufgabe gegeben....

von Peter II (Gast)


Lesenswert?

Ingo L. schrieb:
> Gibt es keine Hysterese, das wäre dumm... Was passiert wenn der ADC-Wert
> gleich dem eingestellten Wert ist?

gibt doch eine

wenn kleiner Low
wenn größer High

also ist die Hysterese 1 bit (also wenn gleich)

von Ingo L. (corrtexx)


Lesenswert?

Lukas F. schrieb:
> Bin in der Schule und der Prof. hat mir die Aufgabe gegeben....
Also hast du vermutlich nicht aufgepasst und wir sollen es jetzt gerade 
ziehen? Vergiss es! Zeig deinen Ansatz und wenn es dort Probleme gibt 
kann man helfen...

Peter II schrieb:
> gibt doch eine
Ja, habe ich dann auch gesehen. Wobei eine Hysterese idealerweise um den 
Schaltpunkt liegt, also Schaltpunkt + oder - Hysterese...

: Bearbeitet durch User
von Lukas F. (Firma: HTL St.Pölten) (lukas_fery)


Lesenswert?

#define F_CPU 16000000UL
#include <avr/io.h>
#include <stdio.h>
#include "lcd-routines.h"
#include "lcd-routines.c"



void set_fusos()
{
  MCUCR |= (1<<JTD);
  MCUCR |= (1<<JTD);

  CLKPR = 0b10000000;
  CLKPR = 0;
  CLKPR = 0;
  CLKPR = 0;
  CLKPR = 0;


}



int main(void)
{
  set_fusos();
  int S=2500, l=1875;
  char s[20],x[20];

  lcd_init();
  lcd_clear();

  lcd_setcursor(1,1);
  sprintf(s,"S=%dmV ",S);
  lcd_string(s);

  lcd_setcursor(10,1);
  sprintf(x,"l=%dmV ",l);
  lcd_string(x);



    while(1)
    {

    }
}



Hab nur schon mal die Ausgabe für das LCD Display gemacht. Wollte nur 
schon mal wissen wie man einen Schwellwert programmiert?

von Ingo L. (corrtexx)


Lesenswert?

Lukas F. schrieb:
> #include "lcd-routines.c"
Ich glaube das wird alles nicht so ganz einfach mit dir...
Zeichne dir zuerst einmal einen Programmablaufplan, dann wirst du sehen 
das du dein Display z.B. nicht updatest sondern nur einmal beschreibst

: Bearbeitet durch User
von Lukas F. (Firma: HTL St.Pölten) (lukas_fery)


Lesenswert?

Wollte doch bitte nur wissen wie man einen Schwellwert programmiert?
Wäre echt nett.

von HildeK (Gast)


Lesenswert?

Lukas F. schrieb:
> Wollte doch bitte nur wissen wie man einen Schwellwert programmiert?
> Wäre echt nett.

Wenn dein µC mit 5V versorgt wird und wenn du diese 5V auch als 
Referenzspannung eines ADCs verwendest, dann ist bei einem 10Bit-Wandler 
eben bei der Hälfte, also bei 2^10 / 2 = 512 auch die Eingangsspannung 
auf 2.5V.
Misst der ADC also irgendwas zwischen 0 und 511, dann ist die 
Eingangsspannung kleiner als 2.5V, sonst ist sie größer als 2.5V.

von Ingo L. (corrtexx)


Lesenswert?

Lukas F. schrieb:
> Wollte doch bitte nur wissen wie man einen Schwellwert programmiert?
Du misst die Spannung deines Schwellwertes und du misst die 
Messspannung. Dann vergleichst du beide. Du musst deinen Schwellwert 
also deinem µC über einen ADC-Eingang zur Verfügung stellen.
Also sinngemäß:

ADMUX auf Referenzeingang setzen
Messen und Ergebnis speichern
ADMUX auf Messeingang setzen
Messen und Ergebnis speichern
Beide Werte vergleichen und Ausgang setzen/löschen
Display update durchführen
Delay von 100ms

So kannst du das alles untereinander weg schreiben. Ist natürlich alles 
wenig elegant, wird aber funktionieren.
Hier mal eine Routine von mir für das Messen:
1
#define START_CONVERSATION()  ( ADCSRA |= (1<<ADSC) )
2
#define WAIT_FOR_DONE()      ( ADCSRA & (1<<ADSC) )
3
4
uint16_t MeasureAndMiddle ( uint8_t MuxChannel, uint8_t NumberOfConversations )
5
{
6
  uint16_t ADC_Temp = 0;
7
  
8
  /* Set Mux */
9
  ADMUX = MuxChannel;
10
  
11
  /* Limit Middle */
12
  if ( NumberOfConversations > 64 ) NumberOfConversations = 64;
13
  
14
  /* Dummy */
15
  START_CONVERSATION();
16
  while ( WAIT_FOR_DONE() ) asm volatile ("nop");
17
  ADC_Temp = ADC;
18
  ADC_Temp = 0;
19
  
20
  for ( uint8_t i = 0; i < NumberOfConversations; i++){
21
    START_CONVERSATION();
22
    while ( WAIT_FOR_DONE() ) asm volatile ("nop");
23
    ADC_Temp += ADC;
24
  }
25
  
26
  ADC_Temp /= NumberOfConversations;
27
  
28
  return ADC_Temp;
29
}
Am Setzen des MUX musst du evtl. noch etwas feilen, je nachdem welche 
Referenz du nutzt. Diese Version nutzt eine externe AREF.

: Bearbeitet durch User
von Lukas F. (Firma: HTL St.Pölten) (lukas_fery)


Lesenswert?

Danke für die Hilfe.

von Dieter F. (Gast)


Lesenswert?

Lukas F. schrieb:
> Danke für die Hilfe

Google ist in A bekannt :-)

Z.B. http://www.grzesina.de/avr/acompare/acompare.html

etc.

Es gibt viele Schwellwert-Beispiele - warum schaust Du Dir diese nicht 
an?

von Peter II (Gast)


Lesenswert?

Ingo L. schrieb:
> while ( WAIT_FOR_DONE() ) asm volatile ("nop");

sieht zwar cool aus dem nop - aber absolut überflüssig. Und sogar 
langsamer, weil im schlimmsten fall noch das nop abgearbeitet werden 
muss.
1
while ( WAIT_FOR_DONE() );

von Ingo Less (Gast)


Lesenswert?

Peter II schrieb:
> sieht zwar cool aus dem nop - aber absolut überflüssig.
Ja, überflüssig und einen Takt langsamer ist es auch. Aber ich baue es 
eigentlich immer ein, den einen Takt gönne ich mir einfach ;)

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.