Forum: Mikrocontroller und Digitale Elektronik C Programm Fehler Lichtschrankenansteuerung


von Lars O. (nelo)


Lesenswert?

Hallo und einen schönen guten morgen zusammen,

ich bin leider noch ziemlich neu in der C Programmierung und habe die 
Aufgabe ein C Programm für einen Atmega 8 zu schreiben in dem eine Zeit 
zwischen dem ich sage jetzt einfach mal auslösen der 1.Lichtschranke und 
der 2. Lichtschranke gemessen werden soll und danach durch die Zeit und 
der festgelegten Strecke die Geschwindigkeit berechnet werden soll. Ich 
habe da auch schon ich hoffe ziemlich alles zusammengestellt bekomme 
dies aber nicht zum laufen.
Vielleicht kann mir ja einer von euch weiter helfen. Falls ihr noch 
weitere Informationen benötigt sagt bitte bescheid und erschlagt mich 
bitte nicht direkt.

C - Code

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>                    // stdio.h benutzen / laden
#include <stdlib.h>                    // stdlib.h benutzen / laden
#include <avr/io.h>                    // io.h benutzen / laden
#include <avr/delay.h>                // delay.h benutzen / laden
#include <avr/interrupt.h>              // interrupt.h benutzen / laden
#include <avr/signal.h>                // signal.h benutzen / laden
#include "lcd.h"                // lcd.h benutzen für LC-Display von 
Peter Fleury / laden
#define F_CPU 1000000                // setzte CPU Taktfrequenz in Hz 
(_delay_ms)

  float distanz=1000;               // Messentfernung in mm
  float ein_counter_dauer = 0.000008;           // 1000000 Hz / 8 in s
  float counter=0, metersec=0, kmh=0, highscore=0;
  char buffermetersec[10], bufferkmh[10], bufferkmhmax[10], 
buffercounter[20], wait;



        // Verhalten bei zu langer Messdauer des Timers1
SIGNAL (SIG_OVERFLOW1)
{
  TCCR1B = 0; 
//Stoppe Counter
  counter=0;                      // Var. counter auf 0 setzten
  PORTD = (0<<PIN7);                    // STATUS LED aus bzw rot
  lcd_clrscr();                                           // LCD Display 
löschen
  for (wait=0; wait<50; wait++)                                       // 
Zeitschleife 50 x 200ms >> 10 sekunden
  {
        lcd_gotoxy(6,1);                                          // 
Position 5 in Zeile 2
        lcd_puts("Messdauer"); 
// Text  über Display ausgeben
        lcd_gotoxy(3,2);                                          // 
Position 4 in Zeile 3
        lcd_puts("ueberschritten"); 
// Text über Displayausgeben
        _delay_ms(200);                      // 200ms wait Wartezeit
    }
    lcd_clrscr();                                                 // LCD 
Display löschen
  PORTD = (1<<PIN7);                     // Status LED grün an
}



        // Verhalten bei Interrupt 0
SIGNAL (SIG_INTERRUPT0)
{
  TCCR1A = 0;                // Timer / Counter Controll Register 1 A
  TCNT1 = 0;                // Inhalt Timer/Counter1
  TCCR1B |= ((0<<CS12) | (1<<CS11) | (0<<CS10));        // Timer
  /*
  CS12  CS11  CS10
  0    0    0        Counter / Timer stopped
  0    0    1        No prescaling (Systemtakt)
  0    1    0        Clock/8 prescaler
  0    1    1        Clock/64 prescaler
  1    0    0        Clock/256 prescaler
  1    0    1        Clock/1024 prescaler
  1    1    0        Externer Takt T1 - fallende Flanke
  1    1    1        Externer Takt T1 - steigende Flanke
  */
  TIMSK |= (1<<TOIE1);              // Timer/Counter Interrupt Mask  - 
Overflow Inttrupt enable

  /* Beschreibung folgt noch zur einrichtung der Timer*/
  //cli();                // Interrupts gesperrt
  //PORTD = (0<<PIN7);              // STATUS LED rot an
  //_delay_ms(50);              // 50 ms wait Wartezeit
  //sei();                // Interrupts wider frei gegeben
}




// Verhalten bei Interrupt 1
SIGNAL (SIG_INTERRUPT1)
{
  counter=0;                                                     // 
Counter Var. Auf 0 setzten
  TCCR1B = 0;                                                    // 
Stoppe Timer0
  counter = (TCNT1);              // Timerinhalt in Var. counter 
schreiben
  PORTD = (0<<PIN7);              // STATUS LED rot an

  cli();                  // Interrupts sperren!
  PORTD = (0<<PIN7);               // Status LED rot an
  lcd_clrscr();                 // Lösche Display inhalt
  lcd_gotoxy(3,0);              // Cursor nach Position 4 in Zeile 1
  lcd_puts("Messung abgeschlossen");          // Text über Display 
ausgeben

  metersec=(distanz/1000)/(counter*ein_counter_dauer);      // 
Berechnung für Meter pro Sekunde
  dtostrf(metersec,5,3,buffermetersec);           // Umwandeln von float 
nach Char
  lcd_gotoxy(0,2);              // Cursor nach Position 1 in Zeile 3
  lcd_puts(buffermetersec);            // Text über Display ausgeben
  lcd_puts(" m/s");              // Text über Display ausgeben

    kmh = (metersec*3.6);                  // Berechnung kmh
  dtostrf(kmh,5,3,bufferkmh);             // Umwandeln von float nach 
String
  lcd_gotoxy(0,3);              // Cursor nach Position 1 in Zeile 4
  lcd_puts(bufferkmh);              // Text über Display ausgeben
  lcd_puts(" km/h");              // Text über Display ausgeben

  for (wait=0; wait<25; wait++)            // Schleife läuft 25 mal 
200ms - 5 sekunden
  {
    _delay_ms(200);              // 200ms wait Wartezeit
  }

  sei();                  // Interrupts wider frei gegeben
  PORTD = (1<<PIN7);               // Status LED grün an
  lcd_clrscr();                // Lösche Display inhalt
}






int main (void)
{
  cli();                                        // Interrupts sperren!
  lcd_init(LCD_DISP_ON);                  // LCD Display einschalten
  lcd_clrscr();                     // lösche LCD Display inhalt 
// LCD löschen

  DDRD |= ( (0<<DDB2) | (0<<DDB3) | (0<<DDB4) | (0<<DDB5) | (0<<DDB6)); 
// Eingänge des MK definieren
  DDRD |= (1<<DDD7);                                  // Ausgänge 
definieren

  PORTD |= ((1<<PORTD2) | (1<<PORTD3) | (0<<DDB5) | (0<<DDB5) | 
(0<<DDB6));    // PULL-UP Widerstände intern aktivieren

  GICR |= (1<<INT1) | (1<<INT0);
  MCUCR |= (1<<ISC11) | (1<<ISC10) | (1<<ISC01) | (1<<ISC00);

  cli();                      // Interrupts gesperrt

  PORTD = (1<<PIN7);                  // STATUS LED rot an

  lcd_clrscr();                     // LCD Initialisieren

  lcd_gotoxy(0,0);                  // Position 1 in Zeile 1
  lcd_puts("Geschwindigkeit 2011");                // Text über Display 
ausgeben

  lcd_gotoxy(0,1);                  // Position 1 in Zeile 2
  lcd_puts("- Michael xxxx");                // Text über Display 
ausgeben

  lcd_gotoxy(0,2);                  // Position 1 in Zeile 3
  lcd_puts("- Thomas xxxxx");              // Text über Display ausgeben

  lcd_gotoxy(0,3);                  // Position 1 in Zeile 4
  lcd_puts("- Lars xxxx");                // Text über Display ausgeben

  for (wait=0; wait<10; wait++)                // Schleife läuft 10 mal 
200ms >> 2 Sekunden
  {
    _delay_ms(200);                  // 200ms wait Wartezeit
  }
  wait=0;


  lcd_clrscr();

  lcd_gotoxy(2,1);                              // Position 3 in Zeile 2
    lcd_puts("Keine Verbindung"); 
// Text ausgeben

    lcd_gotoxy(1,2);                                          // 
Position 2 in Zeile 3
    lcd_puts("Lichtschranken ausrichten"); 
//Text über Display ausgeben

  PORTD = (0<<PIN7);                  // STATUS LED rot an

    while(PIND & (1 << PD6));            // Warten bis an PD6 ein LOW 
Signal anliegt (kreis geschlossen)

    _delay_ms(254);                  // 254ms wait Wartezeit

    lcd_clrscr();                  // lösche Display text

    lcd_gotoxy(7,1);                            // Position 8 in Zeile 2
    lcd_puts("Achtung"); 
// Text über Display ausgeben

    lcd_gotoxy(3,1);                            // Position 4 in Zeile 2
    lcd_puts("Lichtschranken"); 
// Text über Display ausgeben

    lcd_gotoxy(5,2);                            // Position 6 in Zeile 3
    lcd_puts("ausrichten!"); 
// Text über Display ausgeben

    lcd_gotoxy(1,3);                             // Position 2 in Zeile 
4
    lcd_puts("mind. 3sek Stabil"); 
// Text über Display ausgeben

    _delay_ms(254);                   // 254ms wait Wartezeit

do
{
  wait++;
  _delay_ms(100);                    // 100ms wait Wartezeit
  if (PIND & 0<<PD5)
  wait = 0;
  _delay_ms(100);                    // 100ms wait Wartezeit
  if (PIND & 0<<PD4)
  wait = 0;
  _delay_ms(100);                    // 100 ms wait Wartezeit
}
  while( wait < 10 );

  lcd_clrscr();                    // loesche Display inhalt

  PORTD = (1<<PIN7);                   // Status LED grün an

  wait=0;

  for (wait=0; wait<10; wait++)                // Schleife läuft 50 mal
  {
    _delay_ms(100);                  // 100ms wait Wartezeit
  }
  wait=0;

  lcd_clrscr();                     // loesche Display inhalt

  for(;;)                      // Endlosschleife
  {
    sei();                    // Interrupts freigeben

    if (highscore<=kmh) highscore=kmh;            // wenn Highscore 
kleiner ist als kmh wird dieser ersetzt
    dtostrf(highscore,5,3,bufferkmhmax);             // Umwandeln von 
float nach String

    lcd_gotoxy(7,0);                // Position 8 in Zeile 1
    lcd_puts("Bereit");                // Text über Display ausgeben

    lcd_gotoxy(5,2);                // Position 6 in Zeile 3
    lcd_puts("Hoechstgeschwindigkeit");            // Text über Display 
ausgeben

    lcd_gotoxy(4,3);                // Position 5 in Zeile 4
    lcd_puts(bufferkmhmax);                // Text über Display ausgeben
    lcd_puts(" km/h");        // Text über Display ausgeben

    _delay_ms(200);                  // 200ms wait Wartezeit
    _delay_ms(200);                  // 200ms wait Wartezeit
  }
}

von Helfer (Gast)


Lesenswert?

1) Was funktioniert nicht? Wie soll das Programm arbeiten, welche Logik 
steht dahinter?

2) F_CPU wird in den Delay-Routinen benutzt. Deine Reihenfolge hier ist 
problematisch:
1
#include <avr/delay.h>                // delay.h benutzen / laden
2
...
3
#define F_CPU 1000000                // setzte CPU Taktfrequenz in Hz

3) Formatierter Code ist einfacher zu lesen.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

> bekomme dies aber nicht zum laufen.

was läuft denn nicht? Compilerfehler, funktionale Fehler, ... ?

von Matthias (Gast)


Lesenswert?

Lars O. schrieb:
> Ich
> habe da auch schon ich hoffe ziemlich alles zusammengestellt bekomme
> dies aber nicht zum laufen.

Auf eine klare Frage gibt es nur eine klare Antwort: 42

Tips: Für längere Codes gibt es Anhänge. Dann kann sich das ein 
freundlicher Forumsmensch sogar herunterladen und den Compiler drauf 
loslassen

von Lars O. (nelo)


Lesenswert?

Ich habe Compilerfehler die ich leider nicht verstehe.
Die Ansteuerung des Display sowie der LED funktioniert nicht, vermute 
das meine *.hex die zwar erzeugt wird fehlerhaft ist.
werde in ein paar min mal die Meldungen posten, sowie ich sie hab.

von Lars O. (nelo)


Lesenswert?

Das ist alles was mit WINAVR Notepad beim erstellen der Hex. auswirft.
Kann es möglich sein, das Notepad ein paar links nicht findet ?

Compiling: main.c
avr-gcc -c -mmcu=atmega8 -I. -gdwarf-2   -Os -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -Wall 
-Wstrict-prototypes -Wa,-adhlns=main.lst  -std=gnu99 
-Wp,-M,-MP,-MT,main.o,-MF,.dep/main.o.d main.c -o main.o

Compiling: lcd.c
avr-gcc -c -mmcu=atmega8 -I. -gdwarf-2   -Os -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -Wall 
-Wstrict-prototypes -Wa,-adhlns=lcd.lst  -std=gnu99 
-Wp,-M,-MP,-MT,lcd.o,-MF,.dep/lcd.o.d lcd.c -o lcd.o

Linking: main.elf
avr-gcc -mmcu=atmega8 -I. -gdwarf-2   -Os -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -Wall 
-Wstrict-prototypes -Wa,-adhlns=main.o  -std=gnu99 
-Wp,-M,-MP,-MT,main.o,-MF,.dep/main.elf.d main.o lcd.o   --output 
main.elf -Wl,-Map=main.map,--cref    -lm

Creating load file for Flash: main.hex
avr-objcopy -O ihex -R .eeprom main.elf main.hex

Creating load file for EEPROM: main.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex main.elf main.eep

Creating Extended Listing: main.lss
avr-objdump -h -S main.elf > main.lss

Creating Symbol Table: main.sym
avr-nm -n main.elf > main.sym
/usr/bin/sh: /c/WinAVR/bin/avr-nm: Invalid argument
make.exe: *** [main.sym] Error 126

> Process Exit Code: 2
> Time Taken: 00:12

von Lars O. (nelo)


Angehängte Dateien:

Lesenswert?

Hier einmal der gewünschte C Code .... SORRY

von Hubert G. (hubertg)


Lesenswert?

Wenn ich das Signal auf ISR umschreibe
Das #include <avr/signal.h> lösche und das F/CPU in den Configuration 
Options eintrage dann kompiliert das AVR-Studio ohne Fehler und 
Warnungen.

von Hubert G. (hubertg)


Lesenswert?

Noch ein paar Kleinigkeiten:
PORTD= (0<<PIN7);   // STATUS LED aus bzw rot

Du solltest dir eventuell das hier durchlesen:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_IO-Ports

In eine ISR sollte man nicht so viel hinein packen.

von Lars O. (nelo)


Lesenswert?

Vielen Dank

werde eure Tipps morgen früh mal versuchen umzusetzten,
werde euch bescheid geben obs geklappt hat.

Gruß

Lars

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.