Forum: Mikrocontroller und Digitale Elektronik µController programmierung C lernen.


von MP (Gast)


Lesenswert?

Hallo leute...
mir ist aufgefallen dass das ein sehr aktuelles forum ist und da wollte 
ich doch glatt mein problem darlegen...

ich muss es hinbekommen für meine 5. prüfungskomponente (jugend forscht) 
einen µController mit C zu programmieren..

toll ich habe keine ahnung von C und würde gern wissen ob mir irgendwer 
sagen kann mit welcher anleitung  crashkurs  usw. ich am schnellsten 
und effektivsten C lernen kann!

eventuell wäre es schön wenn man mir ein einsteigerprogramm / -compiler 
nennen kann...

das wäre alles echt super
vielen dank schonmal leute

MfG
Max

von Dilligent (Gast)


Lesenswert?

Unter Windows darf ich DevCpp wärmstens empfehlen um C zu lernen, 
einfach mal googlen.
Als Tutorial Seite ist http://www.cprogramming.com/ sehr sehr gut.
Einfach mal etwas mit rumexperimentieren, so schwierig wie sein ruf ist 
C lange nicht.

von Carlos (Gast)


Lesenswert?

Hallo Max,
wenn der µController egal ist, nimm einen 8051er-Chip: 
Experimentalboards gibts genug davon und den C-Compiler von Wickenhäuser 
(www.wickenhaeuser.de). Mit der kostenlosen Demo-Version kannst Du schon 
richtig gute Programme schreiben.
Bei Bedarf kannst Du eine kleine Einführung in C für 8051er von mir 
bekommen.

Viel Spaß
Carlos

von Daniel (Gast)


Lesenswert?

Naja sinnvoll wäre es, wenn du das ganze direkt mit dem compiler, den du 
für dein projekt bauchst lernen könntest, von daher wäre der erste 
schritt einen controller auszuwählen...
beherscht du andere programmiersprachen mehr oder weniger gut?

von Commtel (Gast)


Lesenswert?

@  Carlos

Ich würd gern dein kurs belegen
in verbindung mit dem 8051 wenn es geht

c.u
Commtel

von Robert S. (razer) Benutzerseite


Lesenswert?

HIer ist ei C Tutorial für AVRs und C: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

C Programmierkenntnisse werden aber vorausgesetzt.

Ein C µC ist trotzdem nicht gut geeignet um C zu lernen, da 
Debugausgaben schwer möglich sind als am PC....

Gruß Robert

von Commtel (Gast)


Lesenswert?

@ Robert

ja das ist schon richtig
aber ich versuch jetzt mal ein beispiel das ich am wochenende getest 
habe

ich hab jetzt nicht die genauen unterlagen hier
aber z.b

Setzte vom Port 1 Pin 2 des 8051 auf High
in Assembler kein problem für mich zumindest beim 8051

Setb P1.2

klar da fehlt jetzt noch die zuweisung sprich

Port1 equ 0x90
P1.0 bit 0x90
P1.1 bit 0x91
P1.2 bit 0x92
usw

und nu das ganze in C ???

von Robert S. (razer) Benutzerseite


Lesenswert?

Ich weiß nicht wie die Register 8051 heißen.
Aber prinzipiell:

reg |= (1 << bit)

So geht das in C.

zB

PORTD |= (1 << 5);   //setzt das 6. Bit in PortD.

Aber wie die Register genau heißen, weiß ich nicht...

Gruß Robert

von Commtel (Gast)


Lesenswert?

@ robert

ich muß heute abend wenn ich zeit habe das noch mal raus suchen
wie ich das beim keil in c geschrieben hatte.
Was mich babei wunderte war auch wenn ich z.b ein port anspreche
das diese anweisung z.b setze port A auf 0x5c als subroutine nach dem 
compilern ausgegeben wurde.

Ich werd das ganze nochmals genauer hier posten nur leider bin ich jetzt 
auf der arbeit

von Carlos (Gast)


Lesenswert?

@Commtel:
Das Ansprechen eines Port-Pins in C läuft sehr ähnlich zu dem in 
Assembler ab (Code für µC/51er-C-Compiler):
Du definierst den Port-Pin mit seiner zugehörigen Bit-Adresse:

  unsigned char bit P1_5 @ 0x95;  // Port-Pin P1.5 hat die Bit-Adresse 
95h

Und dann später im Programm selber:

  P1_5 = 1;   // Setzen auf HIGH und
  P1_5 = 0;   // Setzen auf Low.

Das war´s schon.

Gruß Carlos.

von Karl H. (kbuchegg)


Lesenswert?

Der Vollständigkeit halber sei aber noch gesagt, dass es
sich hierbei um kein Standard-C Konstrukt handelt. Die Welt
von C endet bei Bytes (was auch immer ein Byte sein mag,
ob das jetzt 8 Bit, 9 Bit, 16 Bit oder sonstwas größer/gleich
8 ist.) Was kleineres als 1 Byte gibt es in C ganz einfach nicht.

Manche Compiler Hersteller haben daher Erweiterungen eingebaut
um Zugriff auf einzelne Bits zu ermöglichen.

von commtel (Gast)


Lesenswert?

so jetzt mal an alle
ich hab folgendes geschrieben
**********************************************
sfr P1    = 0x90;
sbit TestPin1 = P1^5;

void main(void)

 {
  TestPin1 = 1;
 }
// wichtig an alle anfänger ist auch striche,kommas geschrieben wird
// sonst geht gar nix muste ich festellen
*************************************************
so ja heisen das von port1 pin5 gesetzt wird
also könnte man erwarten das in assembler

 SETB 1.5 sprich D2 95

rauskommen sollte oder nicht

tja denkste

C:0x0000    020003   LJMP     C:0003
C:0x0003    787F     MOV      R0,#0x7F
C:0x0005    E4       CLR      A
C:0x0006    F6       MOV      @R0,A
C:0x0007    D8FD     DJNZ     R0,C:0006
C:0x0009    758107   MOV      SP(0x81),#0x07
C:0x000C    02000F   LJMP     main(C:000F)
     4: void main(void)
     5:
     6:  {
     7:   TestPin1 = 1;
C:0x000F    D295     SETB     TestPin1(0x90.5)<-- das wollt ich NUR 
haben
     8:  }
C:0x0011    22       RET <--warum ist daraus eine subroutine geworden?

und wenn es eine subroutine wo steht denn was von LCALL?
Wäre das dann nicht einfacher und kürzer?

von Thomas B. (detritus)


Lesenswert?

Was da vor dem main abläuft, ist eine Initialisierungsroutine. Erst 
werden die Interrupthandler übersprungen, dann das RAM gelöscht und 
schliesslich wechselt der Controller in das main.
Das muss also nicht mit einem lcall aufgerufen werden, sondern wird bei 
jedem Reset des Controllers genau einmal durchlaufen. (Programmcounter 
steht nach dem Reset auf 0).
Dass der Compiler auch aus dem main eine Subroutine baut, macht hier 
nicht so schrecklich viel Sinn, da die main-Routine ja so nicht mal 
aufgerufen, sondern nur angesprungen wird. Das liegt einfach an der 
Logik von C.

von commtel (Gast)


Lesenswert?

Die Logik von C ist mir nicht so sympatisch aber nun ja
Was mienst du mit Interrupthandler?
die interruptadressen

0x0003 externer interrupt 0
0x000B Timer 0
?

ich werd mal versuchen eine endlos schleife einzubauen nach
 {
  TestPin1 = 1;
 }

damit das ganze ein wenig sinn ergibt.

von Thomas B. (detritus)


Lesenswert?

Ich meine damit die Adressen kurz nach dem Anfang des Flash, an die der 
µC beim Auftreten des jeweiligen Interrupts springt. Also schon das, was 
du grad geschrieben hast.

Was stört dich denn an der C-Logik? Der überflüssige ret?
Das mit der Endlosschleife ist aber eh ne gute Idee, weil die main auf 
µC NIEMALS beendet werden darf (der ret am Ende der main darf niemals 
ausgeführt werden).
Es ist eh fraglich, wo er dann im obigen Programm hinspringen sollte, 
wenn er ja nichtmal ne Rücksprungadresse auf dem Stack liegen hat...

von commtel (Gast)


Lesenswert?

würd sagen irrt sonst wo rum G

so habs geändert

sfr P1    = 0x90;
sbit TestPin1 = P1^5;

void main(void)

 {
  TestPin1 = 1;
  while(1);
 }

C:0x0000    020003   LJMP     C:0003
C:0x0003    787F     MOV      R0,#0x7F
C:0x0005    E4       CLR      A
C:0x0006    F6       MOV      @R0,A
C:0x0007    D8FD     DJNZ     R0,C:0006
C:0x0009    758107   MOV      SP(0x81),#0x07
C:0x000C    02000F   LJMP     main(C:000F)
     4: void main(void)
     5:
     6:  {
     7:   TestPin1 = 1;
C:0x000F    D295     SETB     TestPin1(0x90.5)
     8:   while(1);
C:0x0011    80FE     SJMP     C:0011

mit welchen befehl kann ich 0x0003 resavieren?

ich find gerde nirgends wo man bei keil ein hex file dazu ausgeben 
lassen kann um es im eprom zu brennen.
Bei assembler geht das oder vileicht bin auch gerade nur zu müde.

von Thomas B. (detritus)


Lesenswert?

Das hex-File kriegst du, wenn du unter Project->Options for 
Target->Registerkarte Output den Haken bei "Create HEX File" setzt. Das 
File liegt dann in deinem Projektverzeichnis.

Das HEX kommt aber ins Flash und nicht ins EEPROM, denn aus dem EEPROM 
kann der Controller keinen Code ausführen. Das EEPROM ist vor allem dazu 
da, nichtflüchtig Daten abzulegen oder grosse Mengen an Konstanten zu 
speichern.

>mit welchen befehl kann ich 0x0003 resavieren?

reservieren? für was denn?

von commtel (Gast)


Lesenswert?

sorry hatte mich unklar gestern abend ausgedrückt
Ich meinte wenn ich im flash die adresse 0x0003 im voraus resavieren 
will
oder z.b das meine main erst ab 0x0050 abgelegt wird.
Dafür muß es doch auch ein Befehl geben.

Ich hab noch ein 80c32 daher das mit eeprom ist natürlich ein Eprom 
(ein27c64)
War doch etwas spät gestern ;-)

von Patrick (Gast)


Lesenswert?

Der ursprüngliche Thread-Ersteller kann wahrscheinlich mit den Posts 
hier nichts anfangen, deshalb hier ein Link für MP:

http://www.galileocomputing.de/openbook/c_von_a_bis_z/

Das ist ein Online-Openbook für C-Programmierung. Vielleicht schaust Du 
Dir das mal an.

von Thomas B. (detritus)


Lesenswert?

commtel wrote:
> sorry hatte mich unklar gestern abend ausgedrückt
> Ich meinte wenn ich im flash die adresse 0x0003 im voraus resavieren
> will
> oder z.b das meine main erst ab 0x0050 abgelegt wird.
> Dafür muß es doch auch ein Befehl geben.
>

0x0003 ist erstmal reserviert für den EXINT0, da du diesen nicht 
verwendest, kann der Compiler der Platz dafür für seine 
Initialisierungs-Routine und die main verwenden.

Man kann es dem Linker irgendwie sagen, dass er nen Adressoffset 
draufhauen soll(der Keil macht ja in der Demoversion immer feste 2k), 
aber frag mich nicht wie. Habs noch nie gebraucht ;)
Was willst du damit denn erreichen?


> Ich hab noch ein 80c32 daher das mit eeprom ist natürlich ein Eprom
> (ein27c64)
> War doch etwas spät gestern ;-)


Ahso, dann ist das natürlich was anderes. Bin jetzt von einem moderneren 
Controller ausgegangen.

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
Noch kein Account? Hier anmelden.