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
}
}
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.
> bekomme dies aber nicht zum laufen.
was läuft denn nicht? Compilerfehler, funktionale Fehler, ... ?
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
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.
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
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.