hallo, ich besitze schon seit längerer zeit einen lernroboter, welcher in c programmiert wird. zur erklärung: der roboter besitzt einen atmel atmega 32 mikrocontroller. ich habe auch schon öfter mit ihm programmiert. nur ist es leider so, dass ich bisher hauptsächlich nur mit den makros programmiert habe und die eigentlichen grundlagen von c programmierung nicht wirklich gelernt habe. kann mir vielleicht mal jemand ein ganz einfaches und kurzes programm mit hilfreichen kommentaren posten, mit dem ich per eingangssignal einen ausgang ansteuern kann? also einen taster drücken, und damit eine LED leuchten lassen. die hardware ist bei mir komplett vorhanden. danke schon mal im voraus
Da must du schon ein wenig mehr erzählen damit hier einer was sagen kann.
Schau dir doch hier mal das GCC Tutorial an. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial Wenn allgemein C lernen willst empfielt es sich ein Buch zu Kaufen z.B. "C Programmieren von Anfang an" von Helmut Erlenkötter.
Grundsätzliche Frage: Kennst du Pin und Port schon? Falls Ja:
1 | //Unterprogramm für das Erzeugen eines Delays
|
2 | //Übergabeparameter ist die Wartezeit in ms
|
3 | |
4 | void sleep(unsigned int ms) |
5 | {
|
6 | unsigned int i,j; //Deklariere die Zählvariable |
7 | |
8 | for(i=0;i<ms;i++) |
9 | for(j=0;j<795;j++); //Eine Schlaufe die nichts tut (busywait) |
10 | }
|
11 | |
12 | int main(void) //Hauptprogramm |
13 | {
|
14 | DDRD |= (1<<3); //Setze Port D Pin 3 als Output (DDRD=Directionregister Port D) |
15 | |
16 | while(1) //Führe die Schlaufe für Ewig aus (solange 1 = 1 :) |
17 | {
|
18 | PORTD |= (1<<3); //Setze Port D Pin 3 auf 1 |
19 | sleep(1000); //Warte eine Sekunde |
20 | PORTD &= ~(1<<bit); //Setze Port D Pin 3 auf 0 |
21 | sleep(1000); //Warte eine Sekunde |
22 | }
|
23 | |
24 | }
|
Also falls du jetzt an Port D Pin 3 eine LED angeschlossen hast, blinkt die schön im Takt von einer Sekunde Falls du einen Pin als Input verwenden willst, dann musst du das DDRD-Register auf 0 setzen (input) und PIND als Port verwenden. Ansonsten kann ich dir das Manual empfehlen: http://www.mikrocontroller.net/articles/AVR-Tutorial Das Datenblatt für deinen Prozessor findest du unter: http://www.atmel.com/dyn/resources/prod_documents/doc2503.pdf Als Buch eignet sich auch "C als erste Programmiersprache" ISBN 978-3-8351-0222-4 Hat auch sehr schöne Syntax drin
Ich hab auch mit dem Buch "C als erste Programmiersprache" C gelernt, da die Autoren an meiner Hochschule Professoren sind. Ich finde aber dieses Buch zum erlernen der Programmiersprache nicht sooo toll. Zum nachschlagen wenn man die Grundlagen mal beherscht ist es allerdings super. Kann jetzt aber leider keinen Vorschlag machen für ein anderes Buch, hab mich da hauptsächlich mithilfe des Internets durchgewurschtelt. http://www.win-tux.de/index.htm ist zum Beispiel eine gute Seite...
danke schon mal für eure antworten. jetzt werd ich heute abend mal eure vorschläge ausprobieren. hilfreich sind sie auf jeden fall. p.s. das gcc- tutorial hab ich schon begonnen zu lesen, find es aber an einigen stellen nicht ganz so aufschlussreich. gruß
andi wrote: > p.s. das gcc- tutorial hab ich schon begonnen zu lesen, find es aber an > einigen stellen nicht ganz so aufschlussreich. Notiere dir die Stellen und deine Fragen/Unklarheiten. Wenn du in absehbarer Zeit nicht weiter kommst (manches braucht etwas Reife ;-), frage hier konkret nach.
so, das programm funktioniert jetzt. aber was bedeutet eigentlich das |= und das &=~ in diesem programm genau? gruß
So, jetzt hab ich mal ausprobiert mit einem taster eine led anzusteuern. Der taster ist am Register B am Pin 0 angeschlossen. Die ist am Register B an Pin 7 angeschlossen. hier mein programm: irgendwo liegt noch ein programmierfehler denn die led leuchtet nicht #include "RP6RobotBaseLib.h" void taster(void) {if (PINB & (1<<0)) //wenn PINB high (taster gedrückt) { PORTB |= (1<<7);} //PIN7 von PORTB auf high else {PORTB &=~ (1<<7);} //PIN7 von PORTB auf low } int main(void) //Hauptprogramm {initRobotBase(); DDRB&=~ (1<<0); //PIN0 von PORTB als Eingang DDRB |= (1<<7); //PIN7 von PORTB als Ausgang taster(); }
a &= b; heist soviel wie a = a & b; also ein bitweises und. das gleiche mit dem oder (|=) ~ => bitweises invertieren a &= ~b; löscht bei a die bits die bei b 1 sind...
So, jetzt hab ich mal ausprobiert mit einem taster eine led anzusteuern. Der taster ist am Register B am Pin 0 angeschlossen. Die ist am Register B an Pin 7 angeschlossen. hier mein programm: irgendwo liegt noch ein programmierfehler denn die led leuchtet nicht #include "RP6RobotBaseLib.h" void taster(void) {if (PINB & (1<<0)) //wenn PINB high (taster gedrückt) { PORTB |= (1<<7);} //PIN7 von PORTB auf high else {PORTB &=~ (1<<7);} //PIN7 von PORTB auf low } int main(void) //Hauptprogramm {initRobotBase(); DDRB&=~ (1<<0); //PIN0 von PORTB als Eingang DDRB |= (1<<7); //PIN7 von PORTB als Ausgang taster(); }
Hi, so sollte dein Code funzen. Allerdings sollten die Tasten noch entprellt werden. #include "RP6RobotBaseLib.h" void taster(void) { if (PINB & 0x01) //wenn PINB high (taster gedrückt) { PORTB |= (1<<PB7);} //PIN7 von PORTB auf high } else { PORTB &=~ (1<<PB7);} //PIN7 von PORTB auf low } } int main(void) //Hauptprogramm { initRobotBase(); DDRB = 0x80; //PIN0 von PORTB als Eingang //PIN7 von PORTB als Ausgang while(1) { taster(); } }
danke für deine hilfe, dein programm funktioniert. aber ich habe noch ein paar fragen? und zwar kann ich das PINB & 0x01 nicht einfacher ausgedrückt schreiben bzw. was bedeutet es? das gleiche gilt bei DDRB = 0x80; . was bedeutet das? bzw. kann man es vereinfachen? vielen dank schon mal im voraus
Hi, du solltest mal mit Google nach nem C-Tutorial suchen und das AVR-C-Tutorial auf dieser Seite durcharbeiten. PINB & 0x01 bedeutet, daß das Port Eingangsregister mit 0x01 "verundet" wird. Also werden alle Bits, bis auf das erste (PB0,was ja dein Eingang ist) auf Null gesetzt. DDRB = 0x80 setzt alle Bits des Data Direction Registers auf Null, bis auf das letzte, das setzt es auf eins, also Ausgang (PB7). Meine ganzen Zahlen sind im Hexadezimalformat geschrieben, vielleicht schauste dir das zusammen mit den Tutorialen auch gleich an. Gruß
aber ne möglichkeit das einfacher das eben erklärte zu verwenden gibt es nicht, oder?
p.s. ich mein auf die art, wie ich es oben vorher schon einmal versucht habe.
andi wrote: > hallo, ich besitze schon seit längerer zeit einen lernroboter, welcher > in c programmiert wird. zur erklärung: der roboter besitzt einen atmel > atmega 32 mikrocontroller. > ich habe auch schon öfter mit ihm programmiert. > > nur ist es leider so, dass ich bisher hauptsächlich nur mit den makros > programmiert habe und die eigentlichen grundlagen von c programmierung > nicht wirklich gelernt habe. Hallo Andi, leider kenne ich weder Deine Hardware noch die Implementierung der Ansteuerung in deinen Makros und C-Bibliotheken. Daher kann dein Anliegen auch kaum sinnvoll bearbeitet werden. Die Sprache C an sich stellt dir nur ein syntaktisch standardisiertes Regelwerk zur Programmierung zur Verfügung. Der Compiler prüft Syntax (und in gewissen Grenzen die Semantik), wie genau das Endergebnis implementiert ist kannst Du jedoch nur durch Studium der Quelltexte der von Dir verwendeten Bibliotheken herausfinden - oder, falls du Assembler kannst, durch Disassemblierung. Ich verstehe Dein Problem und glaube zu wissen worauf Du hinauswillst. Im Grunde läuft es doch daruf hinaus, daß du die Funktionsweise deiner C-Funktionen und -Makros verstehen willst. Ohne zuerst jedoch die Sprache zu verstehen wird es ein nichttriviales Problem. Also lerne erst C (dazu gibt es verschiedene Ansätze) und versuche dann die Arbeitsweise der von Dir genutzten Funktionen zu verstehen. > kann mir vielleicht mal jemand ein ganz einfaches und kurzes programm > mit hilfreichen kommentaren posten, mit dem ich per eingangssignal einen > ausgang ansteuern kann? also einen taster drücken, und damit eine LED > leuchten lassen. die hardware ist bei mir komplett vorhanden.
1 | #include <roboter/iosubsys.h> // Headerdatei für Roboter einbinden |
2 | |
3 | int main(void) // Hauptroutinen-Einsprungspunkt |
4 | {
|
5 | while (true) // Endlosschleife |
6 | {
|
7 | if ( inputpoller(IOINPUTPIN01,HIGH) == true) // Taster an Pin 1 abfragen |
8 | output(IOOUTPUTPIN03,HIGH); // LED an Pin 3 rinschalten |
9 | }
|
10 | return 0; // Korrekte Semantik beim Aufruf von main() |
11 | }
|
> danke schon mal im voraus
Keine Ursache und viel Erfolg.
PS: Die Verwendung der üblichen Groß- und Kleinschreibung erhöht die
Chance auf sinnvolle Antworten.
Wenn Pins angesteuert werden, wird hier oft das Hexadezimalsytem verwendet. Es ist dafür einfach praktischer. Zum Umrechnen auf Binär und Dezimal kannst du den Normalen Rechner deines Betriebssystems verwenden. Dazu musst du ihn auf wissenschaftlich schalten. Hier mal eine kurze Tabelle: Pin0 = 00000001 = 0x01 = 1 Pin1 = 00000010 = 0x02 = 2 Pin2 = 00000100 = 0x04 = 4 Pin3 = 00001000 = 0x08 = 8 Pin4 = 00010000 = 0x10 = 16 Pin5 = 00100000 = 0x20 = 32 Pin6 = 01000000 = 0x40 = 64 Pin7 = 10000000 = 0x80 = 128 Insgesamt 8 Pins gibt 1 Port. Bei manchen µC sind nicht alle Pins vorhanden. Um mehrere Pins gleichzeitig zu schalten, musst du am besten per Taschenrechner die einzelnen Pinzahlen zusammenrechnen. Z.B. 0x55 = 01010101 = Pin6, Pin4, Pin 2, Pin 0 auf eine High oder Ausgang. Beim Binär ist links der höchste Pin(7) und rechts der kleinste (0).
danke. genau das wollte ich wissen. weil mir halt auffällt das die ausgänge auf sehr viel verschiedene arten angesteuert werden können, wie man auch in diesem thread sieht. gruß
wie kommt es dann, dass in fubu1000 geposteten programm er mit DDRB = 0x80; //PIN0 von PORTB als Eingang //PIN7 von PORTB als Ausgang dann diese funktion ausführen kann? nach oberer erklärung dürfte er damit ja nur pin 7 ansprechen.
andi wrote: > wie kommt es dann, dass in fubu1000 geposteten programm er mit > > DDRB = 0x80; //PIN0 von PORTB als Eingang > //PIN7 von PORTB als Ausgang > > dann diese funktion ausführen kann? > nach oberer erklärung dürfte er damit ja nur pin 7 ansprechen. Meinst du dieses Programm?
1 | #include "RP6RobotBaseLib.h" |
2 | |
3 | void taster(void) |
4 | {
|
5 | if (PINB & 0x01) //wenn PINB high (taster gedrückt) |
6 | PORTB |= (1<<PB7); //PIN7 von PORTB auf high |
7 | else
|
8 | PORTB &= ~(1<<PB7); //PIN7 von PORTB auf low |
9 | }
|
10 | |
11 | int main(void) //Hauptprogramm |
12 | {
|
13 | initRobotBase(); |
14 | DDRB = 0x80; //PIN0 von PORTB als Eingang |
15 | //PIN7 von PORTB als Ausgang
|
16 | while(1) |
17 | taster(); |
18 | }
|
Bei deiner Frage wird das Datenrichtungsregister DDRB gesetzt und anders geschrieben sieht das so aus (PB7 ist als 7 definiert): DDRB = 0 + (1<<PB7); // == 0x80 == 0b10000000 Alle 0 Bits im Register stellen den betreffenden Portpin auf Ausgang, alle 1 Bits auf Eingang. Aufpassen muss man, wenn man statt = ein |= oder ein &= oder ein ^= im Code sieht. Denn DDRB |= (1<<PB7); // == 0x80 == 0b10000000 entspricht dann DDRB = DDRB | (1<<PB7); // == 0x80 == 0b10000000 Dder Eingang wird dann tatsächlich erst in dieser Zeile abgefragt: if (PINB & 0x01) //wenn PINB high (taster gedrückt) Anders geschrieben so (PB0 ist als 0 definiert) if (PINB & (1<<PB0)) //wenn PINB high (taster gedrückt) Je nach Ergebnis der Abfrage des Eingangs wird der Ausgang in diesen Zeilen verändert: PORTB |= (1<<PB7); //PIN7 von PORTB auf high PORTB &= ~(1<<PB7); //PIN7 von PORTB auf low Anders geschrieben so (PB7 ist als 7 definiert): PORTB |= 0x80; //PIN7 von PORTB auf high PORTB &= 0x7F; //PIN7 von PORTB auf low Anders geschrieben so PORTB = PORTB | 0x80; //PIN7 von PORTB auf high PORTB = PORTB & 0x7F; //PIN7 von PORTB auf low IMHO ist die Schreibweise mit (1<<irgendwas) am lesbarsten und am sichersten, wenn sich die symbolischen Namen irgendwas ändern.
danke stefan, deine erklärung ist wirklich mehr als hilfreich. jetzt hab ich mal einen guten überblick über die verschiedenen möglichkeiten. kann ich das auch so machen? PORTB |= 0x80; //PIN7 von PORTB auf high PORTB &=~ 0x80; //PIN7 von PORTB auf low gruß
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.