Forum: Mikrocontroller und Digitale Elektronik Problem bei Compilerwechsel GCC -> IAR-Compiler


von Christoph M. (christoph137)


Angehängte Dateien:

Lesenswert?

Nach dem Wechsel vom System GCC+Eclipse zur Embedded Workbench von IAR 
funktioniert meine Funktion zur Datenübertragung über die UART nicht 
mehr richtg. Es kommen nur noch die Hex-Zeichen 00 und 80 an, unabhängig 
davon was ich sende.
1
/*--------------------------------------------------------------------
2
 uart.c  
3
 */
4
#include "uart.h"
5
#include "ADuC7026.h"
6
#define CR 0x0D // CR carriage return
7
8
static void warteBisSendebereit_uart(void);
9
10
void init_uart(void) {
11
  // Die Pins für die UART aktivieren (Pin 62+61).
12
  setBit(GP1CON,0);  // Portpins P1.0 und P1.1 für TxD und RxD
13
  setBit(GP1CON,4);  // anktivieren (SPM0 und SPM1).
14
        // Stelle die UART auf 9600bps etc.
15
        COMCON0 = 0x080;  // Zugang zu COMDIV0+1 Registern
16
        COMDIV0 = 0x088;  // setze auf 9000 bps
17
        COMDIV1 = 0x000;
18
        COMCON0 = 0x007;  // 8 Datenbits, 2 Stopbits, kein Parity
19
}           
20
21
void sendeText_uart(char *derText) {
22
  while(*derText) {
23
    sendeZeichen_uart(*derText); 
24
    derText++; 
25
  }  
26
}
27
28
int sendeZeichen_uart(const int dasZeichen)  {
29
  if (dasZeichen == '\n')  {
30
            warteBisSendebereit_uart();
31
      COMTX = CR;
32
  }
33
        warteBisSendebereit_uart();
34
        return (COMTX = dasZeichen);
35
}
36
37
static void warteBisSendebereit_uart(void) {
38
  while(!(0x020==(COMSTA0 & 0x020))){}  
39
}
40
/*--------------------------------------------------------------------
41
 uart.h 
42
 */
43
#ifndef UART_H_
44
#define UART_H_
45
46
/*  450 COMPATIABLE UART CORE REGISTERS */
47
#define UARTBASE   (*(volatile unsigned long *)   0XFFFF0700)
48
#define COMTX            (*(volatile unsigned long *)   0XFFFF0700)
49
#define COMRX            (*(volatile unsigned long *)   0XFFFF0700)
50
#define COMDIV0    (*(volatile unsigned long *)   0XFFFF0700)
51
#define COMIEN0    (*(volatile unsigned long *)   0XFFFF0704)
52
#define COMDIV1    (*(volatile unsigned long *)   0XFFFF0704)
53
#define COMIID0    (*(volatile unsigned long *)   0XFFFF0708)
54
#define COMCON0    (*(volatile unsigned long *)   0XFFFF070C)
55
#define COMCON1    (*(volatile unsigned long *)   0XFFFF0710)
56
#define COMSTA0    (*(volatile unsigned long *)   0XFFFF0714)
57
#define COMSTA1    (*(volatile unsigned long *)   0XFFFF0718)
58
#define COMSCR     (*(volatile unsigned long *)   0XFFFF071C)
59
#define COMIEN1    (*(volatile unsigned long *)   0XFFFF0720)
60
#define COMIID1    (*(volatile unsigned long *)   0XFFFF0724)
61
#define COMADR           (*(volatile unsigned long *)   0XFFFF0728)
62
#define COMDIV2    (*(volatile unsigned long *)   0XFFFF072C)
63
64
/* Funktionen */
65
void init_uart(void);
66
void sendeText_uart(char *derText);
67
int  sendeZeichen_uart(const int dasZeichen);
68
69
#endif /*UART_H_*/
70
/*--------------------------------------------------------------------
71
 main.c
72
 */
73
#include "ADuC7026.h"
74
75
void main(void) {
76
  init_uart();
77
  sendeText_uart("abc");
78
}
Optimiert der Compiler hier falsch, oder wo könnte der Fehler liegen?
Es gibt noch für den Linker diese .xcl Datei - die habe ich mir noch 
nicht richtig angeschaut. Zudem ist anders, dass ich die startup.c Datei 
die ich unter Eclipse verwendet habe nicht mehr benutze.

Hat jemand Erfahrungen damit oder ne Idee?

Lieben Gruß
Christoph

__
Das System:
ADuC7026 von Analog Devices. J-Link Adapter von Segger.
IAR EmbeddedWorkbench 4.41 als 32k-Kickstart Version.

von Christoph M. (christoph137)


Lesenswert?

Ich habe das ganze jetzt mal soweit wie möglich vereinfacht, und im 
Compiler die Optimierungen ausgeschaltet.
Es kommen aber immer noch nur die Hex-Zeichen 00 und 80 an! :-(
1
#include ".\include\ADuC7026.h"
2
3
void main(void){
4
  GP1CON = 0x011;
5
        // Stelle die UART auf 9600bps etc.
6
        COMCON0 = 0x080;  // Zugang zu COMDIV0+1 Registern
7
    COMDIV0 = 0x088;  // setze auf 9000 bps
8
    COMDIV1 = 0x000;
9
    COMCON0 = 0x007;
10
  
11
  while(!(0x020==(COMSTA0 & 0x020))){} //Warten auf Sendebereit
12
   COMTX = 1;  //empfangen wird: 80 00
13
  while(!(0x020==(COMSTA0 & 0x020))){} //Warten auf Sendebereit
14
   COMTX = 0;  //empfangen wird: 00
15
  while(!(0x020==(COMSTA0 & 0x020))){} //Warten auf Sendebereit
16
   COMTX = 0x60;  //empfangen wird: 00 80
17
}
???

von Kai (Gast)


Lesenswert?

Es sieht so aus, dass dein uC zu langsam läuft. Somit werden die Bits 
dann gestreckt und es kommt was falsches raus.
Überprüf doch mal, ob die CD-Bits im POWCON MMR auf 0 stehen! Nur wenn 
dies der Fall ist, gilt für COMDIV0=0x88.

von Christoph M. (christoph137)


Angehängte Dateien:

Lesenswert?

Kai wrote:
> Es sieht so aus, dass dein uC zu langsam läuft. Somit werden die Bits
> dann gestreckt und es kommt was falsches raus.
> Überprüf doch mal, ob die CD-Bits im POWCON MMR auf 0 stehen! Nur wenn
> dies der Fall ist, gilt für COMDIV0=0x88.

OK vielen lieben Dank - du hattest recht!
Wenn ich mit
POWKEY1 = 0x01;
POWCON  = 0x0;
POWKEY2 = 0xF4;

meinen µC auf 41.78 MHz stelle erreiche ich die 9600 bps.

Vorher waren es die standardmäßigen 5.22 MHz und es hat dann natürlich, 
wie ich gerade herausgefunden habe, mit 1200 bps funktioniert.

Noch nen paar Anfängerfragen dazu:
Woran liegt das? Setzt die Software von AnalogDevices ARMWSD einige 
Register wenn ich den Flash beschreibe? Oder wird sowas von der 
startup.S erledigt, die ich nach dem Compilerwechsel nicht mehr verwende 
(weil ich sie nicht zum Laufen bekomme)?

Christoph

von Kai (Gast)


Lesenswert?

Ja, das wird in der startup.s erledigt:

.equ    PLLCFG_Val,     0x00000000

.if PLL_SETUP
                LDR     R0, =MMR_BASE_0
                MOV     R1, #0x01
                STR     R1, [R0,#POWKEY1_OFFSET]
                MOV     R1, #PLLCFG_Val
                STR     R1, [R0,#POWCON_OFFSET]
                MOV     R1, #0xF4
                STR     R1, [R0,#POWKEY2_OFFSET]
.endif

damit hast du jetzt die gleichen Einstellungen wie sie auch schon in 
dieser Datei gemacht wurden.

Melde mich später nochmal.

von Kai (Gast)


Lesenswert?

Wie du siehst, stehen grundlegende Initialisierungen in der startup.s.
Hierzu zählt u.a. die Konfiguration des Stacks und der PLL.
Das Ganze sollte auch in der Embedded Workbench vorhanden sein, wobei 
dann wahrscheinlich andere Standardwerte vorhanden sind.
Ich habe mir grade mal die Embedded Workbench installiert und 
angeschaut.
Die Aufgabe der startup.s übernimmt hier wohl die cstartup.s79. 
Zumindest findet sich hier u.a. eine Initialisierung für den Stack. Die 
Initialisierung für die PLL habe ich aber auch noch nicht gefunden. Wäre 
möglich, dass IAR den ADuC standardmäßig mit seinen Reset-Werten laufen 
lässt und alles andere dem Programmierer überlässt.

von Christoph M. (christoph137)


Lesenswert?

Hallo Kai,

lieben Dank, du bist echt nett!!


Kai wrote:
> Wie du siehst, stehen grundlegende Initialisierungen in der startup.s.
> Hierzu zählt u.a. die Konfiguration des Stacks und der PLL.
> Das Ganze sollte auch in der Embedded Workbench vorhanden sein, wobei
> dann wahrscheinlich andere Standardwerte vorhanden sind.

OK

> Ich habe mir grade mal die Embedded Workbench installiert und
> angeschaut.

Unglaublich. Danke.

> Die Aufgabe der startup.s übernimmt hier wohl die cstartup.s79.

OK hab sie in einem Beispiel gefunden. Auf
ftp://ftp.analog.com/pub/MicroConverter/ADuC702xV1.1/ADuC702x/code/IAR%2 
0Code%20Examples/DacSine/cstartup.s79
habe ich noch eine angeblich neuere Version gefunden.
Werde beide mal austesten, und den code zum Umschalten auf 41.78 MHz 
ggf. einbinden. Ich vermute, dass ich dann auch meine µC-Headerdatei 
wechseln muss (ADuC7026.h -> ioaduc7026.h) und nicht mehr die von GCC 
verwenden kann.

> Zumindest findet sich hier u.a. eine Initialisierung für den Stack. Die
> Initialisierung für die PLL habe ich aber auch noch nicht gefunden. Wäre
> möglich, dass IAR den ADuC standardmäßig mit seinen Reset-Werten laufen
> lässt und alles andere dem Programmierer überlässt.

..kann gut sein.

von Christoph M. (christoph137)


Angehängte Dateien:

Lesenswert?

...bin mir noch nicht so sicher welche der beiden cstartup.s79 Dateien 
ich jetzt nehmen soll. Hab mich erstmal für die aus dem IAR Beispiel 
entschieden, und den Code für die Initialisieung der PLL unten dran 
gehangen.

Läuft!

:-)

PS: Kann auch meine alte <ADuC7026.h> weiter verwenden (warum eigentlich 
auch nicht)

von gerhard (Gast)


Lesenswert?

hallo christoph,
die von dir gesuchte initialisierung wird bei der workbench in der regel 
in der funktion ....LowLevelInit() durchgeführt.
diese funktion wird normalerweise (z.b. beim at91sam7s) noch vor der 
initialisierung des stacks aufgerufen.
bei den ADuC7026 beispielen gibt es diese definitiv nicht.
nach einem reset wird auf den label ?cstartup gesprungen.

kurz danach findest du den kommentar:

; Add initialization needed before setup of stackpointers here

nachfolgend steht hier normalerweise der aufruf der funktion 
....LowLevelInit().

der grund warum ....LowLevelInit() so rasch aufgerufen wird liegt darin, 
das manche arm7 mit einem sehr langsam clokc hochlaufen (z.b.at91sam7s) 
und es daher sinn macht, so rasch als möglich auf die tatsächliche 
clock-frequenz umzuschalten.
nachteilig ist natürlich, das noch kein stack aufgesetzt ist und daher 
jeder funktions-aufruf ode rlokale variable tabu sind.

gruss
gerhard

von Christoph M. (christoph137)


Lesenswert?

...und wieder was gelernt!!

Vielen Dank.

Gruß, Christoph

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.