Hallo Erstmal dazu ich habe übersoein Problem schon überall geguckt, aber es kommt mir so vor als wenn noch niemand versucht hat ein Tachometer zuprogrammieren. Aufjedenfall habe ich ein Software Problem und zwar mit C. Ich habe das Programm zwar fertig aber es funktioniert nicht. Hardware ist in ordnung alles geprüft. Ich kann mir nur nicht erklären warum das Programm selber nicht funktioniert. Das einzige was auf den 3 segment anzeigen angezeigt wird ist 0. Das soll er auch tun aber er fängt nicht anzuzählen. Ich wollte also fragen ob sich jemand damit auskennt und mir helfen kann. Ich hoffe jemand hat eine Idee. Was ich falsch gemacht habe. wenn ihr noch fragen habt was ihr braucht um mir zuhelfen dann schreibt mir bitte per email oder hier als antwort. Danke
ups, na ja... du solltest das Gundkonzept nochmal überdenken. Die Segmentansteuerung sieht etwas sehr unübersichtlich aus (das macht man mit einer Tabelle, die im Flash steht). if(v => 100) { v1=v/100; v2=(v-(v1*100))/10; v3=v-((v1*100)+(v2*10)); } if(v => 10) { v2=v/10; v3=(v-(v2*10)); } if(v < 10) { v3=v; } } Das ist auch nicht gerade elegant gelöst, falsch noch dazu. Wenn schon tippel-tappel-tour, müsste dann ein else if hin (falls v>=100 ist, wird bei dir auch die Berechnung für v>=10 durchgeführt). Da aber jegliche Kommentare fehlen, fällt es mir ziemlich schwer da durchzusteigen. So könnte man nur mit viel Mühe dahinterkommen, was du eigentlich da machst.
Hallo Dennis, auf den ersten Blick fällt mir auf, dass Dein Prototyp und die Funktion verschieden heißen, aber das ist wohl nur ein Tippfehler... int avriabler_zaehler(void); int variabler_zaehler(void){} Hast Du schon mal etwas von switch-case-Abfragen gehört? Diese
1 | if(v1==0) { |
2 | PORTB = 0xf6; |
3 | }
|
4 | ...
|
Abfragerei ist ja gräßlich. Probier mal:
1 | switch( v1 ) |
2 | {
|
3 | case 0: PORTB = 0xf6; |
4 | case 1: PORTB = 0x14; |
5 | case 2: ... |
6 | }
|
Zu Deinem eigentlichen Problem: Meine Glaskugel ist defekt, beschreibe doch nur mal kurz, was Du da für Impulse detektierst. Am besten Du zeigst mal eine Schaltung. Kommentare im Quelltext sollen ungemein der Leserlichkeit von Programmen dienen, hat mal jemand gesagt... Gruß, Nils
Sorry für das Doppelposting... Ich weiß auch nicht, wie ich das geschafft habe. Ja, eine Tabelle ist noch um ein vielfaches eleganter. Nils
> int main(void) > { > DDRA = 0xff; > DDRB = 0xff; > DDRC = 0x00; > DDRD = 0xff; > > PORTA = 0xf6; > PORTB = 0xf6; > PORTD = 0xf6; > > > > int zaehler(void); Das hier ist kein Funktionsaufruf. Das deklariert einfach nur das es irgendwo eine Funktion namens 'zahler' gibt, die keine Argumente erwartet und einen int zurückliefert. Um die Funktion auszurufen, schreibst du zaehler(); > do > { > int avriabler_zaehler(void); dito > int berechnung(void); dito > int segment_1(void); dito > int segment_2(void); dito > int segment_3(void); dito > } Wusste gar nicht, dass man in C jetzt auch mitten drin Deklarationen machen kann. Auf jeden Fall: Da sind noch einige andere Syntaxfehler. Das gepostete geht nie und nimmer durch den Compiler. Es heist if( a >= b ) und nicht if( a => b ) Du brauchst dringend Einführungsliteratur zum Thema 'Einführung in C'
Erstmal vielen vielen dank für die hilfe. ICh weiß das ich selber kein C Ass bin :). Und ich wundere mich eigentlich darüber das jeder auf die Syntax und if-fehler aufmerksam geworden ist. Diese werden natürlich sofort geändert. Ich hätte nur noch ine Frage . Und zwar sind die Timer richtig gemacht? denn ich kenne mich mit controllern genauso gut aus wie mit C :) und zum Compilieren. Komischerweise kann ich das ohne fehler und warnungen Kompilieren. Aber trotzdem werde ich es mit euren hilfen ändern. Danke nochmal an alle
Hier nochmal meine Documentation. Und nochmal zur erklärung, damit ihr das auch versteht. Als Simulator haben wir ein 28 zoll Rad mit einem Signalgeber (TTL) das bei jedem mal wenn das Rad einmal rum ist ein signal gibt. Da ich irgendwie die Frequenz meines Controllers rausfand habe ich mir überlegt wie das umgehen kann. Undzwar in dem ich impulse zähle wenn das Rad bei 1km/h einmal herumlaüft. Also signal timer start zweites signal Timer auslesen. Das wird gespeichert. Am besten für immer hab nur noch nicht rausgefunden wie. Das macht er in der Funktion zaehler. Dann haben wir die Funktion variabler_zaehler dort wird es dauerhaft geprüft. Ich meine damit das sowie der motor an ist der das Rad antreibt, jedesmal wenn das rad rum ist die geschwindigkeit anzeigt. Und hier wird halt gezählt um dies mit der festen impulszahl die wir bei 1km/h gezählt haben ins verhältnis setzt. Also stellt euch vor das Rad bewegt sich mit einer geschwindigkeit von 5km/h, dann muss natürlich ein fünftel von dem gezählt werden wie bei 1 km/h weil sich das rad ja fünfmal schneller dreht. und die restlichen berechnungen mit 100 und 10 dient nur dazu die zahlen zu vereinzeln. Also wenn ich 293 km/h raus habe soll er ja auf jedem meiner 3 segmente eine zahl ausgeben und um das zugewährleisten muss ich diese in 3 zahlen aufteilen. Ich hoffe das hilft euch weiter. Danke
Ohne dir schon wieder an den Karren fahren zu wollen - Word-Dokumente sind hier nicht sonderlich beliebt, bei mir gibts nichtmal Word. Gehts auch als reine Text-Datei?
Oben bei dieser Switch-Case Anweisung ist ein Fehler. Nach jedem case-Block muss ein break; kommen, damit er aus dem Konstrukt herausspringt.
Hier als txt docu. Habe es allerdings nur kopiert und weil da grafiken drinnen sind kann es sein das dort stellen sind wo rauf ich mich auf die grafik bezogen habe. Aber wenn man den quellcode dazu nimmt kommt man eigentlich ganz gut zurecht. Und nochwas ich kann schon einiges ab und keine fährt mir an den karren. warum auch ich erwarte sogar das ihr mir eure meinung dazu sagt, damit ich es beim nächsten mal besser machen kann. also danke
> Und ich wundere mich eigentlich darüber das jeder auf die Syntax und > if fehler aufmerksam geworden ist Liegt vielleicht daran, dass das ganz elementare Fehler sind. Jeder C-Anfänger sollte eigentlich einen Grossteil dieser Fehler nach der zweiten Lehrstunde 'Einführung in C' nicht mehr machen, bzw. selbst finden können > Hier nochmal meine Documentation. Und? Wo ist jetzt dein korrigiertes Program? Du kannst mal davon ausgehen, dass diejenigen die dein Pgm hier korrigieren schon einige Jährchen programmieren am Buckel haben. Denen brauchst du nicht die elementarsten Dinge der Sprache C erklären. Was wir aber von dir erwarten: Wenn wir dir schon Hilfestellung geben, dass du dann dein Pgm entsprechend umbaust und das veränderte Pgm, falls du noch Schwierigkeiten hast, wieder postest. Persönlich denke ich, dass du dich mit der Aufgabenstellung etwas übernommen hast. Du versucht, bildlich gesprochen, einen Marathon zu gewinnen noch bevor du gehen gelernt hast.
>> Liegt vielleicht daran, dass das ganz elementare Fehler sind. >> Jeder C-Anfänger sollte eigentlich einen Grossteil dieser >> Fehler nach der zweiten Lehrstunde 'Einführung in C' nicht >> mehr machen, bzw. selbst finden können Diesen kommentar hättest du dir auch sparen können. Ich weiß selber das ich ein grosser Anfänger bin. Meiner meinung nach ist das was ich aber gmacht habe nur schlechter c-stil und ich glaube nicht das das so wichtig hier ist oder. Genauso wenn ich mich verschrieben haben soll bei diesen if warum meckert der compiler dann nicht. Aber sry das jemand der nicht gut in etwas ist fragen hat. Aber typisch wenn man was kann vergisst man schnell das man selber mal angefangen hat. Und ausserdem ist das ein projekt für die schule und nicht für mich. Ich finde es echt schade das es soviele leute gibt die einen an den kopf werfen müssen das man schlechter als ein anfänger ist nur weil man was nicht so begriffen hat. Ma sehen vielleicht bekomme ich das noch hin. Vielleicht ist ja jemand hier der sich die mühe macht die documentation durchzulesen und mir dann bei meinen Problem zuhelfen. Danke
zu crazy_horse Vielleicht sagst du mir mal ob du damit ein bestimmtes buch meinst oder einfach nur als Satz. wenn es ein buch ist könntest du mir die ISBN nummer gebn und den autor name wäre cool Danke
> Diesen kommentar hättest du dir auch sparen können. Nur dann wenn du dir gespart hättest: >>Und ich wundere mich eigentlich darüber das jeder auf die Syntax und >> if fehler aufmerksam geworden ist > Meiner meinung nach ist das was ich aber gmacht habe nur > schlechter c-stil Na ja. Im Ernst: so schlecht ist dein Stil gar nicht. OK. die riesengrossen switch-case Leisten hätte man vermeiden können, aber Rest ist gar nicht so übel. Bis auf die paar lausigen und üblen Syntax-Fehler. Aber wenn du die korrigierst, sollte man im AVR-Studio im Simulator schon einiges sehen können. Wenn du allerdings nichts korrigierst wirst du auch nicht viel sehen, da dein Pgm dann ausser der Initialisierung nichts macht.
> v=(((3.14*(28*2.54))/100)/(8,037/impuls_diverenz))*3.6;
^
|
Kommazahlen werden mit einem .
geschrieben, nicht mit einem ,
Durch das , hat dein Code eine interessante Wendung bekommen.
Das soll auch mal folgendes verdeutlichen
* Wenn der Compiler ein Pgm anstandslos annimmt, heist
das noch lange nichts
* In C ist es möglich mit nur einem falsch gesetzten Zeichen
ein Pgm komplett im Sinn zu verändern. Und zwar ohne das
der Compiler etwas auszusetzen hätte. Das Pgm entspricht
immer noch den C-Sprachregeln, macht aber etwas komplett
anderes.
* daraus folgt: In C muss man besonders grosse Sorgfalt walten
lassen. Vieles was syntaktisch richtig ist, ist aus Sicht
allgemeiner Programmierlogik kompletter Unsinn.
gut das du noch da bist ich habe das mit den funktionen ausprobiert und der compiler meckert wenn ich es so mache wie du aber nicht wenn ich die funktion in der main mit int und void mache. muss ich noch zusätzlich zaehler(); ?
krass nur ein kleiner tipp fehler und alle fehler sind weg :)
../probe.c:42: warning: implicit declaration of function `zaehler' das habe ich jetzt stehen wenn ich das so mache wie du gesagt hast bei allen meinen funktionen. WAs heißt das genau?
Punkt 1) Wie sieht dein Pgm jetzt exakt aus Poste mal die Quellcode-Datei Punkt 2) Sag niemals: Der Compiler meckert. Der Compiler gibt dir eine Fehlermeldung. Die gibt (meist) einen Hinweis darauf was falsch ist. Punkt 3) So wie du es gemacht hast, ist das zwar syntaktisch richtig (= entspricht den Regeln der Sprache) ist aber trotzdem Unsinn. Du willst an dieser Stelle ja nicht die Funktion deklarieren, sondern du willst die Funktion aufrufen.
#include <avr/io.h> #include <stdint.h> int zaehler(); int variabler_zaehler(); int berechnung(); int segment_1(); int segment_2(); int segment_3(); int v=0; int v1=0; int v2=0; int v3=0; int impuls_diverenz; unsigned int impuls_1; unsigned int variable_impuls_1; unsigned int impuls_2; unsigned int variable_impuls_2; unsigned int impuls_fest; unsigned int impuls_variable; int main(void) { DDRA = 0xff; DDRB = 0xff; DDRC = 0x00; DDRD = 0xff; PORTA = 0xf6; PORTB = 0xf6; PORTD = 0xf6; zaehler(); do { variabler_zaehler(); berechnung(); segment_1(); segment_2(); segment_3(); } while(PINC2==0); }
Aso und als warnung kommt noch ../probe.c:62: warning: control reaches end of non-void function das andere habe ich behoben da ich die funktionen garnicht deklariert hatte.
> ../probe.c:42: warning: implicit declaration of function `zaehler'
OK.
Der Compiler arbeitet dein Pgm von oben nach unten durch.
Wenn er oben anfängt weiss er noch gar nichts, ausser den
C-Schluesselwoertern. Stoesst er jetzt auf etwas, was ernicht
kennt, dann gibt es 2 Moeglichkeiten:
* wird das was er nicht kennt wie eine Variable verwendet, zb
i = 2 * j; // j nicht deklariert
dann lautet die Fehlermeldung meist: undefined reference
oder so ähnlich
* wird das was er nicht kennt wie ein Funktionsaufruf verwendet
zb.
zaehler();
dann geht der Compiler davon aus, dass tatsaechlich irgendwo
eine Funktion namens 'zaehler' existiert. Da er aber nichts
weiter darueber weis, nimmt er Standardannahmen an:
* die Funktion erwartet keine Argumente
* die Funktion liefert einen int zurück.
Und genau das teilt dir der Compiler mit: implizit declaration
also: eine durch die Verwendung festgelegte Deklaration. Durch
die Art und Weise wie du die Funktion verwendet hast, bastelt
sich der Compiler selbst eine Deklaration zurecht.
Was kannst du dagegen tun.
Das einfachste ist es, die Funktion einfach vor ihrer Verwendung
zu definieren. ALso in der Art
void zaehler()
{
.... // mach was
}
int main()
{
....
zaehler();
}
Wenn sich jetzt der Compiler wieder von oben nach unten
durcharbeitet, so sieht er zuerst die Funktion zaehler() in
ihrer ganzen Pracht und kann sich daher auch merken, wie die
Schnittstelle zu ihr aussieht: das sie keine Argumente entgegen
nimmt und nichts zurückliefert.
Wenn er dann auf den Funktionsaufruf stösst, schaut der Compiler
in seinen internen Tabellen nach, ob er eine Funktion zaehler()
kennt. "a da ist sie. Wie war das: nimmt keine Argument und
liefert nichts zurück. Prima, passt genau zu der Art und Weise
wie die Funktion aufgerufen wird. Alles klar, kann ich so übersetzen"
Eine andere Möglichkeit ist es, eine Funktion einfach nur vor
der ersten Verwendung zu deklarieren:
void zaehler( void ); /* das ist eine Deklaration. Sie sagt nur
aus, dass es irgendwo eine Funktion namens
zaehler gibt und dass sie keine Argumente
erwartet und auch nichts zurückliefert
*/
int main()
{
...
zaehler(); /* mit der Deklaration von oben, hat der
Compiler alles was er an dieser Stelle
braucht.
Er weiss, dass es tatsaechlich eine
Funktion zaehler gibt (koennte ja auch
ein Tippfehler sein). Er weiss auch, dass
zahler() keine Argument annimmt und nichts
zurückliefert.
Mehr interessiert ihn an dieser Stelle
nicht. Der Compiler will nur überprüfen
ob der Aufruf der Funktion dieser Schnitt-
stellenvereinbarung entspricht oder nicht.
*/
...
}
void zaehler()
{
..... /* und hier ist dann die Funktion zaehler in ihrer
ganzen Pracht
*/
}
man finde ich echt nett das du mir das so ordentlich erklärst und voralle dem ich habs sogar verstanden:) Danke für die mühe finde ich super
OK (unsere Nachrichten überschneiden sich) Also, den implicit declaration hast du ja jetzt behoben War wohl Möglichkeit 3: ein simpler Tippfehler. Was heist jetzt: control reaches end of non-void Funktion. Nun. Du hast eine Funktion int zaehler() { .. } das 'int' da vorne bedeutet: Diese Funktion liefert einen int (also eine Ganzzahl) zurück. Nur, hier ist die Funktion: int zaehler() { if(PINC1 == 1) { TCCR1B |= (1<<CS12)|(1<<CS10); } if(PINC1 == 1) { impuls_1 = TCNT1L; impuls_2 = TCNT1H; impuls_fest = impuls_1 + impuls_2; } } Wo liefert die irgendetwas zurück? Ich sehe da keinen return 1; oder return irgendetwas; oder return ... (irgendwas was als int Zahl gilt) Wenn deine Funktionen nichts zurückliefern, weil es keinen vernünftigen Return Wert gibt (oder du noch nicht weist wie man das macht) dann sind das void Funktionen. void zaehler() { ... } (Nicht vergessen: die Deklaration ganz am Anfang auch umändern. Sonst stimmen Deklaration und Implementierung der Funktion nicht zusammen)
kann man nur ein wert zurückgeben? Da ich bei der funktion berechnung v1,v2 und v3 als wert auch in anderen funktionen brauche.
> kann man nur ein wert zurückgeben?
Ich sag jetzt mal: Ja, man kann nur einen Wert zurückliefern.
Natürlich gibt es Mittel und Wege diese Beschränkung zu umgehen
(Stichwort: struct), aber nicht zuviel auf einmal. struct's
sind ein Thema für später.
hier mal wie ich versucht habe es zu lösen kann man das so lösen?
Ja, könnte man. Was bringt's. Im Moment nicht viel, da der Aufrufer nichts mit dem zurückgegebenen Wert macht. Wie würde das aussehen: int main() { int Impulse; ... Impulse = zaehler(); zaehler() liefert jetzt einen Wert zurück und in main() (also beim Aufrufer) wird er zurückgegebene Wert in einer Variablen gespeichert. Den könnte man dann wieder an andere Funktionen übergeben, etc. Wart mal einen Moment, ich bereite grade eine ander Nachricht vor, die dir mehr bringt, da sie einiges an der Programmlänge verändert.
Es geht um diese Funktion hier: int segment_1() { if(v1==0) { PORTB = 0xf6; } else if(v1==1) { PORTB = 0x14; } else if(v1==2) { PORTB = 0xba; } else if(v1==3) { PORTB = 0x9e; } else if(v1==4) { PORTB = 0x5c; } else if(v1==5) { PORTB = 0xce; } else if(v1==6) { PORTB = 0xee; } else if(v1==7) { PORTB = 0x94; } else if(v1==8) { PORTB = 0xfe; } else if(v1==9) { PORTB = 0xde; } return v1; } Alleine durch ihre enorme Länge sollte einem diese Funktion schon sauer aufstossen und den Magen umdrehen. Dabei ist die Sache doch sehr einfach. Wenn wir uns mal die if-s ansehen, dann wird hier immer dieselbe Variable mit den Zahlen 0 bis 9 verglichen und je nachdem welche Zahl es war ein anderer Wert an PortB zugewiesen. Das muss doch auch eifnacher gehen. Was wir bräuchten ist ein Konstrukt, in das man mit dem Wert von v1 hineingeht (der ja nur die Zahlen von 0 bis 9 enthalten kann) und das dann den Wert liefert der an PortB ausgegeben werden soll. So was wie eine Tabelle, oder so. Langer Rede, kurzer Sinn: so ein Konstrukt gibt es. Das ist doch genau das was ein Array macht! v1 (also die Zahlen von 0 bis 9) dient als Index in das Array und im Array stehen dann die Werte: int segment_1() { static unsigned char Werte[] = { 0xf6, /* 0 */ 0x14, /* 1 */ 0xba, /* 2 */ 0x9e, /* 3 */ 0x5c, /* 4 */ 0xce, /* 5 */ 0xee, /* 6 */ 0x94, /* 7 */ 0xfe, /* 8 */ 0xde /* 9 */ }; PORTB = Werte[ v1 ]; return v1; } Wesentlich kürzer und auch übersichtlicher. Selbiges kann man natürlich auch mit den anderen beiden segment Funktionen machen.
Da fällt mir noch was auf: So wie du PINCx verwendest, funktioniert das nicht zb hier: do { variabler_zaehler(); berechnung(); segment_1(); segment_2(); segment_3(); } while(PINC2==0); PINC2 ist ein Makro. Wenn man das mal sucht, dann findet man #define PINC2 2 d.h. der Text PINC2 wird durch eine einfache 2 ersetzt. Macht der Präprozessor das, dann steht da while( 2 == 0 ); Nicht ganz das was du willst. Du willst: Die Schleife soll solange wiederholt werden, wie der Pin 2 vom Port C den Wert 0 hat. Jetzt verweise ich dich mal ans Tutorial. Im AVR-GCC-Tutorial auf dieser Seite (in der Link-Liste links in der unteren Hälfte zu finden) gibt es einen Abschnitt 'Allgemeiner Zugriff auf Register'. Den solltest du dir mal reinziehen.
Heißt das das in den headerdateien schon PINC2 auf 2 gesetzt worden ist ? oder muss ich das mittels #define definieren?
Das ist im Header File für dich schon definiert. Kommt über #include <avr/io.h> rein. Wenn es das nicht wäre, würde sich der Compiler beschweren. Du weisst schon: Alles was er nicht kennt ist ein Fehler.
so ich habe das jetzt soweit ich das verstanden habe verändert und compiliert ohne fehler und warnungen. Nur jetzt macht mein Programm rein garnichts. Er geht nichtmal mehr in die main . Woran kann das liegen? hier das programm: danke
> Er geht nichtmal mehr in die main
Wie muss ich das verstehen?
In die main() muss er auf jeden Fall reinkommen.
Dort ist Programmbeginn.
nur ne Kürzung, hat mit deinem Problem nichts zu tun, flash unsigned char Werte[10] = { 0xf6, /* 0 */ 0x14, /* 1 */ 0xba, /* 2 */ 0x9e, /* 3 */ 0x5c, /* 4 */ 0xce, /* 5 */ 0xee, /* 6 */ 0x94, /* 7 */ 0xfe, /* 8 */ 0xde /* 9 */ }; void drive_segmente (){ PORTB = Werte[ v1 ]; PORTD = Werte[ v2 ]; PORTA = Werte[ v3 ]; } flash muss bei deinem Compiler wahrscheinlich const heissen
zu karls frage: Ja ich teste im simulator. er macht nichts. Der pfeil der anzeigt wo das programm gerade ist endet bereits am ingang der main. int main() { - - - > hier und zu crazy_horse ich verstehe dein teil nicht.
Na ja, der Simulator wartet auf deine Befehle. Drück mal F10. Das führt den nächsten Befehl aus.
Die Kürzung die crazy_horse vorschlägt wolle ich auch noch machen. Aber alles zu seiner Zeit. Mach dir jetzt noch keine Gedanken drüber. Ich sprech dich dann durch wenn's soweit ist. Dein Pgm sollte eigentlich soweit funktionieren, dass kein grober Schnitzer mehr drinnen ist. Ob die Berechnungen an sich stimmen hab ich nicht kontrolliert, ich hab mich nur auf den C-Aspekt des Problems konzentriert. Im Simulator (klapp einfach mal das Degbug Menü herunter, da sind alle Befehle drinnen): F10 macht einen Schritt im Programm. Wenn der SChritt der Aufruf einer Funktion ist, dann wird die Funktion komplett still ausgeführt und wenn die Funktion ausgeführt ist meldet sich der Simulator wieder F11 so wie F10, nur werden Funktionen ebenfalls Schritt für Schritt ausgeführt. dann gibts da noch jede Menge anderes Zeugs. Man kann sich Variableninhalte anschauen, das Programm für sich alleine (also nicht schrittweise) ausführen, Breakpoints setzen (ein Breakpoint ist eine Stelle, wenn das Pgm darauf trifft wird die Ausführung unterbrochen und der Simulator meldet sich wieder) usw. Am Anfang wirst du wahrscheinlich hauptsächlich F10 und F11 benutzen, sowie Variablen anschauen. Mach dich mit den Möglichkeiten dieses Simulators (=Debugger; ein 'Bug' ist ein logischer Fehler im Programm, ein De-bug-ger ist daher ein Pgm, das einem hilft logische Fehler zu finden) vertraut, du wirst noch viel Zeit mit diesem Teil verbringen.
Du solltest auch gleich mal im linken Fenster den Reiter im unteren Abschnitt auf 'I/O View' stellen. Im Baum wählst du dann den letzten Punkt 'I/O AtMEGA16' (oder welchen Przessor du halt eingestellt hast) aus. Da tauchen dann alle simulierten Ports und sontige Einrichtungen deines Prozessors auf. Mach mal die ganzen 'PORTA' bis 'PORTD' auf. Wenn die DDRA = Zuweisungen ausgeführt werden, müsstest du sehen können wie sich der Zustand verändert.
ok mit F10 funktionierts ob er auch richtig rechnet hab ich noch nicht überprüft. Das kann auch noch warten. Auf jedenfall funkt es mit f10 macht auch alles richtig. Jetzt wäre es cool wenn ihr mir hilft bei den timern und countern. denn damit kenne ich mich nicht richtig aus und habe es nur mit hilfe des avr-gcc tutorials auf dieser seite gemacht. und vielen vielen dank an karl und crazy ich weiß eure hilfe echt zuschätzen , besonders dir karl. danke
Wobei kennst du dich nicht richtig aus? Das AVR-gcc-Tutorial ist in dem Punkt eigentlich recht umfangreich. Ich wuerde mal folgendes machen: Geh mal einen Schritt zurück, bildlich gesprochen, und vergiss dein eigentliches Problem. Fang ein 2.tes Projekt an, dass ich nur mit dem Timer beschäftigt. Also Timer konfiguerieren (Vorteiler einstellen, Timer einschalten) und im Simulator die Timer Komponente beobachten ob sie auch wirklich zaehlt. Selbiges wenn du den Timer als Counter betreibst. (Du kannst im Simulator auf die Port-Pins [die kleinen Rechtecke} klicken, der Simulator wertet das als Eingabe an den Port). So ein Testprojekt ist eine gute Sache. Denn es erlaubt dir dich nur auf einen bestimmten Teil zu konzentrieren, während alles andere aus dem richtigen Projekt erst mal aussen vor bleibt. Mit dem Testprojekt testet man ab, ob die Dinge wirklich so funktionieren wie man denkt. Hat man dann den Teil verstanden, ist es normalerweise nicht mehr schwer, das Gelernte im richtigen Projekt anzuwenden. Du betritts jetzt eine neue Welt. Teil dieser Welt ist auch, dass man experimentiert und selbst seine Schlussfolgerungen zieht.
so getestet er scheint zu zählen aber die prüfung funktioniert nicht. als die if anweisung ignoriert er denn er fängt auch an zuzählen wenn PINc1 nicht 1 ist. Woran kann das liegen?
Ich stimme Karl Heinz zu, Du solltest Dich erstmal mit den Grundlagen der C und MC-Programmierung beschäftigen. Also LED an, aus, blinken, mit Timer blinken, mit Interrupt blinken, Tasten abfragen, Tasten entprellen usw.. Eben wie jeder erfolgreiche Programmierer mal angefangen hat. Und auch mal anschauen, wie C-Programme aufgebaut sind, denn das hier ist totaler Schwachfug:
1 | int main() |
2 | {
|
3 | ...
|
4 | return impuls_fest; |
5 | return impuls_variable; |
6 | return v1; |
7 | return v2; |
8 | return v3; |
9 | }
|
1. Dein Compiler sollte dich warnen, daß die letzten 4 Zeilen unerreichbarer Code sind. Return macht genau das, was es bedeutet, es gibt nichts dahinter. 2. Wohin soll denn das Main zurückkehren, Du hast aufm MC doch kein Betriebssystem. Auf MCs enthält das Main ausnahmslos eine Endlosschleife, d.h. es läuft immer, bis man den Saft abschaltet. Nur um mal 2 der gröbsten Fouls zu nennen. Sich bequem alle Fouls von den anderen rausmachen zu lassen, ist nicht fein. Ich staune schon lange, daß sich noch Dumme dafür finden. Peter
> die if anweisung ignoriert er
Das tut er 100% nicht.
Anfaenger neigen gerne dazu, einem Computer sowas
wie Eigenleben zu unterstellen. Sei versichert,
dass es das nicht gibt. Die sog. Elektronengehirne
die sich gegen ihre Schöpfer auflehnen sind eine
Erfindung Hollywoods. Wenn eine Abfrage oder
sonst ein Programmteil nicht so funktioniert
wie du dir das vorstellst, dann liegt es
ausnahmslos immer daran, dass du als Programmierer
die Dinge falsch formuliert hast. Falsch heist
in diesem Falle: die Logik stimmt nicht. Dass
dein Programm den Regeln der Programmiersprache
entspricht, darum kümmert sich der Compiler. Aber
das ist nicht alles was ein Programm ausmacht; die
Logik dahinter muss auch stimmen. Und die ist Aufgabe
des Programmierers.
Ich frage nur ungern, aber mir fällt echt nichts ein. ICh bekomme den timer einfach nicht hin, da wollte ich fragen ob einer von euch ein test programm kennt oder irgendwas wo es gut beschrieben ist wie man die Timer/Counter benutzt. Also ich möchte das wenn ein bestimmter Pin auf high geht der timer anfängt zu zählen und wenn der selbe Pin das zweite mal auf high geht der timer ausgelesen wird. Wie im vorrigen beschrieben soll genau das mit nem Rad geschehen. sozusagen die zeit für einmal rum gemessen werden. Aber ich hab es bis jetzt noch nicht hinbekommen. Ich versuches schon die ganze zeit und werdes es auch weiter versuchen aber es wäre toll wenn mir jemand bei diesem Problem hilft. danke
>>Um nun also den Timer0 in Betrieb zu setzen und ihn mit einer Frequenz >>von 1/1024-tel des CPU-Taktes zählen zu lassen, schreiben wir die >>folgende Befehlszeile: >> >>TCCR0 |= (1<<CS00)|(1<<CS02); >> >>Der Zähler zählt nun aufwärts bis 255, um dann wieder bei 0 zu >>beginnen. Der aktuelle Zählerstand steht in TCNT0. Das steht im avr-gcc-tutorial aber ich habe das ausprobiert und frage mich nun , müsste den in TCNT0 laufend die PINS an und ausgehen? bei mir macht er das halt nicht.
Das könnte man so machen. Ein geübter Programmierer würde es zwar nicht so machen, sondern mit einem Input- Capture arbeiten, aber ich denke du solltest mal klein anfangen. #include <avr/io.h> #include <stdint.h> int main() { unsigned int Wert; // den Eingabeport konfigurieren DDRC = 0x00; // Port C alles auf Eingang PORTC = 0x01; // am Pin 0 den Pullup einschalten // warten bis Port C, Pin 0 auf 1 geht while( ( PINC & ( 1 << PINC0 ) ) == 0 ) ; // Vorteiler auf 1024, damit's nicht zu schnell geht // sobald der Vorteiler gesetzt ist, zaehlt der Timer // auch schon, wir wollen ihn ausserdem bei 0 anfangen lassen // zu zählen. Auf den kurzen Zeitverzug, der durch diese // Operationen entsteht, pfeifen wir mal kurzerhand. TCNT1 = 0; TCCR1B = ( 1 << CS12 ) | ( 1 << CS10 ); // jetzt warten wir, bis Port C, Pin 0 wieder zurueck noch 0 faellt // das muessen wir tun, da wir ja nicht wissen, wie lange die 1, // die weiter oben die while Schleife abgebrochen hat, noch // andauert. Und wir wollen ja schliesslich nicht, dass dieselbe // 1, die den ganzen Vorgang ausgelöst hat, ihn auch wieder // stoppt. Erst die nächste 1 soll das tun. while( ( PINC & ( 1 << PINC0 ) ) == 1 ) ; // gut. PinC ist wieder auf 0, d.h. wir koennen auf den naechsten 1 // Puls auf PinC-0 warten. while( ( PINC & ( 1 << PINC0 ) ) == 0 ) ; // der 2.-te Puls ist eingetroffen, den Timer auslesen Wert = TCNT1; // // den mC in eine Endlosschleife schicken, damit er keinen // Unsinn macht. while( 1 ) ; }
> müsste den in TCNT0 laufend die PINS an und ausgehen? > bei mir macht er das halt nicht. Langsam: das passiert schon. Nur hast du einen Vorteiler von 1024. s.h. der Prozessor macht 1024 Befehle (grob gesprochen), bevor der Timer um 1 weiterzählt. D.h. du musst im Simulator schon einige male eine Schleife durchlaufen, bevor du am Timer was siehst. Stell einfach mal den Vorteiler weiter runter, dann sollte es eigentlich schneller gehen.
er zeigt nur auf TCNT0 was an wenn ich auf pause drücke ist das normal?
Ja, das ist normal. Während der Simulator eigenständig läuft wird die Anzeige der Ports und sonstiges nicht nachgeführt. Mir ist klar, dass Atmel damit Simulationszeit einsparen möchte. Allerdings würde es den Simulator gehörig aufwerten, wenn es einen Simulations-Modus gäbe, in dem die Port-Anzeige bzw. was noch wichtiger wäre, die Input-Pins, auch dann nachgeführt bzw. ausgewertet werden, wenn das Pgm tatsächlich ausgeführt wird und nicht nur im Single-Step. Vielleicht macht Atmel das irgendwann. Zur Zeit jedenfalls nicht (oder ich hab den Schalter dafür einfach noch nicht gefunden).
Oh, ich vergass. Zur Not, kann man auch den 'Auto-Trace' benutzen. Das funktioniert allerdings nicht wirklich gut.
hab aber dein Programm probiert und bei dir funktioniert es das alles angezeigt wird. Aber durch dein Programm habe ich rausgefunden das ich richtig gedacht es aber falsch ausgeführt habe. Denn auf die idee mit dem wieder auf null schalten bin ich nicht gekommen. :) Also ich weiß echt nicht wie ich dir danken soll. Hab den ganzen tag gesucht um rauszufinden wie man den timer benutzt und nur weil ich dachte das ich ihn falsch benutze . Aso kurze frage wird der timer nur mit TCNT1 ausgelesen? Ich hatte gedacht man muss den low und high teil noch zusammen rechnen. danke nochmals
Ich habe leider nochmal ne frage. Und zwar hab ich das jetzt eingebunden (ich hoffe du hast nichts dagegen) und ich frag mich jetzt warum ich bei den funktionen zaehler und variabler_zaehler im Programm immer auf Pause drücken muss bevor es weiter geht? kann man das irgendwie unterbinden und muss das so sein?
Aber anscheinend Funktioniert das Ganze Programm jetzt. Denn er zählt und gibt alles aus. Sogar verschiedene zahlen :) Vielen dank für die grosse hilfe.
> Ich hatte gedacht man muss den low und high teil noch zusammen > rechnen. Das muss man auch. Aber das erledigt der Compiler für dich.
Ach sind das schöne Zeiten...als ich mit programmieren angefangen hab,hatte ich weder Internet noch Foren,das alles hat mich viele Nachmittage über Büchern und mit probieren gekostet. @Dennis: Dennoch,interessantes Projekt.Vielleicht etwas zu gross um eine Programmiersprache vernünftig zu lernen,aber interessant :) Viel Erfolg noch mit deinem Projekt.
Wow endlich mal einer der mich nicht gleich kritisiern. Ich will zwar tatsächlich c-lernen aber eigentlich nur in richtung software. Der Tacho ist ein schulprojekt. Aber du hast recht auch interesant. Das hat mich halt auf die idee gebracht mal den Butterfly zukaufen und so damit zu lernen. Danke und gute nacht
Wenn einer gute Bücher oder online-tutorials zum thema c kennt wäre es toll wenn er die hier posten würde. Danke
Mit dem Klassiker, 'K&R' kann man eigentlich nichts falsch machen. Programmieren in C. ANSI C (2. A.). Brian W. Kernighan, Dennis M. Ritchie http://www.amazon.de/exec/obidos/ASIN/3446154973/qid=1149471247/sr=8-1/ref=pd_ka_1/302-5852458-4580021
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.