mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik anfänger frage zu mikrocontroller programmierung


Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Skua C:\> (skua)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da must du schon ein wenig mehr erzählen damit hier einer was sagen 
kann.

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Christoph Mauchle (fakulatus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grundsätzliche Frage: Kennst du Pin und Port schon?
Falls Ja:
//Unterprogramm für das Erzeugen eines Delays
//Übergabeparameter ist die Wartezeit in ms

void sleep(unsigned int ms)
{
  unsigned int i,j; //Deklariere die Zählvariable

  for(i=0;i<ms;i++)
    for(j=0;j<795;j++);  //Eine Schlaufe die nichts tut (busywait)
}

int main(void) //Hauptprogramm
{
  DDRD |= (1<<3);  //Setze Port D Pin 3 als Output (DDRD=Directionregister Port D)
  
  while(1) //Führe die Schlaufe für Ewig aus (solange 1 = 1 :)
  {
    PORTD |= (1<<3); //Setze Port D Pin 3 auf 1
    sleep(1000); //Warte eine Sekunde
    PORTD &= ~(1<<bit); //Setze Port D Pin 3 auf 0
    sleep(1000); //Warte eine Sekunde
  }
   
}

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/...

Als Buch eignet sich auch "C als erste Programmiersprache" ISBN 
978-3-8351-0222-4
Hat auch sehr schöne Syntax drin

Autor: Skua C:\> (skua)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Schlaufe" find ich Klasse!

Autor: hust (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so, das programm funktioniert jetzt. aber was bedeutet eigentlich das |= 
und das &=~ in diesem programm genau?

gruß

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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();
}

Autor: hust (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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();
}

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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();
  }
}

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aber ne möglichkeit das einfacher das eben erklärte zu verwenden gibt es 
nicht, oder?

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
p.s. ich mein auf die art, wie ich es oben vorher schon einmal versucht 
habe.

Autor: Иван S. (ivan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

#include <roboter/iosubsys.h> // Headerdatei für Roboter einbinden

int main(void)                // Hauptroutinen-Einsprungspunkt
{
 while (true)                 // Endlosschleife
 {
  if ( inputpoller(IOINPUTPIN01,HIGH) == true) // Taster an Pin 1 abfragen
       output(IOOUTPUTPIN03,HIGH);             // LED an Pin 3 rinschalten
 }
return 0;                     // Korrekte Semantik beim Aufruf von main()
}


> 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.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

#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();
}

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.

Autor: andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst du.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.