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
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.
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?
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
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)
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
#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?
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
Wollte doch bitte nur wissen wie man einen Schwellwert programmiert? Wäre echt nett.
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.
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
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?
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() ); |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.