Delay bei ATtiny4

OP Persönliche Seite #2567326
Lesenswert?

Hallo,

ich spiele gerade mit dem ATtiny4 etwas rum... es soll eignetlich nur 
ein einfaches Blinklicht mit 2 LEDs werden.
Zum Test habe ich also mal ein Programm geschrieben, was PORTB an und 
aus machen soll:
1
#include <avr/io.h>
2

3
#define F_CPU 1000000UL
4
#include <util/delay.h>
5

6

7

8
int main(void)
9
{
10
  DDRB = 0xFF;
11
    PORTB = 0x00;
12
  
13
    while(1)
14
    {
15
    PORTB = 0x00;
16
    _delay_ms(500);
17
    PORTB = 0xFF;
18
    _delay_ms(500);
19
    }
20
}
das funktioniert soweit auch ganz gut. Nur komisch finde ich es wenn ich 
das Delay auf z.b. 100ms setzen möchte. Dann sagt mir der Compiler:

 error: unable to generate reloads for:
 internal compiler error: in find_reloads, at reload.c:3821

Wenn ich bei 100ms F_CPU auf 8000000 setze läuft das Projekt wieder ohne 
Fehler durch.
Ich kann mir jetzt irgendwie nur vorstellen, dass die delay Bibilotheken 
noch nicht für die neuen Tinys angepasst wurden (obwohl die neuste 
AVRStudio-Version nutze)
Hatte einer von euch schonmal so ein Problem? Wahrscheinlich übersehe 
ich gerade einfach nur eine Kleinigkeit.

Danke schon mal für eure Antworten !

Gruß
Persönliche Seite #2567372
Lesenswert?

Tim H. schrieb:

>  error: unable to generate reloads for:
>  internal compiler error: in find_reloads, at reload.c:3821

Atmel hat den avr-gcc aufgebohrt um die tinys zu unterstützen und dabei 
alle Register aus des Registerklasse "w" verboten.

An anderer Stelle — nämlich den delay-builtins — fordern sie aber, daß 
das Loop-Register die Constraint "w" haben muss.

Du sieht gerade den Effekt davon.

Ergo:

- Die Inline-Assebler-Version aus der avr-libc verwenden.
  Da gibt's irgendwo ein Makro das erkennt ob built-ins da sind oder
  nicht.

- Die Zeiten so stückeln, daß der Fehler nicht mehr auftritt.
Gast #2567516
Lesenswert?

Warum nicht? Wenn man Assembler nicht kann, Atmel es nun möglich macht, 
sehe ich keine Gründe die dagegen sprechen. Es sei denn das Prjekt 
scheitert weil der Code zu groß ist, dass muss man aber vorher 
abschätzen. So pauschal kann man das nicht sagen.


Ingo
OP Persönliche Seite #2567535
Lesenswert?

Also die Flash größe reicht mir... Das Programm oben braucht 92 Byte 
Flash. Und ja ich habe vor davon um die 1000 Stück zu verbauen.

Und: meint ihr soein Makro?
1
/** \ingroup util_delay_basic
2

3
    Delay loop using a 16-bit counter \c __count, so up to 65536
4
    iterations are possible.  (The value 65536 would have to be
5
    passed as 0.)  The loop executes four CPU cycles per iteration,
6
    not including the overhead the compiler requires to setup the
7
    counter register pair.
8

9
    Thus, at a CPU speed of 1 MHz, delays of up to about 262.1
10
    milliseconds can be achieved.
11
 */
12
void
13
_delay_loop_2(uint16_t __count)
14
{
15
  __asm__ volatile (
16
    "1: sbiw %0,1" "\n\t"
17
    "brne 1b"
18
    : "=w" (__count)
19
    : "0" (__count)
20
  );
21
}
OP Persönliche Seite #2567588
Lesenswert?

Hallo,

danke für die Antwort.
jetzt bekomme ich diese Fehlermeldung:
Error: illegal opcode sbiw for mcu attiny4
in der Schleife:
1
void _delay_loop_2(uint16_t __count)
2
{
3
  __asm__ volatile (
4
    "1: sbiw %0,1" "\n\t"
5
    "brne 1b"
6
    : "=d" (__count)
7
    : "0" (__count)
8
  );
9
}
Ich denke ich muss diese Zeile anpassen: "1: sbiw %0,1" "\n\t" aber wie?

Gruß
OP Persönliche Seite #2569160
Lesenswert?

Hallo,

danke für eure Hilfe schonmal. Ich hab jetzt diese Schleife geschrieben:
1
void delay(uint8_t ms){
2
  uint16_t cnt = 17355;
3

4
  while(cnt != 0){  
5
    cnt--;
6
  }
7
}
Die Schleife läuft genau 1s wenn ich den Code nicht optimiere. Aber 
dadurch braucht PORTB=0x00; auch mehrere Befehle. Wenn ich wieder die 
Optimierung einstelle, dann wird meine Schleife einfach wegoptimiert...
Persönliche Seite #2569520
Lesenswert?

Lass doch den MURKS mir C-Warteschleifen!

Korrigiere stattdessen den Header!
1
void _delay_loop_2 (uint16_t __count)
2
{
3
  __asm__ volatile (
4
    "1: subi %A0,1" "\n\t"
5
    "sbci %B0,0"    "\n\t"
6
    "brne 1b"
7
    : "=d" (__count)
8
    : "0" (__count)
9
  );
10
}

Wie's aussieht, hat Atmel nichtmal ein built-in Makro eingebaut, mit dem 
man diese brainf**ck Architektur abfragen kann...

http://distribute.atmel.no/tools/opensource/avr-gcc/gcc-4.5.1/32-gcc-4.5.1-avrtiny10.patch

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren