mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik BYTE xdata buffer[4]; ... und Krawumm...


Autor: Max Wau (wauschi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Forum!

Ich habe gerade einen etwas entdeckt was ich mir nicht erklären kann.

Ich lese mit einem Cypress AN2131 einen ADC über I2C.
Zum verwenden der I2C Funktionen benötige ich eine variable aus dem 
xdata Bereich. Ich schreibe also:

BYTE xdata buffer[4];
buffer[0] = 0;
buffer[1] = 1;

Wenn ich das mache spielt der Controller total verrückt!
Warum?
Was mache ich falsch?

Ich bin schon auf eure Meinung gespannt!

Lg,
Wauschi

Autor: Max Wau (wauschi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:
Verrück ist zB., dass sich gewisse Ports nicht mehr schalten lassen und 
sich der Controller nach gewisser Zeit aufhängt..

Autor: ARM-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleiner Tipp, falls keine Antworten auf deine Frage kommen sollten:

Lies dir mal selbst deine Frage durch und beurteile,
ob die durch einen Fremden ohne hellseherische Fähigkeiten bzw. Kenntnis
des weiteren Sourcecodes zu beantworten ist.

Autor: Max Wau (wauschi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ARM-Fan,
dein Input ist natürlich berechtigt, aber meine Absicht war eigentlich 
nicht, dass jemand meinen Code debugged.

Ich dachte an eine generelle Erklärung wie:
Hallo Wauschi, der xdata Adressbereich wird meist direkt auf die 
Hardware gemappt. Es ist also möglich, dass deine Zuweisung externe 
Beschaltung beeinflusst und damit ein Paradoxon im Raum-Zeit Kontinuum 
auslöst.

Gerne gehe ich genauer auf das Problem ein.
Ich versuche einen AD7417 ADC über I2C mit folgender Funktion zu lesen:

unsigned int readADCformatted(BYTE channel)
{
  unsigned char msb = 0;
  unsigned char lsb = 0;
  unsigned int result = 0;
  BYTE xdata adc_buffer[4];
  //readADC(buffer,channel);
  // reg config
  adc_buffer[0] = 0x01;
  //buffer[1] = channel << 5;
  adc_buffer[1] = 0x80;
  ezusbWriteI2C(ADC_I2C_ADDR, 2, adc_buffer);
  // reg thyst
  adc_buffer[0] = 0x02;
  adc_buffer[1] = 0x4b;
  ezusbWriteI2C(ADC_I2C_ADDR, 2, adc_buffer);
  // reg toti
  adc_buffer[0] = 0x05;
  adc_buffer[1] = 0x00;
  ezusbWriteI2C(ADC_I2C_ADDR, 2, adc_buffer);

  adc_buffer[0] = channel;
  adc_buffer[1] = 0;
  ezusbWriteI2C(ADC_I2C_ADDR, 1, adc_buffer); // select register

  ezusbReadI2C(ADC_I2C_ADDR, 2, adc_buffer); // read adc register

  msb = adc_buffer[0];
  lsb = adc_buffer[1];
  result = (msb << 8) | lsb;
  result >>= 6;
  return result;
}

Nach der Zuweisung: adc_buffer[1] = 0x80; habe ich keine Kontrolle über 
gewisse Ports und der Controller hängt sich früher oder später auf.

Danke für deinen Input,
Wauschi

Autor: ARM-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, hast du denn überhaupt xdata speicher?

Also hat der Controller internen xdata Speicher?
Oder hast du extern noch ein SRAM dranhängen?
Ist in der Entwicklungsumgebung alles richtig eingestellt?
(Falls es der Keil ist, dann mußt du dort angeben, wo dein xdata liegt)

Außerdem habe ich im Datenblatt zum Cyress gerade noch folgendes 
geleseen:

"When ISODISAB=1, the 2,048 bytes of RAM normally used for isochronous 
buffers is available to
the 8051 as XDATA RAM (not program memory), from 0x2000 to 0x27FF in 
internal memory."

Tja, und was wenn nicht...? Wo schreibt er dann hin...

Laß doch den Compiler selbst entscheiden, wo er deinen Buffer hinpackt.
Warum hast du überhaupt xdata angegeben.
Wenn du nichts hinschreibst, dann richtet er sich nach dem in den
Projekteinstellungen angebenen Memory-Model.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Check mal aktivität auf dem RD/WR Anschlüssen deines MC's. Wenn da 
Signale für externen RAM Write anliegen dann wird dein XDATA definitiv 
auf ein externes RAM gemapped (so sollte es ja auch sein).

Ich kann daher die Frage von "ARM Fan" nur wiederholen, hat dein MC 
einen internen RAM Bereich der als XDATA fungiert ? Das ist z.B. bei 
diveresen ATMEL 8x51 Derivaten der Fall. Allerdings führt XDATA zu 
keinerlei aktivitäten auf der READ/WRITE Leitung (da ja internes XDATA).

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, hab mir mal das Datenblatt von deinem EZ-USB angeschaut, 256 Byte 
internes RAM wie beim standard 8x52.

Also vergiss es mit XDATA ;-) es sei denn du hast nen externes RAM.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
alles Quatsch das Teil hat sehr wohl XDATA Speicher. Sonst könnte man 
nicht das Code Ram aus dem Treiber oder EEprom laden. Das ist die
klassische VNM Architektur
Allerdings ist der Speicher sowohl Code als auch XDATA mit den std
einstellungen XDATA im bereich um 0 überschreibst du halt den Code.
Näheres ist wie immer in solchen Fällen im Mapfile zu finden.
Andere Möglichkeit währe dann noch wenn dein XDATA Speicher in EZUSB SFR
Bereich gemapped ist.

Einfach mal das Getting started zu den EZ USB chips durchlesen.
Da ist das alles sehr schön erklärt.

Thomas

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas,

Seite 56 im Manual beschreibt die Speicherarchitektur, es gibt durchaus 
reichlich RAM in dem Teil.

Allerdings bin ich der Meinung das der Fragende die hintergrund 
Informationen zur Verfügung stellen sollte. Ich lese jedenfalls nicht 
das ganze Handbuch für irgendeinen suchenden ;-))

PS: Ein paar Seiten zuvor gibt es einen entsprechenden Hinweis zu den 
Speicherbereichen und dem Verhalten von RD/WR. Nur der untere 
Speicherbereich 0000 - xxxx (such mal selbst) ist von Neuman 
Architektur.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Joe
mir brauchst du das nicht zu sagen ich kenne die Teile und arbeite seit
Jahren damit sowohl mit den alten EZusb als auch FX(1)bzw FX2.
Die Teile haben zwischen 8 und 16k Coderam(Neuman Arch)

Meine Post war nicht and dich gerichtet, sondern algemein gedacht da 
fast ausschlieslich falsche Aussagen in dem Tread gemacht wurde.
Hinweise was falsch ist habe ich auch gegeben.
Warscheinlich schreibt der OP einfach im extented SFR Bereich rum.

Thomas

Autor: Max Wau (wauschi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die wirklich konstruktieven Tips (direktes Maß für die 
Qualität des Forums!)

Ich verwende keinen externen RAM, nicht einmal EEPROM.
Der Grund warum ich plötzlich XDATA deklariere ist weil der Compiler 
einen Fehler ausgibt wenn man ezusbWriteI2C() mit einem normalen Array 
aufruft. Ich habe einen Aufruf (über Umwegen) ohne xdata versucht aber 
da liefert I2C keine Daten. Wenn ich xdata deklariere bekomme ich 
korrekte Daten, aber nur einmal, etwas später hängt sich der Controller 
auf.

Danke für den Hinweis mit den Projekteinstellungen, diese werde ich 
kontrollieren, außerdem werde ich nach dem Getting Started Guide suchen 
(danke Thomas).

@Joe: Natürlich habe ich vor dem Posten das Datenblatt gelesen (speziell 
Seite 53ff), aber (für mich) keine gute Erklärung für xdata gefunden.

@Thomas: Ja, ich stimme dir zu, wahrscheinlich schreibe ich irgendwo im 
externen Berich herum...
Bei den Endpoints ist es mir klar, ich sage xdata, Name und die Adresse 
wo der EP liegt, aber in meinem Code habe ich ja keine Adresse für die 
Variable angegeben. Wie kann dann etwas außerhalb außerhalb angesprochen 
werden, ich würde mir zumindest eine Compiler-Warnung erwarten.

DANKE so weit, vielleicht fällt jemanden noch was ein.... Ich werde 
berichten wenn ich eine Lösung finde.

Wauschi

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der Grund warum ich plötzlich XDATA deklariere ist weil der Compiler
> einen Fehler ausgibt wenn man ezusbWriteI2C() mit einem normalen Array
> aufruft.

das liegt einfach daran dass ezusbWriteI2C() einen xdata buffer sehen 
will
Abhilfe:
entweder die Funktion unschreiben dass sie auch mit einem idata buffer
umgehen kann.
oder einfacher
BYTE xdata adc_buffer[4] in einen ubbenutzten Endpointbuffer legen

Dein XDATA Buffer startet ohen spezielle Masnahmen bei Xdata Addresse 0
Dies ist auch glechzeitig Code Addresse 0 da Neumann Architektur.
Damit überschreibt dein Buffer den Reset Vektor!
Schau mal ins Map File wo dein Buffer generiert wird.

Die I2C Lib Routinen sind nicht so der Bringer. Ich erinnere mich dass 
ich
die nicht verwendet habe sondern eigene geschrieben habe. Auserdem gibt 
es
noch diese I2C Wait Funktionen.

Ich schau mal morgen bach wie ich das hier genau mache

Thomas

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für single-Master ist I2C am einfachsten und kürzesten in Software:

http://home.tiscali.de/peterd/appl/soft/c51/eeprom/index.htm

Da kannst Du Dir ganz bequem die Funktionen zusammenbasteln, wie Du 
lustig bist. Im Beispiel ist es für nen EEPROM 24C16 zusammengebastelt.


Peter

Autor: Max Wau (wauschi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DANKE, Thomas, du bist heute mein Held!
Ich habe xdata vom nicht verwendeten EP7 verwendet.
Nach Tagen der Fehlersuche läuft es jetzt einwandfrei, super!

@Peter, danke für den Hinweis!

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.