Forum: Mikrocontroller und Digitale Elektronik Problem mit SDCC und Daten Seriell einlesen


von Frank aus Köln (Gast)


Lesenswert?

Guten Morgen Zusammen,

ich habe ein Problem mit folgender Funktion :
1
unsigned char spiIn ()
2
{
3
    unsigned char bitcnt;
4
    unsigned char spiindat = 0;
5
    for (bitcnt=0;bitcnt<8;++bitcnt)
6
    {
7
         ENC_CLK = 1;
8
         spiindat<<=1;
9
         spiindat+= ENC_Din;
10
         ENC_CLK = 0;
11
    }
12
    return spiindat;
13
}

Diese funktion soll an dem Portpin "ENC_Din" 8bit serielle daten 
empfangen und in die Variable spiindat schieben.
Das hat auch super geklappt mit der SDCC Version 2.6.0 #4309 (Jul 28 
2006).
Mit den SDCC versionen ab Mai diesen Jahres funktioniert das jetzt nicht 
mehr. In der .lst datei der "alten" version sah das ganze dann so aus :

1 ;--------------------------------------------------------
2 ; File Created by SDCC : FreeWare ANSI-C Compiler
3 ; Version 2.6.0 #4309 (Jul 28 2006)
4 ; This file generated Mon Apr 23 10:15:21 2007
5 ;--------------------------------------------------------
...
534 ;Allocation info for local variables in function 'spiIn'
535 ;------------------------------------------------------------
536 ;bitcnt                    Allocated to registers r3
537 ;spiindat                  Allocated to registers r2
538 ;------------------------------------------------------------
539 ;  spi.c:26: unsigned char spiIn ()
540 ;  -----------------------------------------
541 ;   function spiIn
542 ;  -----------------------------------------
543 _spiIn:
544 ;  spi.c:29: unsigned char spiindat = 0;
545 ;  genAssign
546   mov  r2,#0x00
547 ;  spi.c:30: for (bitcnt=0;bitcnt<8;++bitcnt)
548 ;  genAssign
549   mov  r3,#0x00
550 00101$:
551 ;  genCmpLt
552 ;  genCmp
553   cjne  r3,#0x08,00110$
554 00110$:
555 ;  genIfxJump
556 ;  Peephole 108.a  removed ljmp by inverse jump logic
557   jnc  00104$
558 ;  Peephole 300  removed redundant label 00111$
559 ;  spi.c:32: ENC_CLK = 1;
560 ;  genAssign
561   setb  _P2_6
562 ;  spi.c:33: spiindat<<=1;
563 ;  genLeftShift
564 ;  genLeftShiftLiteral
565 ;  genlshOne
566   mov  a,r2
567 ;  Peephole 254  optimized left shift
568   add  a,r2
569   mov  r2,a
570 ;  spi.c:34: spiindat+= ENC_Din;
571 ;  genAssign
572   clr  a
573   mov  c,_P2_4
574   rlc  a
575 ;  genPlus
576   mov  r4,a
577 ;  Peephole 177.b  removed redundant mov
578 ;  Peephole 236.a  used r2 instead of ar2
579   add  a,r2
580   mov  r2,a
581 ;  spi.c:35: ENC_CLK = 0;
582 ;  genAssign
583   clr  _P2_6
584 ;  spi.c:30: for (bitcnt=0;bitcnt<8;++bitcnt)
585 ;  genPlus
586 ;     genPlusIncr
587   inc  r3
588 ;  Peephole 112.b  changed ljmp to sjmp
589   sjmp  00101$
590 00104$:
591 ;  spi.c:37: return spiindat;
592 ;  genRet
593   mov  dpl,r2
594 ;  Peephole 300  removed redundant label 00105$
595   ret

Bei der Version von Heute z.B. kommt das raus :

1 ;--------------------------------------------------------
2 ; File Created by SDCC : free open source ANSI-C Compiler
3 ; Version 2.7.2 #4871 (Jul  2 2007)
4 ; This file generated Tue Jul 03 07:41:33 2007
5 ;--------------------------------------------------------
...
525 ;------------------------------------------------------------
526 ;Allocation info for local variables in function 'spiIn'
527 ;------------------------------------------------------------
528 ;bitcnt                    Allocated to registers r3
529 ;spiindat                  Allocated to registers r2
530 ;------------------------------------------------------------
531 ;  spi.c:43: unsigned char spiIn()
532 ;  -----------------------------------------
533 ;   function spiIn
534 ;  -----------------------------------------
535 _spiIn:
536 ;  spi.c:46: unsigned char spiindat = 0;
537   mov  r2,#0x00
538 ;  spi.c:47: for (bitcnt=0;bitcnt<8;++bitcnt)
539   mov  r3,#0x00
540 00101$:
541   cjne  r3,#0x08,00110$
542 00110$:
543   jnc  00104$
544 ;  spi.c:49: ENC_CLK = 1;
545   setb  _P2_6
546 ;  spi.c:50: spiindat<<=1;
547   mov  a,r2
548   add  a,r2
549   mov  r2,a
550 ;  spi.c:51: spiindat+= ENC_Din;
551   mov  c,_P2_4
552   clr  a
553   rlc  a
554   mov  r4,a
555   add  a,r2
556   mov  r2,a
557 ;  spi.c:52: ENC_CLK = 0;
558   clr  _P2_6
559 ;  spi.c:47: for (bitcnt=0;bitcnt<8;++bitcnt)
560   inc  r3
561   sjmp  00101$
562 00104$:
563 ;  spi.c:54: return spiindat;
564   mov  dpl,r2
565   ret

Ich vermute das Problem liegt in den Zeilen 551 bis 553, da erst der 
Akku gelöscht wird und dann geschoben wird.

Hat soetwas schon jemand gehabt und kennt jemand einen Workaround für 
dieses Problem. Ich habe schon versucht diese Funktion anders zu 
formulieren aber das brachte bis jetzt auch nicht den gewünschten 
erfolg.

Gruß aus Köln

Frank


von Joe (Gast)


Lesenswert?

Das ist ein BUG, BUGREPORT ist erstellt.

von Andreas K. (a-k)


Lesenswert?

> Ich vermute das Problem liegt in den Zeilen 551 bis 553, da erst der
> Akku gelöscht wird und dann geschoben wird.

Ist so korrekt. Damit wird das C-Flag in Bit 0 vom Akku geschoben, mit 
dem Ergebnis A = C ? 1 : 0. CLR A lässt das C Flag unverändert, daher 
ist es egal ob das vor MOV C,port oder danach erfolgt.

Da das der einzige Unterschied ist, dürfte das Problem woanders liegen.

von Joe (Gast)


Lesenswert?

Es ist ein BUG im startupcode, P2 wird hier 0x00 gesetzt.

Setzte P2 auf 0xFF und es geht.

von Frank aus Köln (Gast)


Lesenswert?

Hallo zusammen,

das ist ja echt ein Knaller, kaum macht man tes richtig schon gehts 
auch.
Ich habe den ENC_Din (P2_4) jetz auf 1 gesetzt und schon läuft die 
Routine.
Also Andreas hatte schon recht, das die Macke irgendwo anders liegen 
muss.

Wenn ich eine Main Funktion baue die nichts anderes als ein while(1) 
enthält, wird auch P2 "gecleart" (Kopfkratz).

Es wird aber auch nur P2 gelöscht. Und ausgerechnet an diesem Port liegt 
mein Ausgang vom ENC.

Also scheint der SDCC eine Macke zu haben, oder kann mir jemand erklären 
warum P2 vor dem eigentlichen Programm gelöscht werden sollte ?

Vielen Dank euch beiden

Gruß

Frank

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.