Forum: Compiler & IDEs fehler in asm.S für winavr-c


von pebisoft (Gast)


Lesenswert?

der befehl : cbi  PortB,0
und       sbi  PortB,0
werden beanstandet, welcher fehler liegt hier vor.
ich progge in winavr-c
mfg pebisoft

soft_uart_1.S: Assembler messages:
soft_uart_1.S:10: Error: constant value required
soft_uart_1.S:12: Error: constant value required


.global soft_uart
.func   soft_uart
soft_uart:
      lds  r24,wert
  __Com1O:ldi    r25,10
      Com    r24
      sec
  __C1O0:  brcc  __C1O1
      cbi    PortB,0
      rjmp  __C1O2
  __C1O1:  sbi    PortB,0
      Nop
  __C1O2:  ldi    r23,66
      rcall  __Wtic
      ldi    r23,66
      rcall  __Wtic
      lsr    r24
      dec    r25
      brne  __C1O0
          rjmp  __ende

  __Wtic:  dec    r23
      brne  __Wtic
      ret

  __ende:
      ret
.endfunc
.end

von pebisoft (Gast)


Lesenswert?

korrektur : PortB.0 habe ich auch schon anders geschrieben : PORTB,0
trotzdem der fehler.
mfg pebisoft

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?


von pebisoft (Gast)


Lesenswert?

jetzt habe die beiden mal reingestellt.
soft_uart_1.o(.text+0x2): In function `soft_uart':
soft_uart_1.S:6: undefined reference to `wert'

wie kann ich den "wert" bekannt machen?

die winavr-c-datei:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include #include <inttypes.h>
#include <stdint.h>
#include <avr/delay.h>


extern void soft_uart(uint8_t wert);

void warte(uint16_t wert){
  for (uint16_t zeit=0;zeit<wert;zeit++)
  {
    _delay_ms(10);
  }
}

int main (void)
{
    DDRB|=(1<<PB0);

  uint8_t wert;
  wert=34;

  for (;;) {

    soft_uart(wert);
    warte(100);

   }
}


die soft_uart.S :

#include <avr/io.h>

.global soft_uart
.func   soft_uart
soft_uart:
      lds  r24,wert
  __Com1O:ldi    r25,10
      Com    r24
      sec
  __C1O0:  brcc  __C1O1
      out  _SFR_IO_ADDR(PORTB), 0
      rjmp  __C1O2
  __C1O1:  out  _SFR_IO_ADDR(PORTB), 1
      Nop
  __C1O2:  ldi    r23,66
      rcall  __Wtic
      ldi    r23,66
      rcall  __Wtic
      lsr    r24
      dec    r25
      brne  __C1O0
          rjmp  __ende

  __Wtic:  dec    r23
      brne  __Wtic
      ret

  __ende:
      ret
.endfunc
.end

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> wie kann ich den "wert" bekannt machen?

Du lässt diese Zeile einfach weg. ;-)

r24 ist ohnehin der erste Funktionsparameter.  Vielleicht hättest
du ja in TFM gleich weiter R'en sollen?  In der FAQ steht die
Registerkonvention:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html

Das hier

  __C1O2:  ldi    r23,66
      rcall  __Wtic
      ldi    r23,66
      rcall  __Wtic
...
  __Wtic:  dec    r23
      brne  __Wtic
      ret

verstehe ich übrigens nicht.  Warum nicht
gleich

   1:  ldi  r23, 132
       dec  r23
       brne 1b

?  (Ggf., die 132 noch erhöhen, weil 2x RCALL/RET wegfallen.)

Statt rjmp _ende kannst du natürlich auch gleich ret schreiben. ;-)

von pebisoft (Gast)


Lesenswert?

danke, jetzt funktioniert es.
die sofware_uart-senden mit dem avr16 und 8mhz ist fehlerfrei.
die datei ist jetzt schön klein und handlich.
hatte garnicht gedacht, das eine datei so kurz werden kann
mit so einem guten resultat.

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <string.h>
#include <stdint.h>
#include <avr/delay.h>

volatile uint8_t wert;
extern void soft_uart(void);

void warte(uint16_t wert){
  for (uint16_t zeit=0;zeit<wert;zeit++)
  {
    _delay_ms(10);
  }
}

int main (void)
{
    DDRB|=(1<<PB0);

  for (wert = 7; wert < 16; wert++)
  {

    soft_uart();
    warte(50);

   }
}


soft_uart.S datei:

#include <avr/io.h>

.global soft_uart
.func   soft_uart
soft_uart:
      lds    r24,wert
  __Com1O:ldi    r25,10
      Com    r24
      sec
  __C1O0:  brcc   __C1O1
      ldi   r16,0
      out    _SFR_IO_ADDR(PORTB), r16
      rjmp  __C1O2
  __C1O1:  ldi   r16,1
      out    _SFR_IO_ADDR(PORTB), r16
      Nop
  __C1O2:  ldi    r23,132
  __1b:  dec    r23
            brne   __1b
      lsr    r24
      dec    r25
      brne  __C1O0
      ret
.endfunc
.end

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.