Problem mit I2C-Schnittstelle ATMega 16 / 32

Und noch zwei weitere Fehlerchen...

  • 1
  • 2
  • Page 1 of 2
Gerrit
 
Avatar
 
Subject:

Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 10.04.2013 - 15:38  ·  #1
Moinsen!

Ich hab hier ein Verhalten der I2C-Schnittstelle, welches ich mir nicht erklären kann:

Hier das Programm, das als I2C-Slave arbeitet. Ist derzeit eine absolut abgespeckte Testversion (ich hab mich gestern dumm und dusselig gesucht... :angry7: ), die Daten laufen nachher auch nicht als Text sondern binär...

Code

begin
  InitPorts;


  EnableInts;
  
  ShowProg;
  mdelay(2000);
  loop
    IsI2CDbg := not Bit(PinD.2);

      ADCRes := GetADC;
      OutStr := IntToStr(ADCRes);
      DsplWriteLine(0,outStr);
      mDelay(50);
      
      PrgStrToArray(@OutStr,@TWITXBUFFER[8]);

      DsplWriteLine(1,ByteToHex(TwiTxBuffer[8]) + ' ' + ByteToHex(TwiTxBuffer[9]));

//      TWITXBUFFER[11] := LO(ADCRes);
//      TWITXBUFFER[10] := HI(ADCRes);


//  TWITXBUFFER[0]:= 123;

//  Test := 1;
//  Repeat
//    TWITXBUFFER[Test]:=NOT TWITXBUFFER[Test-1];
//    TWITXBUFFER[Test]:=Test;
//  Until not IncToLim(Test,63);

//    PrgReadADC;
//  TWITXBUFFER[8] := 123;//LO(ADCRes);
//  TWITXBUFFER[9] := 124; // HI(ADCRes);

//  IncToLimWrap(TwiTxBuffer[10],250,0);

    
//    mDelay(1);
//    portD.7 := not PortD.7;
  endloop;
end SerPedCtrl.



Hier jetzt der Programmteil des Masters, der den Slave ausliest:

Code
Procedure HndlDbgUT1;
Var
  TmpVol : Word;
  TmpTst : Byte;
  TmpCnt : Byte;
  TmpStr : String[16];
Begin
  LCDxy(0,0);
  Write(LCDout,'+');
  DsplWriteLine(1,'Wait...');


  TmpVol: = 0;
  TmpCnt := 0;
  repeat
    If TwiStat(2) Then
      If TwiOut(2,0) Then
        IF TwiInp(2,TestARR) Then
//          TwiInp(2,TestXXX);
          TmpTst:= 0;
          TestStr :='';
          Repeat
            TestStr := TestStr + ByteToHex(TestARR[TmpTst]);
          until not IncToLim(tmpTst,7);
//          DsplWriteLine(1,ByteToHex(TestARR[8]) + ' ' + ByteToHex(TestARR[9]));
          DsplWriteLine(0,TestStr);

          TmpTst:= 8;
          TestStr :='';
          Repeat
            TestStr := TestStr + ByteToHex(TestARR[TmpTst]);
          until not IncToLim(tmpTst,15);
//          DsplWriteLine(1,ByteToHex(TestARR[8]) + ' ' + ByteToHex(TestARR[9]));
          TestStr := '';
          PrgArrayToStr(@TestStr,@TestArr[0]);
          DsplWriteLine(1,TestStr);
        Else
          DsplWriteLine(1,'RD-ERR');
        EndIf;
      Else
        DsplWriteLine(1,'WT-ERR');
      EndIf;
    Else
        DsplWriteLine(1,'No device');
    EndIf;
    
    repeat
      SwtReslt := SwtPressedSwt;
      mDelay(1);
    Until (Not IncToLim(TmpCnt,50)) OR (SwtReslt = cSwtOKay);
    TmpCnt := 0;
  Until SwtReslt = cSwtOKay;

  LCDxy(0,0);
  Write(LCDout,' ');
  LCDclrLine(1);

  SwtReslt := cSwtWork;
End HndlDbgUT1;





Eigentlich würde man ja erwarten, daß im Master im Datenfeld die Daten an den Indizes 8 und fortlaufend stehen.

Irritierender Weise finden sich die daten aber unter dem Index 0 und folgende. Wenn ich Daten im Slave auf die Felder 0 ... 7 im Ausgangs-Datenfeld schreibe, werden diese Daten nicht vom Master gelesen obwohl als Startlese-index 0 gesendet wird.

Hätte da jemand vlt. eine Erklärung?

Bei der Gelegenheit noch zwei weitere Fehlerchen, die mir aufgefallen sind:

1) Die String-Konvertierungsfunktionen (ByteToStr etc.) arbeiten nicht bzw. nicht richtig mit lokalen Prozedurvariablen.

2) Beim Einlesen von Daten via SPIinpWord erhalte ich sowohl im Lowbyte als auch im Highbyte des Word die gleichen Daten. Lese ich aber mit SPIInpByte zweimal ein, erhalte ich die richtigen Daten. SPI-CS ist dabei in beiden Fällen programmgesteuert

Achso, und wo ich grad dabei bin: In der IDE verschluckt sich die Auflistung der Projekt-Funktionen/Variablen gerne mal beim Umschalten zwischen einzelnen geöffneten Projekten und unter Windows 7 wird mir inder IDE gerne auch mal eine Uhrzeit in der Art "63:20" angezeigt ... :angel7:

Viele Grüße

Gerrit
Gerrit
 
Avatar
 
Subject:

Re: Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 12.04.2013 - 19:07  ·  #2
Moinsen!

Keine eine Idee...? Schade.... *snieeef* ;)

Viele Grüße

Gerrit
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 12.04.2013 - 21:52  ·  #3
Hallo Gerrit,

die TWIs in den Megas sind leider nicht sonderlich stabil. Man muss da vorsichtig sein.
Es gibt hier aber ein paar User die ein TWI Master/Slave System sicher am laufen haben.

Zu den anderen Problemen soviel: ein kleines Beispiel wegen lokalen strings und ByteToStr
wären hilfreich.

Schon mal an Stack oder Frame überlauf gedacht ??

rolf
Gerrit
 
Avatar
 
Subject:

Re: Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 12.04.2013 - 23:49  ·  #4
Moin Rolf!

Hmmm - sehr schade, daß das mit den TWIs nicht so schön läuft. Dann muß ich wohl über die serielle Schnittstelle gehen (hab grad für einen anderen Teil der Anwendung festgestellt, daß die mit 1MBaud auch noch sehr schön läuft). Ich hatte schon sowas befürchtet und strick mir hier grad eine Schnittstelle und ein kleines Protokoll dazu.

Mit den lokalen Strings und ByteToString ist das nicht immer reproduzierbar. Ich glaube aber, daß ich gestern (eine mögliche) Ursache entdeckt habe: Für den Dateneingang der seriellen Schnittstelle nutze ich eine globale Variable. Zu Debugzwecken habe ich dann in einer Prozedur eine lokale Variabe als String[64] definiert - und mich hinterher gewundert und ziemlich lange gesucht, warum das danach nicht mehr klappte. Ich habe dann festgestellt, daß nach Eintritt in die Prozedur die Definition der lokalen Variable anscheinend den Speicherplatz der globalen Variable (ganz bis teilweise) überschrieben und geleert hatte.

Da das Ganze kein wirkliches Geheimnis (und auch noch nicht fertig) ist, poste ich hier mal den ganzen Code:

Code
program SerOTCtrl;

{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = mega16, VCC=5;
{ $BOOTRST $01C00}         {Reset Jump to $01C00}

Define_Fuses
//  Override_Fuses;
  NoteBook   = A;
  COMport    = USB;
  LockBits0 = [];
  FuseBits0  = [];
  FuseBits1  = [SPIEN];
  ProgMode   = SPI;

Import SysTick, SerPort, ADCPort, SPIdriver, TWIslave;
//Import SysTick, SerPort,  SPIdriver, TWIslave, LCDport;

From System Import LongWord;


Define
  ProcClock      = 16000000;       {Hertz}
  SysTick        = 5;             {msec}
  StackSize      = $0064, iData;
  FrameSize      = $0064, iData;
  SerPort        = 1000000, Stop1;    {Baud, StopBits|Parity}
//  SerPort        = 250000, Stop1;    {Baud, StopBits|Parity}
//  SerPort        = 9600, Stop1;    {Baud, StopBits|Parity}
  RxBuffer       = 32, iData;
  TxBuffer       = 32, iData;

  ADCchans       = 1, iData, Int2;
  ADCpresc       = 2;

  TWImode        = Transparent;    {HandShake or Transparen}
  TWIbuffer      = 64, iData;       {buffer/packet size}
  TWIaddr        = $31;             {BASS-OT Controler}

  SPIpresc       = 0;
  SPIOrder       = MSB;
  SPICPOL        = 1;
  SPICPHA        = 0;
  SPI_SS         = false;

//  LCDport        = PortA;
//  LCDtype        = 0073;
//  LCDrows        = 2;              {rows}
//  LCDcolumns     = 16;             {columns per line}

Implementation

{$IDATA}

{--------------------------------------------------------------}
{ Type Declarations }

type


{--------------------------------------------------------------}
{ Const Declarations }
CONST
  cSerCmdReset : Byte = $00;    //Schnittstellenreset

  cSerCmdPedals : Byte = $01;    // Es folgen Pedaltastendaten (Ein/Aus)
  cSerCmdSwell  : Byte = $02;    // Es folgen Schwellerdaten
  cSerCmdLwrDta : Byte = $03;    // Es folgen Tasten-/Schalterdaten.

  cSerCmdLslie  : Byte = $10;    // Eingangsdaten - Lesliesteuerung


{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
VAR
  PedSwlVal  : Word;           // Wert der Unterteil-Schwellerspannung
  PedKeyVal  : ARRAY[0..3] OF Byte;  // Tastenstati der Pedale
  PedSwitch  : Byte;                 // Fußschalter Unterteil
                                     // Bit 0,1 sind die Schwellerschalter Links/Rechts

  VolCtrlVal : Word;                 // Ausgabewert der Schwellerspannung (0...5V)

  SerNewData : Boolean;            // True, wenn neue Daten zum Senden
                                   // vorhanden sind.

  SerNewInp  : Boolean;            // True, wenn neue Daten empfangen wurden.

  SerInpStr  : String[33];         // Daten-Eingangsstring für seriellen Empfang

  SerInpDta  : ARRAY[0..15] OF Byte; // Eingangsdaten decodiert

  SerInpCmd  : Byte;               // Eingangsbefehl (seriell)

  IsI2CDbg   : Boolean;            // TRUE, wenn das Debuging auf dem I2C-
                                   // Port eingestellt ist (Jumper)



  TmpTest : Byte;
  OutStr : String[16];
  TestVal : Word;
{--------------------------------------------------------------}
{ functions }

procedure InitPorts;
begin
  PortA:= %11111111;
  DDRA:=  %00000000;
  
  PortB:= %11111111;
  DDRB:=  %10111100;
  
  PortC:= %11110000;
  DDRC:=  %11110000;
  
  PortD:= %11111111;
  DDRD:=  %00000010;
end InitPorts;


{
//Display nur zum ersten Debuggen.
Procedure DsplWriteLine(Line:Byte;Data:String[16]);
Begin
  LCDClrLine(Line);
  LCDxy(0,Line);
  Write(LCDout,Data);
End DsplWriteLine;


Procedure ShowProg;
Begin
  LCDClr;

  DsplWriteLine(0,'Test OTC 1 V 0.0');
  DsplWriteLine(1,'Vers. ' + IntToStr(ProjectBuild));

End ShowProg;
}



{---------------------------------------------------------------
Name:      PrgStrToArray
Datum:     01.04.2013
Parameter: Dta - String, der in ein ByteArray überführt werden soll
           ArPtr - Zeiger auf das Ziel-Array

Rückgabe:  keine


Zweck:
------
Überführt Daten aus einem String in ein Byte-Array, welches durch einen
Pointer festgelegt wird. Das Zielarray muß von der Größe her dem Quellstring
entsprechen, da es sonst zu Fehlern kommen kann.
--------------------------------------------------------------}
Procedure PrgStrToArray(StrPtr : Pointer; ArPtr : Pointer);
Var
  TmpN : Byte;
  TmpLen : Byte;
Begin

  ArPtr^ := StrPtr^;
  TmpLen := StrPtr^;

  TmpN :=1;
  For TmpN :=1 To TmpLen Do
    Inc(ArPtr);
    Inc(StrPtr);
    ArPtr^ := StrPtr^;
  EndFor;

  StrPtr := Nil;
  ArPtr  := Nil;
End PrgStrToArray;


{---------------------------------------------------------------
Name:      PrgArrayToString
Datum:     01.04.2013
Parameter: Dta - String, in den ein ByteArray überführt werden soll
           ArPtr - Zeiger auf das Quell-Array

Rückgabe:  keine


Zweck:
------
Überführt Daten aus einem Byte-Array in einen String, welches durch einen
Pointer festgelegt wird. Das Quellarray muß von der Größe her dem Zielstring
entsprechen, da es sonst zu Fehlern kommen kann.
--------------------------------------------------------------}
Procedure PrgArrayToStr(StrPtr : Pointer; ArPtr : Pointer);
Var
  TmpN : Byte;
  TmpLen : Byte;
Begin

  //SetLength(Dta,TmpDta);
  TmpLen := ArPtr^;
  StrPtr^:=ArPtr^;

  TmpN :=1;
  For TmpN :=1 To TmpLen Do
    Inc(ArPtr);
    Inc(StrPtr);
    StrPtr^:=ArPtr^;
  EndFor;

  StrPtr := Nil;
  ArPtr  := Nil;
End PrgArrayToStr;




{---------------------------------------------------------------
Name:      AlgIOWriteDacVal
Datum:     10.04.2013
Geändert:  10.04.2013

Parameter: Value - Der zu wandelnde Wert
           First - TRUE:  DAC-Kanal A
                   FALSE: DAC-Kanal B

Rückgabe:  keine


Zweck:
------
Schreibt den Wert in einen DAC.
Die Werte wurden bereits aufbereitet!
HINWEIS: "First" wird ignoriert, da für diese Anwendung nur
         ein Einkanaliger DAC (MCP4901) zum Einsatz kommt.
--------------------------------------------------------------}
Procedure AlgIOWriteDacVal(Value:Word;First:Boolean);
Var
  DacSnd: Word;
Begin
  DacSnd := 0;
  DacSnd := Value;

//  SetBit(DacSnd.15,First);
  SetBit(DacSnd.15,0);  // Für MCP4901 muß das Bit "0" sein, sonst wird der
                        // Befehl im DAC ignoriert.
  InCl(DacSnd,14);    // Kein Puffer - Werte direkt setzen
  InCl(DacSnd,13);
  InCl(DacSnd,12);

//  SetSPIorder(true);
//  SetSPIclkPol(1);
//  SetSPIclkPha(0);
  
  // Daten schreiben.
  PortB.2 := 0;
  sDelay(4);
  SPIoutByte(Hi(DacSnd));
  SPIoutByte(Lo(DacSnd));
  sDelay(4);
  PortB.2 := 1;

  // LDAC auslösen
  PortB.3 := 0;
  sDelay(4);
  PortB.3 := 1;

End AlgIOWriteDacVal;


{---------------------------------------------------------------
Name:      KeyWriteData
Datum:     10.04.2013
Geändert:  10.04.2013

Parameter: keine

Rückgabe:  keine


Zweck:
------
Schreibt die Daten der Tasten in die Ausgangsregister
--------------------------------------------------------------}
Procedure KeyWriteData;
Var
  TmpByte:Byte;
Begin

  PortB.4 := 0;
{  TmpByte:= Mirror8(SwtOutData[5]);
  SpiOutByte(SwtOutData[5]);

  TmpByte:= Mirror8(SwtOutData[4]);
  SpiOutByte(SwtOutData[4]);
}

//  TmpByte:= Mirror8(PedKeyVal[0]);
  SpiOutByte(PedKeyVal[0]);

//  TmpByte:= Mirror8(PedKeyVal[1]);
  SpiOutByte(PedKeyVal[1]);

//  TmpByte:= Mirror8(PedKeyVal[2]);
  SpiOutByte(PedKeyVal[2]);

//  TmpByte:= Mirror8(PedKeyVal[3]);
  SpiOutByte(PedKeyVal[3]);

  PortB.4 :=1;
End KeyWriteData;




{---------------------------------------------------------------
Name:      SerInpCnvrt
Datum:     10.04.2013
Geändert:  10.04.2013

Parameter: AsString : True, wenn die übergebenen Daten KEINE
                      Binärdarstellung sondern eine Zeichenfolge
                      sind

Rückgabe:  Boolean - True, wenn Daten empfangen wurden


Zweck:
------
Analysiert die empfangenen Daten der seriellen Schnittstelle
und setzt die entsprechenden Variablen
Die Funktion setzt die globaden Werte

    - SerInpStr
    - SerInpDta
    - SerInpCmd
--------------------------------------------------------------}
Function SerInpCnvrt(AsStr:Boolean):Boolean;
Var
  TmpStt:Byte;
  TmpAdr:Byte;
  TmpDta:String[31];
Begin
  If SerStat then
    ReadLn(SerInp,SerInpStr);    // Datenzeile einlesen

    If AsStr Then
      TmpDta := Copy(SerInpStr,2, Length(SerInpStr)-1);
      PrgStrToArray(@TmpDta,@SerInpDta);
    Else
      // Puffer löschen
      // ACHTUNG: Auf die Grenzen achten sonst wird darüber hinaus geschrieben.
      TmpAdr := 0;
      Repeat
        SerInpDta[TmpAdr] := 0;
      Until not IncToLim(TmpAdr,Byte((SizeOf(SerInpDta)-1)));

      //Daten einlesen
      //Zuerst das CommandByte
      TmpAdr := 0;
      TmpDta := Copy(SerInpStr,1,2);
      SerInpCmd := HexToInt(TmpDta);

      For TmpStt:=3 To (Length(SerInpStr)-1) By 2 Do
        TmpDta := Copy(SerInpStr,TmpStt,2);
        SerInpDta[TmpAdr] := HexToInt(TmpDta);
        IncToLim(TmpAdr);
      EndFor;

    EndIf;

    Return (True);
  Else
    Return (False);
  EndIf;
End SerInpCnvrt;




{---------------------------------------------------------------
Name:      SerHdlData
Datum:     10.04.2013
Geändert:  11.04.2013

Parameter: keine

Rückgabe:  keine


Zweck:
------
Wertet die seriell empfangenen Daten aus und setzt die Ausgangsregister
enstprechend.

Die Funktion setzt die globaden Werte

    -
    -
    -
--------------------------------------------------------------}
Procedure SerHdlData;
Var
  NewKeys : Boolean;
  NewSwll : Boolean;
  NewSwts : Boolean;
  TmpCnt  : Byte;
  
  TmpVol  : Word;

//  TmpStr  : String[64];
Begin

//  TmpStr := '';
//  TmpStr := 'TestData';
  
  NewKeys := False;
  NewSwll := False;
  NewSwts := False;
  TmpCnt := 0;

  If SerInpCnvrt(False) Then
//writeLn(SerOut,'New data');
//mdelay(20);
    // Derzeit wird nur "Kombiniert" empfangen.
    
    // Daten kommen schon mit positiver Logik aus dem Unterteil,
    // d.h. gedrückte Tasten sind ein gesetztes Bit, nicht gedrückte
    // Tasten sind "0"
    tmpCnt:= 0;
    repeat
      If PedKeyVal[TmpCnt]<> SerInpDta[TmpCnt] Then
        NewKeys := True;
        PedKeyVal[TmpCnt] := SerInpDta[TmpCnt];
      EndIf;
    Until NOT IncToLim(TmpCnt,3);

//    PedSwitch := SerInpDta[4];

    IF (not Bit(PinB,1)) OR Bit(PinD.3) Then
      // Es ist kein Schweiller im Oberteil eingesteckt, daher die
      // hier empfangenen Daten setzen.

      Hi(TmpVol) := SerInpDta[5];
      Lo(TmpVol) := SerInpDta[6];
//WriteLn(SerOut,'Is external');

      // Hammond liefert invertiert, daher hier umkehren.
      TmpVol := 1024 - TmpVol;

      // Jetzt entsprechend verschieben
      TmpVol := TmpVol SHR 2;
      TmpVol := TmpVol SHL 4;

      If TmpVol>4095 Then
        TmpVol := 4095;
      EndIf;
//WriteLn(SerOut,'Temp Vol: ' + IntToStr(TmpVol));
      If TmpVol <> VolCtrlVal Then
//WriteLn(SerOut,'Temp Vol: IsNew ' + IntToStr(TmpVol));
        NewSwll := True;
      endIf;
    EndIf;
  EndIf;
  
  If Bit(PinB,1) AND (NOT Bit(PinD,3)) then
    // Es ist ein Schweller im Oberteil eingesteckt.
    TmpVol := GetADC;

//WriteLn(SerOut,'Is internal');

    // Jetzt entsprechend verschieben
    TmpVol := TmpVol SHR 2;
    TmpVol := TmpVol SHL 4;

    If TmpVol>4095 Then
      TmpVol := 4095;
    EndIf;
    If TmpVol <> VolCtrlVal Then
      NewSwll := True;
    endIf;
  EndIf;
  
  //Fußschalter links
  SetBit(PedSwitch,7,(Bit(SerInpDta[4],0) OR (Not Bit(PinA,1))));

  //Fußschalter rechts
  SetBit(PedSwitch,6,(Bit(SerInpDta[4],1) OR (Not Bit(PinA,2))));

  If (Bit(PedSwitch,7)<>Bit(PedKeyVal[3],7)) OR (Bit(PedSwitch,6)<>Bit(PedKeyVal[3],6)) Then
    NewKeys := TRUE;
    SetBit(PedKeyVal[3],0,Bit(PedSwitch,7));
    SetBit(PedKeyVal[3],1,Bit(PedSwitch,6));
  EndIF;
  
  If NewKeys Then
    KeyWriteData;
  EndIf;
  If NewSwll then
    VolCtrlVal := TmpVol;
    AlgIoWriteDacVal(VolCtrlVal,False);
  EndIf;
  
//  If NewKeys Or NewSwll Then
//    TmpStr := ByteToHex(PedKeyVal[0]) + ' ' + ByteToHex(PedKeyVal[0]) + ' ' + ByteToHex(PedKeyVal[0]) + ' ' +
//                   ByteToHex(PedKeyVal[0]) + ' ' + IntToStr(VolCtrlVal);
                   
//    WriteLn(SerOut, ByteToHex(PedKeyVal[0]) + ' ' + ByteToHex(PedKeyVal[1]) + ' ' + ByteToHex(PedKeyVal[2]) + ' ' +
 //                  ByteToBin(PedKeyVal[3]) + ' Vol: ' + IntToStr(VolCtrlVal));
//  EndIf;
End SerHdlData;





{--------------------------------------------------------------}
{ Main Program }
{$IDATA}

begin
  InitPorts;


  EnableInts;
  
//  ShowProg;
//  mDelay(2000);
  
  TmpTest := 0;
//  Repeat
//    TWITXBUFFER[TmpTest] := TmpTest;
//  until not IncToLim(TmpTest,63);

//  For TmpTest := 0 To 63 Do
//    TWITXBUFFER[TmpTest] := tmptest;
//  EndFor;


  TestVal := 0;
  loop
    SerHdlData;

//  If SerStat then
//    ReadLn(SerInp, SerInpStr);
//    WriteLn(SerOut,SerInpStr);
//  EndIf;
  endloop;
end SerOTCtrl.


Ist (in diesem Falle zum Glück) noch nicht ganz aufgeräumt. Das Verhalten trat hier in der Prozedur "SerHdlData" auf.

Ich vermute daher, daß das auch das Problem mit bei den ByteToStr-Funktionen sein kann denn die Funktionen arbeiten einwandfrei, wenn von lokale auf globale variable gewechselt wird.

Viele Grüße

Gerrit
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 13.04.2013 - 17:21  ·  #5
Hallo Gerrit,

wow, SerHdlData ruft SerInpCnvrt auf und beide haben (hatten) mächtig was auf dem
Frame (lokale Vars).
Dazu kommen noch die String Konvertierungen, die auch relativ viel Frame brauchen.
Da knallt es dann im Frame mit einem Frame-Überlauf, 100%ig.

rolf
miparo
Administrator
Avatar
Gender:
Location: Germany
Age: 58
Posts: 959
Registered: 09 / 2007
Subject:

Re: Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 15.04.2013 - 00:26  ·  #6
Quote by Gerrit

1) Die String-Konvertierungsfunktionen (ByteToStr etc.) arbeiten nicht bzw. nicht richtig mit lokalen Prozedurvariablen.


Hallo Gerrit,
das deutet meistens schon auf einen zu kleinen Frame hin.

Merkwürdes Verhalten immer erst im Stack/Frame suchen bzw. in der Entwicklungsphase immer reichlich hoch setzten. Sparen kannste dann immer noch.

miparo
Gerrit
 
Avatar
 
Subject:

Re: Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 23.04.2013 - 16:46  ·  #7
Moinsen!

'tschuldigung. Mußte überraschend geschäftlich dringend ein paar Tage weg und konnte mich nicht weiter darum kümmern, daher jetzt erst die Rückmelung...

Danke erstmal für die Tips, das seh ich mir mal an. Irgendwie war ich der Meinung gewesen, daß da eine Warnung kam, wenn das mit dem Frame/Stack nicht ausreichte - aber da werde ich wohl was verwechseln...

@Rolf: Ich geb's ja zu, ich mag keine globalen Variablen. Da ich meist in anderen Entwicklungsumgebungen unterwegs bin, spielt das auch keine Rolle - nur bei den µCs muß ich mir das, was ich mir seit 35 Jahren abgewöhnt habe hier wieder angewöhnen... :D

Hab mich im übrigen jetzt endgültig dazu entschieden, die I2C Schnittstelle für die Kommunikation unter den Modulen rauszuschmeißen und werde stattdessen mit der seriellen Schnittstelle arbeiten - allerdings nicht mit dem seriellen Netzwerk. Da spendier ich lieber noch zwei bis drei Leitungen und einen 245er je Modul ... ;)

Nochmals vielen Dank.

Viele Grüße

Gerrit
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1408
Registered: 03 / 2005
Subject:

Re: Problem mit I2C-Schnittstelle ATMega 16 / 32

 · 
Posted: 23.04.2013 - 17:13  ·  #8
Hi Gerrit.

I also always use local variables where I can - not globals.

It is not inherently bad, because once used the space is given back. It is only a problem with things like strings in parameter lists where is can be a bit of a challenge.

Don't give up on 35 years of good programming practice ;-)
  • 1
  • 2
  • Page 1 of 2
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   135   149 · Page-Gen-Time: 0.034191s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI