Not logged in. · Lost password · Register

Page:  1  2  next 
5er
Member since Apr 2011
5 posts
Subject: Tankkontrolle - März 2010
Einfach mal zum drüberschauen.
alles was auf da angabe steht hab ich nicht mehr dazu geschrieben

  1. /*
  2. * Tankkontrolle.c
  3. *
  4. *  Created on: 29.07.2011
  5. *      Author: Manuel
  6. */
  7.  
  8. static volatile uint8_t abgespert = 0;
  9. static volatile uint16_t fill = 0;
  10.  
  11. ISR( INT1_vec) {
  12.     abgespert + 1;
  13.     abgespert %= 2;
  14.     //0 zu 1 oder 1 zu 0
  15. }
  16. ISR( INT0_vec) {
  17.     fill++;
  18.     if (fill >= FILL_MAX) {
  19.         PORTD &= ~(1 << 0);
  20.     }
  21. }
  22.  
  23. void main(void) {
  24.  
  25.     init();
  26.  
  27.     while (1) {
  28.         cli();
  29.         while (abgespert == 0) {
  30.             sleep_enable();
  31.             sei();
  32.             sleep_cpu();
  33.             sleep_disable();
  34.             cli();
  35.  
  36.         }
  37.         sei();
  38.                 //status vorher merken um pegelwechsel zu registrieren
  39.         static uint8_t vorher = 0;
  40.         if (PIND & (1 << 1) = !0) {
  41.             vorher == 1;
  42.         }
  43.  
  44.         while (abgespert == 1) {
  45.             if (vorher == 1 && (PIND & (1 << 1)) == 0) {
  46.                 cli();
  47.                 fill--;
  48.                 sei();
  49.                 vorher = 0;
  50.             } else if (vorher == 0 && (PIND & (1 << 1)) == 1) {
  51.                 cli();
  52.                 fill--;
  53.                 sei();
  54.                 vorher = 1;
  55.             }
  56.                         //zufluss öffnen
  57.             cli();
  58.             if (fill <= FILL_MIN) {
  59.                 PORTD |= (1 << 0);
  60.  
  61.             }
  62.  
  63.         }
  64.     }
  65. }
  66.  
  67. void init(void) {
  68.     //des was schon in da angabe steht
  69.     MCUCCR |= (1 << ISC00);
  70.     MCUCCR |= (1 << ISC01);
  71.  
  72.     MCUCCR |= (1 << ISC10);
  73.     MCUCCR &= ~(1 << ISC11);
  74.  
  75.     GICR |= ((1 << INT1) | (1 << INT0));
  76.     cli();
  77.     PORTD |= (1 << 0);
  78. }
This post was edited on 2011-07-29, 18:30 by 5er.
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
So, hab' schnell überflogen. Sieht gut aus. Nur in der init fehlt noch eine Kleinigkeit..... :)

Nachtrag: In Zeile 50 ist ein kleiner Fehler!  Und in 62 vermiss ich auch was. ;)
This post was edited 2 times, last on 2011-07-29, 19:42 by morty.
5er
Member since Apr 2011
5 posts
Erstmal Danke fürs Anschauen.
Denke die drei Sachen waren falsch?:
In da init hab ich vergessen PORTD als Ausgang zu setzen.
  1. DDRD|=(1<<0);
in Zeile 50: Des zweite bit muss 1 seins, nicht das niedrigste.  
  1.  } else if (vorher == 0 && ((PIND & (1 << 1)) == (1<<1)) {   //oder !=0

In Zeile 62 hab ich vergessen die Interrupts wieder einzuschalten.


Glaub die fehler hät ich nach fünf mal lesen nich gefunden ;)
D.Kay
Member since Oct 2010
15 posts
Ich glaube es fehlt auch noch die Funktionendeklaration der init() und Zeile 12 sollte so auch nicht funktionieren ;-)
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Quote by D.Kay:
Ich glaube es fehlt auch noch die Funktionendeklaration der init() und Zeile 12 sollte so auch nicht funktionieren ;-)

Jep, da hast du recht.

Quote by 5er:
  1. } else if (vorher == 0 && ((PIND & (1 << 1)) == (1<<1)) {   //oder !=0

"!=0" ist besser, weil du nur eine Stelle ändern musst, wenn du evtl doch einen Pin verändern willst.
holzblock
Member since Oct 2010
21 posts
Hallo!
Ich hab da mal 2 Fragen:

1. Warum schaltest du die Interrupts so oft an und aus z.B. benutzt du cli() direkt bevor du die while-schleife in zeile 27 verlässt aber schaltest unmittelbar danach die Interrupts wieder an. Was macht das für einen Sinn?

2. Woher weiß ich, wie ich Pin0 konfigurieren muss?
sicherha
Informatik-Veteran
Member since Oct 2010
53 posts
Quote by holzblock:
1. Warum schaltest du die Interrupts so oft an und aus z.B. benutzt du cli() direkt bevor du die while-schleife in zeile 27 verlässt aber schaltest unmittelbar danach die Interrupts wieder an. Was macht das für einen Sinn?
Das Konstrukt in Zeile 27-37 ist die Standard-Warteschleife™, mit der man auf das Eintreten eines externen Ereignisses wartet, das durch das Setzen einer Variable in einem Interrupt-Handler signalisiert wird. Die Interrupts muss man sperren, um das Eintreten des bekannten Lost-Wakeup-Problems [1] zu verhindern.

Die anderen Interruptsperren sind dafür da, den Zugriff auf die Zählvariable atomar zu machen (Stichwort Lost-Update-Problem [2]). In Zeile 62 vermisse ich noch das Freigeben per sei().

[1] Eine Ereignissignalisierung geht verloren, wenn sie zwischen der Entscheidung, dass man schlafen muss, und dem tatsächlichen Einschlafen kommt.
[2] Ein Variablenzugriff wird durch einen zweiten Zugriff unterbrochen, bevor er sein Ergebnis zurückgeschrieben hat. Dann gehen die Änderungen, die der unterbrechende Zugriff gemacht hat, verloren.
holzblock
Member since Oct 2010
21 posts
Ahja! Jetz hab ich das glaub ich verstanden! Danke!
Und wie schauts aus mit Frage 2?
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Quote by holzblock:
Ahja! Jetz hab ich das glaub ich verstanden! Danke!
Und wie schauts aus mit Frage 2?
...steht in der Angabe. Auch wenn bei der Tank-Aufgabe das Leseverständnis, bei dem Deutschland ja laut PISA nicht so der Hit ist, getestet wird. ;) Ohne die Infos rauszuschreiben hätte ich sie aber wohl auch nicht geschafft.
This post was edited on 2011-08-01, 11:26 by morty.
mukkl
Member since May 2011
12 posts
Hallo,
2 Fragen: Ist es möglich in dem Teil "Abfluss überwachen" (Zeile 39 -64) auch so kurz zu schreiben:
  1. int vorher = (PORTD & (1<<1)) > 0;
  2.  
  3. while(!abgesperrt){
  4.     if(((PORTD & (1<<1)) > 0)  != vorher){
  5.         fill--;
  6.  
  7.         vorher = !vorher;
  8.         if(fill <= FILL_MIN){
  9.             PORTD |= 1;
  10.         }
  11.     }
  12. }
2. Wofür braucht man vor dem fill-- (Zeile 47) ein cli() und danach ein sei() ?
This post was edited on 2011-08-03, 00:39 by dom.
Edit reason: code tags hinzugefügt
joan
Member since Apr 2011
15 posts
hi,
könnte jemand die Standardwarteschleife von mal genauer erklären. Sie wurde zwar schon von sicherha beantwortet aber ganz verstanden hab ich es noch nicht.
Vor allem die stelle nach sleep_disable();. Es ist mir schleierhaft warum man die interrupts mit cli() sperrt und dann mit sei() gleich wieder macht.
Die while schleife wird doch hier ohnehin verlassen da man sonst aus dem Befehl sleep_cpu nicht herauskommt.
Besten Dank schon mal :).

  1.     while (1) {
  2.         cli();
  3.         while (abgespert == 0) {
  4.             sleep_enable();
  5.             sei();
  6.             sleep_cpu();
  7.             sleep_disable();
  8.             cli();
  9.  
  10.         }
  11.         sei();
This post was edited on 2011-08-03, 00:40 by dom.
Edit reason: code tags
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
mukkl: ja
joan: Der Suchbegriff für die Folien heißt lost wakeup.
joan
Member since Apr 2011
15 posts
ja auf den folien hab ich es durchgearbeitet aber ich habe nicht alles verstanden und ich habe gehofft jemande könnte es nochmal mit anderen worten formuliern.
mukkl
Member since May 2011
12 posts
Ahh ok! Vielen Dank!
Und was ist mit der Frage 2  ? :-)
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
@mukkl: Hier heißt das Suchwort lost update (bei 16 Bit Variablen)
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O :troll:
Special characters:
Page:  1  2  next 
Go to forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen