Hallo, ich möchte meinen ersten mikrocontroller programmieren - leider ist es schon ein ARM7, allerdings in einer einfachen schaltung - sprich als erstes ziel hab ihc mir gesetzt, die serielle schnittstelle zum leben zu erwecken (damit ich mit im hyper terminal sachen ausgeben kann). Wie sieht die prinzipielle Struktur von so einem Programm aus - am anfang muss ich ein startup-file haben, in dem nach einem reset ständig alle ports etc. richtig geschalten werden und wird hier dann auch gleich die main routine aufgerufen? die main routine besitzt wahrscheinlich keinen return-wert, oder (weil dieser an niemanden zurückgegeben werden kann)? Wie spreche ich das externe Flash z.B. an? oder einzelne Ports? Muss ich hier PortB als variable definieren? Kennt jmd. gute seiten, in denen erklärt wird wie man am besten mit c oder besser c++ einen mikrocontroller programmiert bzw. welche strukturen man einhalten muss? Bernd
Bernd Schuster wrote: > ich möchte meinen ersten mikrocontroller programmieren - leider ist es > schon ein ARM7, allerdings in einer einfachen schaltung Naja, mit externen Flash drangepappt ist das keine einfache Schaltung mehr, da ist schon ne ganze Menge Holz auf dem Board. Den Schaltplan hast Du doch und weißt ihn zu lesen? > Wie sieht die prinzipielle Struktur von so einem Programm aus Du mußt auf nichts Rücksicht nehmen, alles ist erlaubt. Strukturier Dein Programm ganz so, wie es Dir gefällt. Es muß eine main-Funktion drin stehen, das ist alles. > - am > anfang muss ich ein startup-file haben, in dem nach einem reset ständig > alle ports etc. richtig geschalten werden Nö, das Startup kümmert sich nur um die Compilersachen (Stack, Interruptvertoren, Variablen initialisieren) Wenn Du Ports verwenden willst, mußt Du Dich selber drum kümmern. > und wird hier dann auch gleich > die main routine aufgerufen? die main routine besitzt wahrscheinlich > keinen return-wert, oder (weil dieser an niemanden zurückgegeben werden > kann)? Main darf nie enden (Endlos-Schleife). > Wie spreche ich das externe Flash z.B. an? oder einzelne Ports? ARM ist nicht gleich ARM, ohne genaue Typangabe kann keiner was dazu sagen. Die ARM von NXP haben z.B. das lustige Feature, daß es für die Ports getrennte Setz- und Löschregister gibt. Du mußt also den Schaltplan und das Datenblatt (Usermanual) Deines ARM zur Hand nehmen. Und da beginnt dann auch der Unterschied zu nem AVR-MC. Beim AVR ist die Beschreibung noch handlich, beim ARM wirst Du förmlich erschlagen (über tausend Seiten auf viele PDFs verteilt). Richtig lustig wirds aber erst, wenn Du Interrupts programmierst (wird ne ganze Weile dauern). > Muss ich > hier PortB als variable definieren? Ich kenne die ARM nur mit numerierten Ports (PORT0, Port1 usw.). Z.B. bei den ST-ARM werden die Ports über Pointer mit Offset angesprochen, sonst macht sich der ARM tot mit ständig neue Adressen laden. Sieht allerding nicht sehr leserlich aus. Ist ne Sache, wie der Compilerhersteller die Headerfiles angelegt hat. Peter
Hallo Bernd, hat es einen realistischen Grund, dass Du gleich mit so einem starken Controller anfangen willst? Wenn Du Dich uebernimmst kannst Du leicht das Interesse verlieren, gerade am Anfang. Michael
>Den Schaltplan hast Du doch und weißt ihn zu lesen? das Board hab ich zum Testen bekommen - also hardware-technisch dürfte es auf jeden fall funktionieren. >hat es einen realistischen Grund, dass Du gleich mit so einem starken >Controller anfangen willst? Wenn Du Dich uebernimmst kannst Du leicht >das Interesse verlieren, gerade am Anfang. mit einem Atmega8 hab ich schon so ganz kleine standard-sachen programiert in assembler (wie Leds an aus, Taster mit speziellen funktionien wie LEDs leuchten, und Interrupts - aber alles ganz basic (der Code war stets ca. ne seite auf monitor)... jetzt möchte ich mich mit diesem ARM7 Board vertraut machen (ganz langsam und step by step)... also zuerst einmal die LEDs ansprechen und RS232 ansprechen (das wäre super, wenn ich da schon mal dann auch einen rückkanal hätte, damit ich sehe was ich mache... deshalb suche ich auch nach praktischen beispielen, an denen ich lernen kann (also muss nicht auf den prozessor zugeschnitten sein, sondern mir nur zeigen wie ich was anspreche (blöd ausgedrückt - also z.B. wie abstrakt ich schon mit C oder C++ gegenüber Assembler sein darf bzw. wie ich die Register ansprechen muss (oder ob ich schon eine ebene darüber arbeite).. vielleicht hat jmd. einen bsp-code für mich, in dem nur vielleicht eine led an einem port aktiviert wird und auf ein paar register oder speicherstellen zugegriffen wird bzw. Werte gespeichert werden (gut dokumentiert)... ich glaub, dadurch könnte ich mir schon einiges ablesen, wie ich arbeiten muss... auch so der Aufbau - eine Main-Funktion und (in C), dann viele einzelne Funktionen, die nach einander oder bei bestimmten (Interrupts) Zuständen, aus Main aufgerufen werden --> dann muss ja alles wichtige gespeichert werden und nach der Interrupt-Methode wieder aus dem Speicher geholt werden... Bernd
Bernd Schuster wrote: >>Den Schaltplan hast Du doch und weißt ihn zu lesen? > > das Board hab ich zum Testen bekommen - also hardware-technisch dürfte > es auf jeden fall funktionieren. Um das Funktionieren geht es nicht, sondern darum, zu erkennen, wie und in welche Adreßbereiche der Flash und sonstige Peripherie gemappt ist, wie man in den Bootloader kommt usw. > jetzt möchte ich mich > mit diesem ARM7 Board vertraut machen (ganz langsam und step by step)... > also zuerst einmal die LEDs ansprechen und RS232 ansprechen Da dürfte die beste Quelle das Exampleverzeichnis Deiner Tools-Installation zu dem Board sein. Ich nehme mal an, das Board war nicht nackt, sondern ne CD dazu und vielleicht sogar ein JTAG-USB-Debugger. Es nimmt Dir auch keiner übel, wenn Du endlich mal damit rausrücken würdest um welchen ARM7 (Hersteller, Bezeichnung) es überhaupt geht. Solange das keiner weiß, können die Antworten nur abstrakt sein. Peter
anbei mal eine ARM Code den ich in der FH geschrieben hab...
1 | #include <stdio.h> |
2 | |
3 | /* define segments in terms of IO lines */
|
4 | #define SEG_A (1 << 10)
|
5 | #define SEG_B (1 << 11)
|
6 | #define SEG_C (1 << 12)
|
7 | #define SEG_D (1 << 13)
|
8 | #define SEG_E (1 << 14)
|
9 | #define SEG_G (1 << 15)
|
10 | #define SEG_F (1 << 16)
|
11 | |
12 | #define DISP_0 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F)
|
13 | #define DISP_1 (SEG_B | SEG_C)
|
14 | #define DISP_2 (SEG_A | SEG_B | SEG_G | SEG_E | SEG_D)
|
15 | #define DISP_3 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G)
|
16 | #define DISP_4 (SEG_B | SEG_C | SEG_F | SEG_G)
|
17 | #define DISP_5 (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G)
|
18 | #define DISP_6 (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
|
19 | #define DISP_7 (SEG_A | SEG_B | SEG_C)
|
20 | #define DISP_8 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
|
21 | #define DISP_9 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)
|
22 | #define DISP_A (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G)
|
23 | #define DISP_B (SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
|
24 | #define DISP_C (SEG_A | SEG_D | SEG_E | SEG_F)
|
25 | #define DISP_D (SEG_B | SEG_C | SEG_D | SEG_E | SEG_G)
|
26 | #define DISP_E (SEG_A | SEG_D | SEG_E | SEG_F | SEG_G)
|
27 | #define DISP_F (SEG_A | SEG_E | SEG_F | SEG_G)
|
28 | |
29 | /*Funktion zur Intialisierung der LEDs und Sieben-Segment
|
30 | Ãœbergabewerte: -keine-
|
31 | Rückgabewerte: -keine-*/
|
32 | void io_init(volatile unsigned int *); |
33 | |
34 | /*Funktion um die LEDs auf den übergebenen Wert setzen
|
35 | Ãœbergabewerte: char wert 0-0xF
|
36 | Rückgabewerte: -keine-*/
|
37 | void leds(char wert,volatile unsigned int *); |
38 | |
39 | /*Funktion zum Einlesen der Schalter
|
40 | Ãœbergabewerte: -keine-
|
41 | Rückgabewerte: char 0-0xF*/
|
42 | char schalter(volatile unsigned int *); |
43 | |
44 | /*Funktion zum Setzen der Siebensegmentanzeige
|
45 | Ãœbergabewerte: char wert 0-0x0F
|
46 | Rückgabewerte: -keine-*/
|
47 | void segment(char wert,volatile unsigned int *); |
48 | |
49 | |
50 | static const unsigned numeric_display[] = { DISP_0, DISP_1, DISP_2, DISP_3, DISP_4, DISP_5, DISP_6, |
51 | DISP_7, DISP_8, DISP_9, DISP_A, DISP_B, DISP_C, DISP_D, DISP_E, DISP_F }; |
52 | |
53 | int main (void) |
54 | {
|
55 | volatile unsigned int *z_iopmod,*z_iopdata; |
56 | char i; |
57 | |
58 | z_iopdata=(volatile unsigned *)(0x03FF0000 + 0x5008); |
59 | z_iopmod=(volatile unsigned *)(0x03FF0000 + 0x5000); |
60 | |
61 | io_init(z_iopmod); |
62 | /*10 mal Hallo Welt ! auf der Konsole ausgeben*/
|
63 | for(i=0;i<10;i++) |
64 | {
|
65 | printf("Hallo Welt !"); |
66 | fflush(stdout); |
67 | }
|
68 | /*Alle möglichen Kombinationen auf LED und 7-Segmentanzeige ausgeben*/
|
69 | for(i=0;i<16;i++) |
70 | {
|
71 | leds(i,z_iopdata); |
72 | segment(i,z_iopdata); |
73 | }
|
74 | /*SChalter einlesen und auf LED und 7-Segmentanzeige ausgeben*/
|
75 | while(1) |
76 | {
|
77 | i=schalter(z_iopdata); |
78 | leds(i,z_iopdata); |
79 | segment(i,z_iopdata); |
80 | |
81 | }
|
82 | |
83 | return 0; |
84 | }
|
85 | |
86 | void io_init(volatile unsigned int *z_iopmod) |
87 | {
|
88 | *z_iopmod = ((1<<4)|(1<<5)|(1<<6)|(1<<7)); |
89 | // wo LEDS dran als Output
|
90 | *z_iopmod |= ((1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<15)|(1<<16)); |
91 | // wo Sieben-Segment dran als Output
|
92 | }
|
93 | |
94 | void leds(char wert,volatile unsigned int *z_iopdata) |
95 | {
|
96 | wert &= (1|(1<<1)|(1<<2)|(1<<3)); |
97 | //schneide Wert passend zu
|
98 | *z_iopdata &=~ ((1<<4)|(1<<5)|(1<<6)|(1<<7)); |
99 | //lösche alten Wert
|
100 | *z_iopdata |= wert<<4; |
101 | //schreibe Wert von 0 bis 0xF auf LEDs
|
102 | }
|
103 | |
104 | char schalter(volatile unsigned int *z_iopdata) |
105 | {
|
106 | return (*z_iopdata & (1|(1<<1)|(1<<2)|(1<<3))); |
107 | //hole Wert der Schalter und maskiere den Rest
|
108 | }
|
109 | |
110 | void segment(char wert,volatile unsigned int *z_iopdata) |
111 | {
|
112 | wert &= (1|(1<<1)|(1<<2)|(1<<3)); |
113 | //schneide Wert passend zu
|
114 | *z_iopdata &=~ ((1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<15)|(1<<16)); |
115 | //lösche alten Wert
|
116 | *z_iopdata |= numeric_display[wert]; |
117 | //Passe wert an und suche dann passende Kombination aus dem Array numeric_display raus.
|
118 | }
|
printf landet hierbei über JTAG im Debugger(PC-Software) an ein 4 Pins hängen Schalter, an 4 LEDs, und dann noch ne 7-Segment Anzeige ist aber alles herstellerabhängig, jeder Hersteller kann die Adresswerte anders verteilen... Interrupt sind noch komplizierter, weil du alles selber schreiben musst bzw jeder Hersteller den IRQ Controller anders implementieren kann da ARM eine Lizenz zum bauen von Kernen verkauft und selber keine CPUs verkauft
>Um das Funktionieren geht es nicht, sondern darum, zu erkennen, wie und >in welche Adreßbereiche der Flash und sonstige Peripherie gemappt ist, >wie man in den Bootloader kommt usw. der Addressbereich steht im Datenblatt sehr gut aufgeschlüsselt drinnen. Benötigt man auch zu Beginn gleich einen Bootloader? Eigentlich wollte ich ganz ohne allem erst mal anfangen... der prozessor ist der LPC2212. Bei dem Board war eine CD mit dabei, mit Bootloader U-Boot und dazu Beispielprogrammen, aber ich möchte halt zuerst mal ohne Bootloader auskommen... @Gast vielen dank für dein beispiel, werde es mir morgn mal genau anschauen. Aber ein paar Fragen hab ich gleich beim Durchlesen gefunden. 1. was bedeutet denn fflush genau? 2. ist eine endlosschleife ohne abbruchkriterium gang und gebe? 3. das mit den ganzen defines muss ich mir noch mal anschauen genauso wie die Zeile z_iopdata=(volatile unsigned *)(0x03FF0000 + 0x5008); Im Prinzip geht es mir darum, zu erlernen wie man was programmiert bzw. wie man vorgeht. Bernd
zu 1. ist nur interessant wenn du eine Online Debugger hast... fflush leert den Buffer in den Klammern, sonst kann es bei printf passieren das die Ausgabe erst erscheint wenn der Buffer irgendwann mal voll ist (Standard C Fkt) zu 2. ja im µC Berich schon, weil was willst du den reinschreiben als Abbruch zu 3. z_io... ist ein zeiger im C, dessen Adresse wird auf den angegeben Wert gelegt dadurch kann man auf das Register zugreifen (die Register sind in diesem Fall memory mapped)
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.