Meiner Meinung nach fehlt das Init
Hallo,
mit diesem Code versuche ich erst die linke BackLED einzuschalten, und eine Sekunde später die rechte dazu. Die linke geht zwar an, aber dann passiert nichts mehr.Code:#include "asuro.h" main() { //linke BackLED an DDRC=(1<<PC1); PORTC=(1<<PC1); Msleep(1000); //rechte BackLED an DDRC=(1<<PC0); PORTC=(1<<PC0); }
Kann mir jemand sagen, was falsch ist?
Gruss
M.
Meiner Meinung nach fehlt das Init
Hallo
Die Funktion main() muss immer mit einer Endlosschleife enden! Sie wird eigentlich wie jede andere Funktion aufgerufen, allerdings ist nirgends definiert, wohin das Programm springen soll, wenn main() beendet ist.
Ausserdem sollte sie die Form
int main(void)
{
// hier kommt das eigentliche Programm rein
while(1);
return(1);
}
haben, sonst motzt der Compiler. int für den Rückgabewert, deshalb steht da auch immer return(1), und void für kein Parameter wird benötigt.
Ihr seid immer soooo schnell. asuro.h und Init(); benötigt man nicht, wenn man solche Programm schreibt, es genügt
#include <avr/io.h>
#include <avr/interrupt.h>
für die #defines und die Interrupts. Hab ich doch selbst erst gestern kapiert und erklärt:
https://www.roboternetz.de/phpBB2/vi...=295604#295604
Ohne asuro.h gibt's natürlich auch kein Msleep(), deshalb muss man mit Verzögerungsschleifen arbeiten:
unsigned int i,j;
for (i=0; i < 20; i++) { for (j=0; j < 65535; j++); }
20 in der i-Schleife sind ungefähr 'ne Sekunde Verzögerung.
Gruss
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Nur pass auf, daß Dir der Kompiler sowas nicht wegoptimiert...unsigned int i,j;
for (i=0; i < 20; i++) { for (j=0; j < 65535; j++); }
nur besser ist sowas:
Gruß SebastianCode:#define F_CPU 8000000 #include <util/delay.h> ... ... uint8_t a; for (a=0;a<100;a++) _delay_ms(10);
Linus TorvaldSoftware is like s e x: its better when its free.
Aha, klasse. Bei optimierung=0 scheint er den Code drin zu lassen, aber mit delay.h ist es eleganter.
Ist natürlich fraglich, in wieweit man sich fertiger Funktionen bedient, denn irgendwann wird man dann wieder bei der asuro.h landen. Ich versuche doch jetzt mir das Schritt für Schritt zu erarbeiten, dann kann ich doch nicht schon bei der dritten Hürde auf vorgefertigtes zurückgreifen.
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Ja gut,
delay.h ist ein Bestandteil von avr-gcc und beinhaltet noch ein paar "Zeitvernichtungs" Routinen.
Die sind sehr gut geschrieben(schau Dir mal delay.h an)es ist eigentlich Assembler pur, nur pass bloß mit -O0 auf, die Optimierung ganz abzuschalten ist keine gute Idee, vor allem in Verbundung mit _delay* Funktionen.
Es werden Fließkomaoperationen ausgeführt, die mit -Os komplett zu Kompilierzeit aufgelöst werden, bei -O0 bleiben sie drin, und wie gut der M8 damit umgehen kann weißt Du sicherlich selbst
Das ist sehr gut, es macht Spaß sowas zu lesen, wo ich noch mit dem Asuro gespielt hatte, hab ich den in Assembler programmiert, das hat auch viel Spaß gemacht, und vor allem, ich habe sehr viel über die AVR's gelernt !ch versuche doch jetzt mir das Schritt für Schritt zu erarbeiten, dann kann ich doch nicht schon bei der dritten Hürde auf vorgefertigtes zurückgreifen.
Achja, noch was, wenn Du willst, daß Deine "sinnlosen" Schleifen nicht wegoptimiert werden, mußt Du die Variablen volatile deklarieren, aber das weißt Du sicherlich auch schon...
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Hallo,
danke für eure Mühe,
habe die asuro.h drin weil ich sie dann sowieso brauche,
Init ist jetzt auch drin...
Jetzt habe ich erstmal versucht die BackLEDs nur auszuschalten
die linke LED geht an, allerdings nicht ganz hell.Code:#include "asuro.h" int main(void) { Init(); StatusLED(OFF); DDRC=(1<<PC1); DDRC=(1<<PC0); //beide BackLED aus ?????????? linke ist an!!!!!!!! PORTC=(0<<PC0); PORTC=(0<<PC1); while (1); return 0; }
Mit BackLED(OFF,OFF) sind beide LEDs wirklich ganz aus
???
Gruss
M.
Nein,nein, überleg mal
In der ersten Zeile setzt Du PC1 auf Ausgang, Dein DDRC sieht so aus 00000010DDRC=(1<<PC1);
DDRC=(1<<PC0);
In der Zweiten Zeile setzt Du PC0 auf Ausgang und überschreibst Du das was Du zuvor gesetzt hast Dein DDRC sieht jetzt so aus 00000001
Die Lösung:
oderCode:DDRC=(1<<PC1)|(1<<PC0);
Mit der Portzuweisung geht es genauso.Code:DDRC=(1<<PC1); DDRC |=(1<<PC0);
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Hallo
Ich hab' mir den asuro ins Haus geholt, weil ich endlich mal in c einsteigen wollte. In Assembler ist halt alles was anspruchsvoller ist etwas zäh, da ist c als "Hochsprache" schon deutlich mächtiger. Außerdem kann man mit c auch recht nahe an der Maschine bleiben, wenn man weis, wie es geht. Mit Hilfe der tollen Tutorials auf deiner HP habe ich nun endlich auch die Timergeschichte kapiert und damit auch die nächste Hürde genommen:als ich noch mit dem Asuro gespielt hatte, hab ich den in Assembler programmiert
Das lief dann übrigens auf Anhieb, obwohl ich mir nicht sicher bin, ob das Laden eines 16Bit-Wertes nach TCNT1 legitim ist. Meine Optimierung steht übrigens auf "size" habe ich jetzt gesehen.Code:#include <avr/io.h> #include <avr/interrupt.h> unsigned int timer_startwert=65536-7812; // 8MHz/1024=7812,5 int main(void) { DDRB=0; // nicht benoetigte Ports auf Eingang setzen DDRC=0; DDRD=(1 << PD2); //rote StatusLED haengt an PD2(= Port D, Bit2) PORTD=0; // alles aus /* Es folgt eine Verzögerung von ca. 1 Sekunde */ TCNT1=timer_startwert; // 16-Bit auf einmal laden? TCCR1B |= 0b00000101; // Prescaller Timer1 auf 1024 setzen while(!(TIFR & 0b00000100)); //Warten bis Überlauf Timer1 TCCR1B &= ~0b00000101; // Prescaller löschen bedeutet Timer1 stoppen TIFR |= 0b00000100; // Flag setzen bedeutet Flag wieder löschen while(1) PORTD=((PINC & (1<<PC4)) >> 2); // eine Taste schaltet StatusLED aus return(0); }
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Hallo Sebastian,Zitat von izaseba
vielleicht sollte ich die ganze Sache nochmal vertagen - ich weiß eigentlich gar nicht was ein DDRC ist. Die Ports habe ich im Schaltplan gefunden, und da jede LED einen eigenen hat, habe ich gedacht, ich könnte sie unabhängig voneinander ein- und auschalten.
Folgendes habe ich noch probiert
aber vielleicht geht das ja gar nicht??????????Code:#include "asuro.h" int main(void) { Init(); StatusLED(OFF); DDRC=(1<<PC1)|(1<<PC0); //beide BackLED an PORTC=(1<<PC1); PORTC|=(1<<PC0); Msleep(3000); //beide BackLED aus PORTC=(0<<PC1); PORTC|=(0<<PC0); Msleep(3000); //linke BackLED an PORTC=(1<<PC1); Msleep(3000); //linke BackLED aus PORTC=(0<<PC1); Msleep(3000); //rechte BackLED an PORTC=(1<<PC0); Msleep(3000); // an dieser Stelle soll die linke BackLED angehen, ohne die rechte zu beeinflussen // jetzt geht die rechte aber aus // ??????????????????????? PORTC=(1<<PC1); Msleep(3000); while (1); return 0; }
Gruss
M.
Lesezeichen