www.mikrocontroller.net

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


Autor: Christoph Meyer (christoph137)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.
/*--------------------------------------------------------------------
 uart.c  
 */
#include "uart.h"
#include "ADuC7026.h"
#define CR 0x0D // CR carriage return

static void warteBisSendebereit_uart(void);

void init_uart(void) {
  // Die Pins für die UART aktivieren (Pin 62+61).
  setBit(GP1CON,0);  // Portpins P1.0 und P1.1 für TxD und RxD
  setBit(GP1CON,4);  // anktivieren (SPM0 und SPM1).
        // Stelle die UART auf 9600bps etc.
        COMCON0 = 0x080;  // Zugang zu COMDIV0+1 Registern
        COMDIV0 = 0x088;  // setze auf 9000 bps
        COMDIV1 = 0x000;
        COMCON0 = 0x007;  // 8 Datenbits, 2 Stopbits, kein Parity
}           

void sendeText_uart(char *derText) {
  while(*derText) {
    sendeZeichen_uart(*derText); 
    derText++; 
  }  
}

int sendeZeichen_uart(const int dasZeichen)  {
  if (dasZeichen == '\n')  {
            warteBisSendebereit_uart();
      COMTX = CR;
  }
        warteBisSendebereit_uart();
        return (COMTX = dasZeichen);
}

static void warteBisSendebereit_uart(void) {
  while(!(0x020==(COMSTA0 & 0x020))){}  
}
/*--------------------------------------------------------------------
 uart.h 
 */
#ifndef UART_H_
#define UART_H_

/*  450 COMPATIABLE UART CORE REGISTERS */
#define UARTBASE   (*(volatile unsigned long *)   0XFFFF0700)
#define COMTX            (*(volatile unsigned long *)   0XFFFF0700)
#define COMRX            (*(volatile unsigned long *)   0XFFFF0700)
#define COMDIV0    (*(volatile unsigned long *)   0XFFFF0700)
#define COMIEN0    (*(volatile unsigned long *)   0XFFFF0704)
#define COMDIV1    (*(volatile unsigned long *)   0XFFFF0704)
#define COMIID0    (*(volatile unsigned long *)   0XFFFF0708)
#define COMCON0    (*(volatile unsigned long *)   0XFFFF070C)
#define COMCON1    (*(volatile unsigned long *)   0XFFFF0710)
#define COMSTA0    (*(volatile unsigned long *)   0XFFFF0714)
#define COMSTA1    (*(volatile unsigned long *)   0XFFFF0718)
#define COMSCR     (*(volatile unsigned long *)   0XFFFF071C)
#define COMIEN1    (*(volatile unsigned long *)   0XFFFF0720)
#define COMIID1    (*(volatile unsigned long *)   0XFFFF0724)
#define COMADR           (*(volatile unsigned long *)   0XFFFF0728)
#define COMDIV2    (*(volatile unsigned long *)   0XFFFF072C)

/* Funktionen */
void init_uart(void);
void sendeText_uart(char *derText);
int  sendeZeichen_uart(const int dasZeichen);

#endif /*UART_H_*/
/*--------------------------------------------------------------------
 main.c
 */
#include "ADuC7026.h"

void main(void) {
  init_uart();
  sendeText_uart("abc");
}
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.

Autor: Christoph Meyer (christoph137)
Datum:

Bewertung
0 lesenswert
nicht 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! :-(
#include ".\include\ADuC7026.h"

void main(void){
  GP1CON = 0x011;
        // Stelle die UART auf 9600bps etc.
        COMCON0 = 0x080;  // Zugang zu COMDIV0+1 Registern
    COMDIV0 = 0x088;  // setze auf 9000 bps
    COMDIV1 = 0x000;
    COMCON0 = 0x007;
  
  while(!(0x020==(COMSTA0 & 0x020))){} //Warten auf Sendebereit
   COMTX = 1;  //empfangen wird: 80 00
  while(!(0x020==(COMSTA0 & 0x020))){} //Warten auf Sendebereit
   COMTX = 0;  //empfangen wird: 00
  while(!(0x020==(COMSTA0 & 0x020))){} //Warten auf Sendebereit
   COMTX = 0x60;  //empfangen wird: 00 80
}
???

Autor: Kai (Gast)
Datum:

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

Autor: Christoph Meyer (christoph137)
Datum:
Angehängte Dateien:

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

Autor: Kai (Gast)
Datum:

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

Autor: Kai (Gast)
Datum:

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

Autor: Christoph Meyer (christoph137)
Datum:

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

Autor: Christoph Meyer (christoph137)
Datum:
Angehängte Dateien:

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

Autor: gerhard (Gast)
Datum:

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

Autor: Christoph Meyer (christoph137)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...und wieder was gelernt!!

Vielen Dank.

Gruß, Christoph

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.