Hallo, als Dateianhang habe ich ein Mini-C-Programm eingefügt, das eine LED blinken lässt. Arbeite mit dem Infineon XC167CI-Board von Phytec und Keil µVision 2 als Entwicklungsumgebung. In C bin ich inzwischen ganz fit, und hab schon Mächtigere Dinge programmiert ;) Allerdings brauche ich exemplarisch noch Assembler-Code, bekomme aber nichts Kompilierbares zustande. FRAGE: Kann mir jemand eine Starthilfe geben, wie ich ein kompilierfähiges Assemblerprogramm erstelle, oder kann mir gar jemand das Blinky-Programm kurz übersetzen ? Ich danke euch im voraus! Gruß MrAndyCool
--- HIER DAS PROGRAMM: ---
1 | /* FLASH.C - LED Flasher for Phytecs Rapid Development Kits */
|
2 | |
3 | #include <XC167.h> /* special function register for XC161 */ |
4 | |
5 | sbit P9_0 = P9^0; /* declare portpin to use */ |
6 | sbit DP9_0 = DP9^0; /* declare direction bit to use */ |
7 | |
8 | void wait (void) { /* wait function */ |
9 | ; /* only to delay for LED flashes */ |
10 | }
|
11 | |
12 | void main (void) { |
13 | unsigned long i=0; /* delay var */ |
14 | |
15 | DP9_0 = 1; /* init direction to output */ |
16 | while (1) /* loop forever */ |
17 | { /* An embedded program does not stop */ |
18 | |
19 | P9_0 = 0; /* output to LED port */ |
20 | for (i=0; i<100000; i++) { /* delay for 150000 counts */ |
21 | wait (); /* call wait function */ |
22 | }
|
23 | |
24 | P9_0 = 1; /* output to LED port */ |
25 | for (i=0; i<100000; i++) { /* delay for 150000 counts */ |
26 | wait (); /* call wait function */ |
27 | }
|
28 | }
|
29 | }
|
Ich weiß nicht, ob der Code lesbar ist, aber bei den Projekt-Einstellungen gibts normalerweise ein Hackerl, mit dem man ASM-Sourcen erzeugen lassen kann. mfg
Habs gerade versucht, das funktioniert (im Listing-File), danke. Die Codeschnipsel kann ich verwenden. ABER das Programmieren ist auch nicht das Haupt-Problem: Ich brauche eine Starthilfe, WIE man überhaupt in Assembler programmiert: 1. Welche Datei muss ich anlegen ? (*.A66 ?) 2. Was muss ich am Header schreiben ? ($MODV2 ??? $include ??? ORG ???) Ich will schlicht erst mal kompilieren können.
Puh...hab den XC bis jetzt nur in C programmiert. Vielleicht hilft dir aber noch ein Blick in den startup-code den uVision dabei hat, der sollte einigermaßen gut dokumentiert sein. mfg
Erst einmal ein herzliches Hallo an alle im Forum!!!! Ist mein erster Beitrag hier :) So, tut mir leid das ich diesen Thread ausgrabe, aber ich komme einfach nicht weiter... Ich benutze seit kurzem das ekxc167ci und wollte es wahlweise mit c, oder c++ programmieren. Auf der Suche nach einem Code-Beispiel bin ich auf den oben dargestellten Code gestoßen. Er lässt sich in Keil uVision 4 auch compilieren und linken. Aber: diese kleinen mistigen LEDs wohlen nicht leuchten... und ich weis einfach nicht warum... Soweit ich das noch weis, muss ich doch nur den Pin der LED (also für mehrere LEDs die Pins) deklarieren, auf Ausgang setzen und an- und ausschalten. Ich bring die LED nicht mal nur zum leuchten... Könnte mir bitte wer helfen? Benutze ich die falschen Befehle? Würde mich über Eure Hilfe sehr freuen und hoffe das kit nicht aus dem Fenster feuern zu müssen ;)
blub blubba schrieb: > Erst einmal ein herzliches Hallo an alle im Forum!!!! > Ist mein erster Beitrag hier :) Sieht man: wozu einen mehr als 5 Jahre alten Thread kapern? > Autor:Reinhard B. (brainstorm) > Datum: 07.05.2007 > Autor: blub blubba (Firma: none) (crumbjunk) > Datum: 14.12.2012 Besser wäre es, einen neuen Thread anzulegen und auf den alten zu verlinken, wenn der relevant ist. blub blubba schrieb: > das ekxc167ci Link zum Manual? > Soweit ich das noch weis, muss ich doch nur den Pin der LED (also für > mehrere LEDs die Pins) deklarieren, auf Ausgang setzen und an- und > ausschalten. Und wie sieht das bei dir genau aus? (längeren C-Quelltext als Anhang mit Dateieindung *.c) Kannst du Einzelschritt debuggen?
Hi Lothar danke für deinen Hinweis. Das nächste mal werde ich einen neuen Thread aufmachen und den alten bei Relevanz verlinken. So, zu meinem Problem. Die LEDs leuchten jetzt! Leider aber nicht so wie sie sollen...
1 | #include <XC167.h> /* special function register for XC161 */ |
2 | |
3 | sbit blink = P1L^0; |
4 | |
5 | |
6 | void wait (void) |
7 | {
|
8 | unsigned long i; |
9 | while (i < 10000000) |
10 | {
|
11 | i = i + 1; |
12 | }
|
13 | }
|
14 | |
15 | void main (void) |
16 | {
|
17 | endless:
|
18 | DP1L = 0xff; |
19 | wait(); |
20 | DP1L = 0x00; |
21 | wait(); |
22 | goto endless; |
23 | }
|
Sie sollten nun ja eigentlich blinken. Leider leuchten sie erst ca. 1 Sekunde hell und werden dann dunkler und bleiben dann so... Hab ich mich nur verrechnet? (Board hat einen 40 MHz Takt. Oder stimmt doch was an meinem Code nicht? Oh, jetzt hätte ich es fast vergessen: hier ist das manual: http://www.infineon.com/dgdl/xc167_32_ds_v1.1_2006_08.pdf?folderId=db3a304412b407950112b408e8c90004&fileId=db3a304412b407950112b41c637b2e04&sId=db3a30443b92f0fc013b9575aefe055e
So ein Murks. Das "sbit blink = P1L^0;" kannst Du Dir ganz schnell löschen. Registerdefinitionen sind schon in Deinen µC-Definitionen "#include <XC167.h>" drin. Bitte ERST die entsprechenden Port-Richtungsregister einmalig setzen (auf Output), dann die Pins toggeln. Was machst Du da mit dem GOTO? Ist das Dein erster C-Code? Umständlich...
Hehe, danke für den Hinweis das es Murks ist... die goto-loop war noch ein Überbleibsel von Assembler und wie ich auf den ständigen direction-Wechsel gekommen bin... mh... keine Ahnung^^ Naja, was solls. Jetzt läufts. Für alle die es vielleicht interessiert:
1 | #include <XC167.h> /* special function register for XC161 */ |
2 | |
3 | |
4 | |
5 | void wait (void) |
6 | {
|
7 | double i; |
8 | while(i < 40000) |
9 | {
|
10 | i = i+1; |
11 | }
|
12 | }
|
13 | |
14 | void main (void) |
15 | {
|
16 | |
17 | DP1L = 0xff; // port P1L output |
18 | while(1) // endless loop |
19 | {
|
20 | P1L = 0x00; // P1L (all LEDs) on |
21 | wait(); |
22 | P1L = 0xff; // P1L (all LEDs) off |
23 | wait(); |
24 | }
|
25 | }
|
Vielen Dank für Eure helfenden Beiträge!
Ja, das ist was, was ich auch nicht ganz verstehe. Wenn i vom Typ unsigned long ist und i bis 40.000.000 gezählt wird, dann leuchten die LEDs ziemlich genau 8 Sekunden lang hell, und werden dann dunkler. Nun hat ja das Board einen Takt von 40 MHz, also sollten die LEDs doch, wenn ich i bis 40.000.000 hochzählen lasse, jede Sekunde an, bzw. aus gehen. Sie gehen aber, wenn i vom Typ double ist und i bis 80.000 gezählt wird ziemlich genau jede Sekunde an und dann aus. Warum?
Ja... Genau aus dem Grund macht man das ja auch so nicht mit seinen Delay-Schleifen. ODer besser ausgedrückt: Delay-Schleifen sind immer zu vermeiden. Organisiere das mal mit einem Timer, dann muss man sich auch nicht wundern, dass ein 16-Bit-µC (wie der XC167) eine andere Zeit braucht, um double -Fließkomma-Variablen (!) zu handeln, als ein anderer µC. Für die oben im Code gezeigten 40000 reicht hier auch ein unsigned short int aus, das wären dann 16 Bit. Ich bin mir aber sehr sicher, dass der XC mit unsigned short ints schneller "umgehen kann", als mit Fließkommazahlen.
Was Du machst, ist irgend einen Datentypen zu nehmen und so lange am Schräubchen zu drehen, bis da ungefähr 1 Sekunde raus kommt. Sei froh, dass sie LED sichtbar blinkt, damit war's dann auch schon mit dem Demo-Code.
blub blubba schrieb: > Nun hat ja das Board einen Takt von 40 MHz, also sollten die LEDs doch, > wenn ich i bis 40.000.000 hochzählen lasse, jede Sekunde an, bzw. aus > gehen. 1. Der Takt aussen am Board ist noch lange nicht der Core Takt für die CPU. 2. Verschiedene Befehle haben unterschiedliche Verarbeitungszeiten. Es gibt Pipelines und Compileroptimierungen, die eine zeitliche Bestimmung der Programmablaufgeschwindigkeit erheblich erschweren. 3. Für Zeitreferenzen gibt es Timer. Die melden sich üblicherweise per Interrupt. Wenn du mit deinem Experiment noch weiter basteln möchtest, nutze den unsigned long und schalte jegliche Optimierung aus. Dann spielst du mit dem i und fügst ein paar _nop() ein, bis dir die Werte gefallen. Aber das ist nur basteln ohne Lerneffekt.
So, hab`s jetzt. Das Problem lag ja eigentlich auf der Hand. wait() zählt einmal hoch und bleibt dann auf dem hochgezählten Wert stehen (ich hab ja nie zurückgesetzt). Daher leuchten die LEDs hell bis einmal hochgezählt wurde. Anschließend wird ohne wait() ständig ein- und ausgeschaltet und so leuchten die LEDs schwächer. Hier ist mal ein Lauflicht, bei dem der Zähler immer wieder mit dem Parameter 0 gestartet wird.
1 | |
2 | #include <XC167.h> /* special function register for XC161 */ |
3 | |
4 | |
5 | |
6 | void wait (unsigned long i) |
7 | {
|
8 | |
9 | while(i < 4000000) |
10 | {
|
11 | i = i+1; |
12 | }
|
13 | }
|
14 | |
15 | void main (void) |
16 | {
|
17 | |
18 | DP1L = 0xff; // port P1L output |
19 | P1L = 0xff; // all LEDs off |
20 | while(1) |
21 | {
|
22 | wait(0); |
23 | P1L = 0xfe; |
24 | |
25 | wait(0); |
26 | P1L = 0xfd; |
27 | |
28 | wait(0); |
29 | P1L = 0xfb; |
30 | |
31 | wait(0); |
32 | P1L = 0xf7; |
33 | |
34 | wait(0); |
35 | P1L = 0xef; |
36 | |
37 | wait(0); |
38 | P1L = 0xdf; |
39 | |
40 | wait(0); |
41 | P1L = 0xbf; |
42 | |
43 | wait(0); |
44 | P1L = 0x7f; |
45 | |
46 | wait(0); |
47 | P1L = 0xbf; |
48 | |
49 | wait(0); |
50 | P1L = 0xdf; |
51 | |
52 | wait(0); |
53 | P1L = 0xef; |
54 | |
55 | wait(0); |
56 | P1L = 0xf7; |
57 | |
58 | |
59 | wait(0); |
60 | P1L = 0xfb; |
61 | |
62 | wait(0); |
63 | P1L = 0xfd; |
64 | }
|
65 | }
|
Funktioniert wunderbar und wait() läuft mit unsigned long so wie erwartet. @ fvbq34g1 Vielen Dank für die Info. Bei Gelegenheit werde ich das Progrämmchen mit einem Timer realisieren! @ fvbq34g1 Unnütz... @ 32 Bit Danke, wie gesagt, den Timer werde ich bei nächster Gelegenheit mal ausprobieren! Das es Verzögerungen gibt, da die Befehle verarbeitet werden müssen habe ich gewusst, nur das es doch soviel ausmacht hätte ich nicht erwartet. Danke nochmal.
blub blubba schrieb: > #include <XC167.h> /* special function register for XC161 */ > > > > void wait (unsigned long i) > { > > while(i < 4000000) > { > i = i+1; > } > } > > void main (void) > { > > DP1L = 0xff; // port P1L output > P1L = 0xff; // all LEDs off > while(1) > { > wait(0); > P1L = 0xfe; > > wait(0); > P1L = 0xfd; > > wait(0); > P1L = 0xfb; noch ein Tipp für die Schleife, obwohl man das natürlich mit einem Timer macht.
1 | void wait (void) |
2 | {
|
3 | unsigned long i; |
4 | |
5 | for(i = 0;i < 4000000;i++) |
6 | _nop_(); // #include <INTRINS.H> |
7 | _nop_(); |
8 | _nop_(); |
9 | }
|
10 | |
11 | void main (void) |
12 | {
|
13 | DP1L = 0xff; // port P1L output |
14 | P1L = 0xff; // all LEDs off |
15 | while(1) |
16 | {
|
17 | wait(); |
18 | P1L = 0xfe; |
19 | |
20 | wait(); |
21 | P1L = 0xfd; |
22 | |
23 | wait(); |
24 | P1L = 0xfb; |
25 | ...
|
32 Bit schrieb: > for(i = 0;i < 4000000;i++) > _nop_(); // #include <INTRINS.H> > _nop_(); > _nop_(); Mist! for(i = 0;i < 4000000;i++) { _nop_(); // #include <INTRINS.H> _nop_(); _nop_(); } Klammern vergessen.
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.