Forum: Compiler & IDEs const verändert


von Peter Z. (Gast)


Lesenswert?

Hallo allerseits,
ich programmiere mit dem Atmel Studio 6.1 einen ATtiny84 der hat 512 
Byte RAM. Bisher lief mein kleines Programm ganz gut, dann bin ich auf 
die Idee gekommen als erstes nach der Portinitialisierung ein Blümchen 
auf den LCD-Bildschirm zu malen.
1
void Blume(void)
2
{
3
  uint32_t Screen[102]; // 408 von 512 Byte!!!
4
  int16_t A,B,C,D;
5
  // der Code hier interressiert jetzt nicht
6
}
Wie man sieht braucht die Blume fast den ganzen RAM des ATtiny84.
Danach sind die Globalen Konstanten verändert:
1
const int32_t max_wert[4] = {1123,9999,99999,3600};
statt dessen steht in den Konstanten:
0xAF590763, 0x0000370D, 0x00000000, 0x00000000

Wie kann das sein?
Es gab keine Compiler Warnung!
Was tun außer Blümchen weg lassen?

von Ralf G. (ralg)


Lesenswert?

Peter Zz schrieb:
> Wie kann das sein?
Das Programm braucht auch RAM (Stack).
> Es gab keine Compiler Warnung!
Kann er auch nicht.
> Was tun außer Blümchen weg lassen?
Konstanten in den Flash. Größerer Controller.

von Peter Z. (Gast)


Lesenswert?

Ralf G. schrieb:
> Konstanten in den Flash.

was meinst du damit?
1
const int32_t PROGMEM max_wert[4] = {1123,9999,99999,3600};
So?

von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:
> Ralf G. schrieb:
>> Konstanten in den Flash.
>
> was meinst du damit?
>
1
> const int32_t PROGMEM max_wert[4] = {1123,9999,99999,3600};
2
>
> So?


Ja.
Aber wenn du es so machst, dann musst du auch die Zugriffe im Programm 
verändern. Du kannst dann die Werte nicht mehr einfach so benutzen, 
sondern musst über die Funktion pgm_read_xxxx gehen

AVR-GCC-Tutorial: Flash mit PROGMEM und pgm read

Allerdings muss das dein Problem noch nicht lösen. Wenn es im SRAM eng 
wird, dann zerschiesst man sich gerne eine Menge Dinge. Das einzelne 
Variablen ihren Wert ändern, ist oft nur die Spitze des Eisbergs.

Im übrigen wäre es vernünftig, nicht die Maximalwerte ins SRAM zu 
verschieben, sondern das Blümchen.
Denn
1
void Blume(void)
2
{
3
  uint32_t Screen[102]; // 408 von 512 Byte!!!
4
  int16_t A,B,C,D;
5
  // der Code hier interressiert jetzt nicht
6
}
Ganz im Gegenteil. Genau dieser Code interessiert. Denn wenn du das 
Screen-Array gar nicht brauchst, löst sich dein Problem ganz von alleine 
in Luft auf.

: Bearbeitet durch User
von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Du kannst dann die Werte nicht mehr einfach so benutzen,
> sondern musst über die Funktion pgm_read_xxxx gehen

Mache ich auch schon z.B. für die LCD-Initialisierung:
1
const unsigned char PROGMEM init_seq[13]=
2
{0x40,0xA0,0xC8,0xA4,0xA6,0xA2,0x2F,0x27,0x81,0x10,0xFA,0x90,0xAF};
oder die Zeichensätze.

Habe andere konstante Werte mit enum gemacht:
1
enum{keine_Taste,up,down,rechts,links,Enter};

Bin unzufrieden, warum werden gerade Konstanten verändert,
die sollten doch, wie der Name schon sagt, konstant sein.
Es gab keine Compiler Warnung, selbst als ich das Array noch größer als 
512 Byte gemacht habe.

von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:

> Bin unzufrieden, warum werden gerade Konstanten verändert,

weil es sich, auch wenn der Name etwas anderes suggeriert, erst mal um 
Variablen handelt. Variablen von denen der Programmierer die Zusage 
macht, dass er sie im Programm nicht verändern wird und die daher als 
konstante Werte aufzufassen sind. Aber es sind nach wie vor Variablen 
und wenn der Compiler es nicht schafft, die Werte überall an den 
verwendenden Stellen einzusetzen, dann werden die auch im Speicher 
angelegt, so wie jede andere Variable auch.

> die sollten doch, wie der Name schon sagt, konstant sein.

Dagegen, dass du mit der Brechstange durch den Speicher pflügst, ist 
kein Kraut gewachsen. Wenn die Brechstange zuschlägt, ändern sich 
Speicherinhalte im SRAM. Punkt. Was auch immer an dieser Stelle im 
Speicher liegt, wird verändert. Die Brechstange kümmert sich nicht 
darum, was du eigentlich an dieser Stelle im Speicher liegen hättest.
In einem Tiny gibt es keine Hardware, mit der man SRAM Speicher gegen 
Schreibzugriffe schützen könnte.

> Es gab keine Compiler Warnung, selbst als ich das Array noch größer als
> 512 Byte gemacht habe.

Weil das dem Compiler wurscht ist. Der Compiler weiß nicht, wieviel SRAM 
Speicher zur Verfügung steht.

: Bearbeitet durch User
von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Genau dieser Code interessiert. Denn wenn du das
> Screen-Array gar nicht brauchst, löst sich dein Problem ganz von alleine
> in Luft auf.

Das LCD-Display ist EA DOGS102W-6 mit 102x64 Pixel
Ich zeichne die erste Hälfte des Blümchen ins uint32_t Screen[102] 
Array.
Danach wird diese erste Hälfte zum LCD-Display geschickt.
Dann zeichne ich die zweite Hälfte des Blümchen ins Array.
Danach wird diese zweite Hälfte zum LCD-Display geschickt.

Dann wird das Blümchen 2 Sekunden lang angezeigt. Das Array wird danach 
nicht mehr gebraucht, die Funktion Blume() wird nie mehr aufgerufen.

von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
>> Es gab keine Compiler Warnung, selbst als ich das Array noch größer als
>> 512 Byte gemacht habe.
>
> Weil das dem Compiler wurscht ist. Der Compiler weiß nicht, wieviel SRAM
> Speicher zur Verfügung steht.

Kann es sein, das es nur bei Globalen Variablen eine Compilerwarnung 
gibt?!

von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:

> Ich zeichne die erste Hälfte des Blümchen ins uint32_t Screen[102]
> Array.

Wie zeichnest du?
Ist das eine Formel. Vielleicht irgendwas in der Art eines Spirographen. 
Oder ist das eine vorgefertigte Bitmap? Oder?

...
> Danach wird diese erste Hälfte zum LCD-Display geschickt.
> Dann zeichne ich die zweite Hälfte des Blümchen ins Array.
> Danach wird diese zweite Hälfte zum LCD-Display geschickt.
>
> Dann wird das Blümchen 2 Sekunden lang angezeigt. Das Array wird danach
> nicht mehr gebraucht, die Funktion Blume() wird nie mehr aufgerufen.

Das mag schon sein. Aber wenn sie aufgerufen wird, verbraucht sie zuviel 
Speicher. Das ist nicht wegzudiskutieren. Das Symptom ist, dass andere 
Variablen ihre Werte ändern. Die Ursache ist, dass die Funktion Blume() 
zu viel Speicher verbraucht.
Was willst du bekämpfen? Das Symptom oder die Ursache?
Ich würde das Problem an der Wurzel packen und die Ursache bekämpfen. 
Die Funktion muss weniger Speicher verbrauchen. Egal wie.

: Bearbeitet durch User
von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Dagegen, dass du mit der Brechstange durch den Speicher pflügst, ist
> kein Kraut gewachsen.

immerhin habe ich eine Abfrage ob ich die Grenzen des Array Screen[102] 
verlassen habe:
1
if((Y <= 31) && (X < 102)) Screen[X] |= (uint32_t)0x01 << Y;// PSET(X,Y)

von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Wie zeichnest du?
> Ist das eine Formel. Vielleicht irgendwas in der Art eines Spirographen.
1
void Blume(void)
2
{
3
  uint32_t Screen[102];
4
  int16_t A,B,C,D;
5
  uint16_t n;
6
  uint8_t X,Y,Spalte,Zeile,i;
7
  for(Zeile = 0;Zeile <= 7;Zeile += 4)
8
  {
9
    A = 2867;
10
    B = 0;
11
    C = 942;
12
    D = 0;
13
    for(Spalte = 0;Spalte <= 101;Spalte++) Screen[Spalte] = 0;
14
    for(n = 0;n < 3216;n++)
15
    {
16
      A = A + ((B * 4) >> 9);
17
      B = B - ((A * 4) >> 9);
18
      C = C + ((D * 25) >> 9);
19
      D = D - ((C * 25) >> 9);
20
      X = 51 + ((A + D) >> 7);
21
      Y = 32 + ((B + C) >> 7) - Zeile * 8;
22
      if((Y <= 31) && (X < 102)) Screen[X] |= (uint32_t)0x01 << Y;// PSET(X,Y)
23
    }
24
    for(i = 0; i <= 3;i++)
25
    {
26
      set_pos(Zeile + i,0,absolut);
27
      switch(i)
28
      {
29
        case 0 : for(Spalte = 0;Spalte <= 101;Spalte++) LCD_Data(Screen[Spalte] >>  0); break;
30
        case 1 : for(Spalte = 0;Spalte <= 101;Spalte++) LCD_Data(Screen[Spalte] >>  8); break;
31
        case 2 : for(Spalte = 0;Spalte <= 101;Spalte++) LCD_Data(Screen[Spalte] >> 16); break;
32
        case 3 : for(Spalte = 0;Spalte <= 101;Spalte++) LCD_Data(Screen[Spalte] >> 24); break;
33
      }
34
    }
35
  }
36
}

von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Ich würde das Problem an der Wurzel packen

und die Blume rausreißen  ;-)

von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:
> Karl Heinz schrieb:
>> Dagegen, dass du mit der Brechstange durch den Speicher pflügst, ist
>> kein Kraut gewachsen.
>
> immerhin habe ich eine Abfrage ob ich die Grenzen des Array Screen[102]
> verlassen habe:

Du hast das Problem nicht verstanden.

Du hast 10 Eimer Wasser nebeneinander stehen, von denen keiner übergehen 
darf. Du achtest peinlich genau darauf, dass genau das nicht passiert, 
wenn du Wasser nachfüllst.
Und dann kommt die Feuerwehr und spritzt mit dem Schlauch in deinen 
Garten.

Es spielt keine Rolle, ob die peinlich genau auf die Füllmenge achtest. 
Denn die Feuerwehr tut das nicht und spritze einfach alles nieder.

Dein Array ist zu groß für deinen Speicher. Das kannst du drehen und 
wenden wie du willst. Es gibt einzelne Speicherzellen, die sowohl für 
den Array benutzt werden als auch für andere Dinge.

Wenn du Variablen global anlegst, dann wachsen die im Speicher von der 
linken Seite her
1
int Variable1, Variable2;
2
3
   +---+---+---+---+---+---+---+---+---+---+
4
   |   |   |   |   |   |   |   |   |   |   |
5
   +---+---+---+---+---+---+---+---+---+---+
6
     ^   ^
7
     |   | 
8
     |  Variable 1
9
   Variable 2

wenn du eine Funktion aufrufst, die lokale Variablen hat, dann müssen 
die ja dynamisch erzeugt werden, weil es sie ja nur während der 
Ausführung der Funktion gibt. Die werden sukzessive vom rechten Rand des 
Speichers aus allokiert
1
void foo()
2
{
3
  int lokalVariable1;
4
  int lokalVariable2;
5
}
6
7
                                  lokalVariable2
8
                                     | lokalVariable1
9
                                     |   |
10
                                     v   v
11
   +---+---+---+---+---+---+---+---+---+---+
12
   |   |   |   |   |   |   |   |   |   |   |
13
   +---+---+---+---+---+---+---+---+---+---+
14
     ^   ^                           
15
     |   |                           
16
     |  Variable 1                   
17
   Variable 2

wird die Funktion verlassen, dann wird am rechten Rand des SPeichers 
wieder freigegeben.
Aber: Wenn deine lokalen Variablen zu groß sind, dann wachsen die immer 
weiter nach links. Bis es dann eben irgendwann mal kracht, weil die 
allokierten lokalen Variablen denselben Speicher erreicht haben, der 
auch für die globalen Variablen benutzt wird.
1
void foo()
2
{
3
  int lokalVariable1;
4
  int lokalVariable2;
5
  int lV3;
6
  int lV4;
7
  int lV5;
8
  int lV6;
9
  int lV7;
10
  int lV8;
11
  int lV9;
12
}
13
14
                                  lokalVariable2
15
        lV9 lV8 lV7 lV6 lV5 lV4 lV3  | lokalVariable1
16
         |   |   |   |   |   |   |   |   |
17
         v   v   v   v   v   v   v   v   v
18
   +---+---+---+---+---+---+---+---+---+---+
19
   |   |   |   |   |   |   |   |   |   |   |
20
   +---+---+---+---+---+---+---+---+---+---+
21
     ^   ^                           
22
     |   |                           
23
     |  Variable 1                   
24
   Variable 2

schreibst du etwas an lV9, dann veränderst du auch 'Variable1', weil die 
in denselben Speicherzellen hausen.

Und genau das ist dein Problem. Bei dir kracht es, weil das Array zu 
groß ist.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:
> Karl Heinz schrieb:
>> Wie zeichnest du?
>> Ist das eine Formel. Vielleicht irgendwas in der Art eines Spirographen.
>
>
1
> void Blume(void)
2
> {
3
>   uint32_t Screen[102];
4
>   int16_t A,B,C,D;
5
>   uint16_t n;
6
>   uint8_t X,Y,Spalte,Zeile,i;
7
>
Also Formel.
Ich würde an deiner Stelle folgendes machen.
Ich würde mir den Code zum malen auf den PC holen. Würde mir dort ein 
Programm machen, welches das Blümchen auf dem PC berechnet und in Form 
eines bereits fertigen Bildes als C-Code abspeichert.
1
uint32_t ImagePart1[] = { 0x00000000, 0x00001000, ....
2
3
uint32_t ImagePart2[] = { 0x00000000, 0x00001000, ....
und das dann ausgeben. Der Clou an der Sache: Diese Arrays kann ich dann 
ins PROGMEM schieben und habe sie so aus dem SRAM draussen.

Und so ganz nebenbei ist dann auch noch eine Funktion auf dem Tiny 
abgefallen, mit der man Bitmaps aus dem Flash Speicher ausgeben kann :-)
Das soll ja nicht so uninteressant sein, wenn man mal anstatt eines 
Blümchens ein etwas anderes aufwendigeres Logo ausgeben will, dass sich 
mit Formeln nicht mehr beschreiben lässt.

: Bearbeitet durch User
von bal (Gast)


Lesenswert?

Und lass die PROGMEM Krücke und benutze lieber _flash, einen halbwegs 
aktuellen gcc vorrausgesetzt.

von Peter Z. (Gast)


Lesenswert?

bal schrieb:
> Und lass die PROGMEM Krücke und benutze lieber _flash,

warum ist PROGMEM eine Krücke und _flash nicht?


> einen halbwegs aktuellen gcc vorrausgesetzt.

Ich habe Atmel Studio 6.1 installiert und fertig!
Woher weiß ich ob mein gcc halbwegs aktuell ist?

von Ralf G. (ralg)


Lesenswert?

Vielleich noch zur Ergänzung der ausführlichen Erklärung von Karl Heinz
Beitrag "Re: const verändert"

Peter Zz schrieb:
> Bin unzufrieden, warum werden gerade Konstanten verändert,
> die sollten doch, wie der Name schon sagt, konstant sein.
> Es gab keine Compiler Warnung, selbst als ich das Array noch größer als
> 512 Byte gemacht habe.

Deine 'Konstante' ist keine Konstante, sondern eine mit dem 
Schlüsselwort 'const' versehene Variable. Wenn du jetzt in deinem 
Programm an dieser Variablen rumfummelst, dann warnt der Compiler! 
'const' ist also nur deine eigene Absichtserklärung, dass du die 
Variable nie ändern willst.

Wenn du das Array jetzt größer machst, dann werden die Daten dort 'noch 
viel eher' überschrieben. (Nur dass eben zufällig nichts Wichtiges 
drinsteht.) Im Programmablauf benötigen Funktionsaufrufe und Variablen 
RAM, der von den hohen Adressen absteigend bei Bedarf einkassiert und am 
Ende der Funktion wieder freigegeben wird.

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


Lesenswert?

Peter Zz schrieb:
> bal schrieb:
>> Und lass die PROGMEM Krücke und benutze lieber _flash,
>
> warum ist PROGMEM eine Krücke und _flash nicht?

__flash folgt einem Standardvorschlag für named address spaces,
während PROGMEM auf _attribute_ hinausläuft, was eine reine
GCC-Erweiterung ist.

Bei __flash handelt es sich um einen type qualifier, der vom
Compiler überprüft werden kann.  Die Benutzung von _attribute_
hingegen ist eine Art Schweizer Taschenmesser, bei dem man dem GCC
zwar einiges mit auf den Weg geben kann, aber kontrollieren kann er
das nicht.

Bei __flash kann der Compiler die normale Dereferenzierung (also
das Einsetzen der LPM-Anweisungen) selbst vornehmen, bei PROGMEM
muss man selbst dran denken, das pmg_read*-Geraffel dafür anzuwerfen.

>> einen halbwegs aktuellen gcc vorrausgesetzt.
>
> Ich habe Atmel Studio 6.1 installiert und fertig!

Auch da kann man letztlich verschiedene Toolchains drunter setzen,
wenn man will.

> Woher weiß ich ob mein gcc halbwegs aktuell ist?

Du schaust dir die Ausgabe von "avr-gcc -v" mal an.  Es sollte
mindestens ein GCC 4.7 sein (ist aber meiner Meinung nach der Fall).

von Teo D. (teoderix)


Lesenswert?

Ohne jetzt Ahnung von gcc o. AVR zu haben.

Tut das wirklich Not, das ganze in einem Array zwischen zu speichern?
Kann man die einzelnen Pixel nicht gleich ins LCD schreiben!

von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Und so ganz nebenbei ist dann auch noch eine Funktion auf dem Tiny
> abgefallen, mit der man Bitmaps aus dem Flash Speicher ausgeben kann :-)
> Das soll ja nicht so uninteressant sein, wenn man mal anstatt eines
> Blümchens ein etwas anderes aufwendigeres Logo ausgeben will, dass sich
> mit Formeln nicht mehr beschreiben lässt.
1
//*********************************************************************
2
// Auf dem LC-Display wird eine Überraschung angezeigt               //
3
// Das LCD-Display ist EA DOGS102W-6 mit 102x64 Pixel                //
4
// Der µC ist ein ATtiny84 mit 3,3V Betriebsspannung                 //
5
//*********************************************************************
6
#define F_CPU 8000000
7
#include <avr/io.h>
8
#include <avr/pgmspace.h>
9
#include <util/delay.h>
10
//*********************************************************************
11
#define LCD_SDA     PA7
12
#define LCD_SDA_0   PORTA &= ~(1 << LCD_SDA)
13
#define LCD_SDA_1   PORTA |=  (1 << LCD_SDA)
14
#define PORTA_Init  DDRA |= (1<<LCD_SDA)
15
//*********************************************************************
16
#define LCD_SCK    PB2
17
#define LCD_CD     PB1
18
#define LCD_RST    PB0
19
#define LCD_SCK_0   PORTB &= ~(1 << LCD_SCK)
20
#define LCD_SCK_1   PORTB |=  (1 << LCD_SCK)
21
#define LCD_CD_0    PORTB &= ~(1 << LCD_CD)
22
#define LCD_CD_1    PORTB |=  (1 << LCD_CD)
23
#define LCD_RST_0   PORTB &= ~(1 << LCD_RST)
24
#define LCD_RST_1   PORTB |=  (1 << LCD_RST)
25
#define PORTB_Init  DDRB |= (1<<LCD_RST)|(1<<LCD_CD)|(1<<LCD_SCK)
26
//*********************************************************************
27
enum{absolut,relativ};
28
//*********************************************************************
29
void Port_Init(void);
30
void LCD_Init(void);
31
void set_pos(uint8_t,uint8_t,uint8_t);
32
void LCD_Data(uint8_t);
33
//*********************************************************************
34
extern const uint8_t PROGMEM init_seq[];
35
extern const uint8_t PROGMEM Bild[];
36
//*********************************************************************
37
int main(void)
38
{
39
  Port_Init();
40
  LCD_Init();
41
  while(1){}
42
}
43
//*********************************************************************
44
void Port_Init(void)
45
{
46
  PORTA_Init;
47
  PORTB_Init;
48
}
49
//*********************************************************************
50
void LCD_Init()
51
{
52
  uint16_t k = 0;
53
  LCD_RST_0; _delay_ms(100);
54
  LCD_RST_1; _delay_ms(100);
55
  LCD_CD_0;
56
  for (uint8_t n=0;n < 13;n++) LCD_Data(pgm_read_byte(&init_seq[n]));
57
  LCD_CD_1;
58
  for(uint8_t line = 0;line <= 7;line++)
59
  {
60
    set_pos(line,0,absolut);
61
    if(line <= 4) for (uint8_t n = 0;n < 102;n++) LCD_Data(~pgm_read_byte(&Bild[k++]));
62
    else for (uint8_t n = 0;n < 102;n++) LCD_Data(0x00);
63
  }
64
}
65
//*********************************************************************
66
void set_pos(uint8_t wert_l,uint8_t wert_x,uint8_t modus)
67
{
68
  static uint8_t line;
69
  static uint8_t xpos;
70
  if(modus == absolut)
71
  {
72
    line = wert_l;
73
    xpos = wert_x;
74
  }
75
  if(modus == relativ)
76
  {
77
    line += wert_l;
78
    xpos += wert_x;
79
  }
80
  LCD_CD_0;
81
  LCD_Data(0xB0 + (line & 0x07)); //Set the SRAM page address PA=0..7
82
  LCD_Data((xpos + 0x1E) & 0x0F); //Set the SRAM column address CA[3..0]
83
  LCD_Data(0x10 | ((xpos + 0x1E) >> 4)); //Set the SRAM column address CA[7..4]
84
  LCD_CD_1;
85
}
86
//*********************************************************************
87
void LCD_Data(uint8_t Data)
88
{
89
  if(Data & 0x80) LCD_SDA_1; else LCD_SDA_0;
90
  LCD_SCK_0; LCD_SCK_1;
91
  if(Data & 0x40) LCD_SDA_1; else LCD_SDA_0;
92
  LCD_SCK_0; LCD_SCK_1;
93
  if(Data & 0x20) LCD_SDA_1; else LCD_SDA_0;
94
  LCD_SCK_0; LCD_SCK_1;
95
  if(Data & 0x10) LCD_SDA_1; else LCD_SDA_0;
96
  LCD_SCK_0; LCD_SCK_1;
97
  if(Data & 0x08) LCD_SDA_1; else LCD_SDA_0;
98
  LCD_SCK_0; LCD_SCK_1;
99
  if(Data & 0x04) LCD_SDA_1; else LCD_SDA_0;
100
  LCD_SCK_0; LCD_SCK_1;
101
  if(Data & 0x02) LCD_SDA_1; else LCD_SDA_0;
102
  LCD_SCK_0; LCD_SCK_1;
103
  if(Data & 0x01) LCD_SDA_1; else LCD_SDA_0;
104
  LCD_SCK_0; LCD_SCK_1;
105
}
106
//*********************************************************************
107
const unsigned char PROGMEM init_seq[13]=
108
{0x40,0xA0,0xC8,0xA4,0xA6,0xA2,0x2F,0x27,0x81,0x10,0xFA,0x90,0xAF};
109
//*********************************************************************
110
const unsigned char PROGMEM Bild[510] =
111
{
112
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
113
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
114
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
115
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x0F,0x07,0x07,0x03,0xC3,
116
  0xF1,0xF9,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
117
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
118
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
119
  0xFF,0xFF,0xF9,0xF9,0xF1,0xF0,0xE0,0xE0,0xE0,0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,
120
  0x3C,0x3C,0x18,0x18,0x38,0x38,0x70,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
121
  0xF0,0x38,0x0C,0x07,0x03,0x81,0xC1,0xF1,0xF9,0xFD,0x3F,0x1F,0x0F,0x07,0x87,0xE7,
122
  0x77,0x1F,0x0F,0x07,0x03,0xC1,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xF8,0xFE,0x7F,0x7F,
123
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
124
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x0F,0x0F,0x07,
125
  0xC7,0xE3,0xF3,0xFB,0xFB,0xFF,
126
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0xF3,0xE7,0xE7,0xC7,0xCF,0x8E,
127
  0x8E,0x0E,0x1C,0x1C,0x18,0x18,0x00,0x00,0x00,0x01,0x01,0x81,0xFF,0xFF,0x0F,0x01,
128
  0x00,0x00,0xC0,0xF0,0xF0,0xF1,0x71,0x01,0x01,0x00,0x00,0xC0,0xF8,0x1E,0x07,0x01,
129
  0x80,0x80,0x80,0x84,0x87,0x87,0x07,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,
130
  0x00,0x78,0x70,0x70,0x71,0x71,0x63,0x03,0x07,0x07,0x1F,0xFF,0xCF,0x0F,0x1F,0x3F,
131
  0x7F,0xFF,0xFF,0x7F,0x3F,0x1F,0x07,0x03,0x01,0x00,0x00,0x80,0xC0,0xF8,0xFE,0xFF,
132
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
133
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
134
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,
135
  0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xF8,0xF8,0xF8,0xF8,0xFE,0xFF,0xF1,0xF0,0xF0,0xF0,
136
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xE0,0xE0,0xE0,0xE0,0xFF,0xFF,0xF0,0xE0,0xE0,
137
  0xE0,0xE0,0xFC,0xF8,0xF0,0xE0,0xC0,0xC4,0xCC,0xDC,0xFE,0xFF,0xC7,0xC0,0xC0,0xE0,
138
  0xF8,0xF0,0x00,0x00,0x00,0x00,0x08,0x38,0xFC,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
139
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
140
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
141
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x80,0xE0,
142
  0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
143
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
144
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
145
  0xFF,0xFF,0xFC,0xE0,0xC0,0x80,0x00,0x00,0x1F,0x3F,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,
146
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
147
//*********************************************************************

von Karl H. (kbuchegg)


Lesenswert?

Teo Derix schrieb:
> Ohne jetzt Ahnung von gcc o. AVR zu haben.
>
> Tut das wirklich Not, das ganze in einem Array zwischen zu speichern?
> Kann man die einzelnen Pixel nicht gleich ins LCD schreiben!

wird wohl ein Laufzeitproblem sein.
Einzelne Pixel setzen ist meistens recht aufwändig. Da ist es schon 
einfacher erst mal in Streifen die Pixel vorab zu sammeln und dann die 
Streifen (also zb jeweils 8 übereinander liegende Pixel) in einem Rutsch 
auszugeben. Das macht dann schon einen Unterschied, ob du mit einer 
Datenübertragung zum LCD lediglich 1 Pixel oder gleich 8 in einem 
Aufwasch korrekt setzt.

Wobei man natürlich auch argumentieren könnte, dass beim Einschalten 
eines Gerätes anstatt eines Standbildes eine 'Animation' abläuft, die am 
Ende in besagter Blume resultiert und bei der die errechneten Pixel 
einfach direkt ausgegeben werden, so wie sie aus der Rechnung anfallen. 
Wer sie sehen will, der wartet. Wer sie nicht sehen will, drückt einfach 
einen Knopf und die 'Animation' wird abgebrochen.
Persönlich bin ich sowieso kein Freund derartiger 
Zwangs-Einschalt-Beglückungen. Die sehen die ersten paar mal nett aus, 
aber man sieht sich dann doch recht schnell daran satt. Mit ist lieber 
die Gerätefunktion ist durchdacht. Da kann ich dann gerne auch auf das 
eine oder andere optische Gimmick verzichten.

: Bearbeitet durch User
von Peter Z. (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Du schaust dir die Ausgabe von "avr-gcc -v" mal an.

Wo soll ich "avr-gcc -v" eingeben?

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


Lesenswert?

Peter Zz schrieb:
> Wo soll ich "avr-gcc -v" eingeben?

Auf einer Kommandozeile natürlich.  Entgegen anderslautenden Gerüchten
gibt es sowas auch bei Windows.  Allerdings wird das Atmel Studio
vermutlich den PATH nicht passend gesetzt haben; du musst dir also
vorher noch die Mühe machen, das Verzeichnis ausfindig zu machen, in
dem sich avr-gcc.exe befindet.

von Karl H. (kbuchegg)


Lesenswert?

Ich würds einfach ausprobieren.

kleines Testprogramm, erstellt mit Teilen aus dem AVR-GCC-Tutorial und 
wenn der Compiler __flash nicht anmeckert, dann wird er es wohl bereits 
kennen.

von Peter Z. (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Auf einer Kommandozeile natürlich.

Bin eben selber drauf gekommen:

Obere Leiste "Tools" dann Command Prompt wählen.
Pfade waren anscheinend richtig mein gcc ist 4.7.2

von Peter Z. (Gast)


Lesenswert?

Karl Heinz schrieb:
> kleines Testprogramm, erstellt mit Teilen aus dem AVR-GCC-Tutorial und
> wenn der Compiler __flash nicht anmeckert, dann wird er es wohl bereits
> kennen.
1
//*********************************************************************
2
void LCD_Init()
3
{
4
  static const __flash uint8_t init_seq[13] =
5
  {0x40,0xA0,0xC8,0xA4,0xA6,0xA2,0x2F,0x27,0x81,0x10,0xFA,0x90,0xAF};
6
7
  static const __flash uint8_t Bild[510] = {
8
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
9
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
10
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
11
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x1F,0x0F,0x07,0x07,0x03,0xC3,
12
  0xF1,0xF9,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
13
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
14
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
15
  0xFF,0xFF,0xF9,0xF9,0xF1,0xF0,0xE0,0xE0,0xE0,0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,
16
  0x3C,0x3C,0x18,0x18,0x38,0x38,0x70,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
17
  0xF0,0x38,0x0C,0x07,0x03,0x81,0xC1,0xF1,0xF9,0xFD,0x3F,0x1F,0x0F,0x07,0x87,0xE7,
18
  0x77,0x1F,0x0F,0x07,0x03,0xC1,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xF8,0xFE,0x7F,0x7F,
19
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
20
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x0F,0x0F,0x07,
21
  0xC7,0xE3,0xF3,0xFB,0xFB,0xFF,
22
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0xF3,0xE7,0xE7,0xC7,0xCF,0x8E,
23
  0x8E,0x0E,0x1C,0x1C,0x18,0x18,0x00,0x00,0x00,0x01,0x01,0x81,0xFF,0xFF,0x0F,0x01,
24
  0x00,0x00,0xC0,0xF0,0xF0,0xF1,0x71,0x01,0x01,0x00,0x00,0xC0,0xF8,0x1E,0x07,0x01,
25
  0x80,0x80,0x80,0x84,0x87,0x87,0x07,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,
26
  0x00,0x78,0x70,0x70,0x71,0x71,0x63,0x03,0x07,0x07,0x1F,0xFF,0xCF,0x0F,0x1F,0x3F,
27
  0x7F,0xFF,0xFF,0x7F,0x3F,0x1F,0x07,0x03,0x01,0x00,0x00,0x80,0xC0,0xF8,0xFE,0xFF,
28
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
29
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
30
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,
31
  0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xF8,0xF8,0xF8,0xF8,0xFE,0xFF,0xF1,0xF0,0xF0,0xF0,
32
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xE0,0xE0,0xE0,0xE0,0xFF,0xFF,0xF0,0xE0,0xE0,
33
  0xE0,0xE0,0xFC,0xF8,0xF0,0xE0,0xC0,0xC4,0xCC,0xDC,0xFE,0xFF,0xC7,0xC0,0xC0,0xE0,
34
  0xF8,0xF0,0x00,0x00,0x00,0x00,0x08,0x38,0xFC,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
35
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
36
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
37
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x80,0xE0,
38
  0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
39
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
40
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
41
  0xFF,0xFF,0xFC,0xE0,0xC0,0x80,0x00,0x00,0x1F,0x3F,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,
42
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
43
44
  uint16_t k = 0;
45
  LCD_RST_0; _delay_ms(100);
46
  LCD_RST_1; _delay_ms(100);
47
  LCD_CD_0;
48
  for (uint8_t n=0;n < 13;n++) LCD_Data(init_seq[n]);
49
  LCD_CD_1;
50
  for(uint8_t line = 0;line <= 7;line++)
51
  {
52
    set_pos(line,0,absolut);
53
    if(line <= 4) for (uint8_t n = 0;n < 102;n++) LCD_Data(~Bild[k++]);
54
    else for (uint8_t n = 0;n < 102;n++) LCD_Data(0x00);
55
  }
56
}
57
//*********************************************************************
klappt, aber diese ganzen Werte müssen anscheinend zuerst in der 
Funktion drin stehen?!

von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:

> klappt, aber diese ganzen Werte müssen anscheinend zuerst in der
> Funktion drin stehen?!

Was meinst du mit 'in der Funktion drinn stehen'?

Du kannst die Arrays auch global machen, oder im C-File als static 
Moduleglobale Arrays anlegen, wenn dir das besser gefällt.

Du könntest die tatsächlichen Werte auch in eine eigene Datei auslagern 
und per #include einbinden, so dasss du beim Editieren des Source Codes 
nicht jedesmal den Zahlenwust der Array Initialisierung siehst.

Aber eines ist klar: Irgendwo müssen die Werte im Code vorkommen, damit 
sie auch mitcompiliert werden.

: Bearbeitet durch User
von Schwimmbadpinkler (Gast)


Lesenswert?

Karl Heinz schrieb:
> Du kannst die Arrays auch global machen, oder im C-File als static
> Moduleglobale Arrays anlegen, wenn dir das besser gefällt.

Wie? Habt Ihr mal ein Beispiel? Das würde mich jetzt auch mal 
interessieren!

von Karl H. (kbuchegg)


Lesenswert?

Schwimmbadpinkler schrieb:
> Karl Heinz schrieb:
>> Du kannst die Arrays auch global machen, oder im C-File als static
>> Moduleglobale Arrays anlegen, wenn dir das besser gefällt.
>
> Wie? Habt Ihr mal ein Beispiel? Das würde mich jetzt auch mal
> interessieren!

Bitte!
Das steht aber nun wirklich selbst in den allerschlimmsten und 
unvollstaendigsten C Buechern drinn!Aber echt, ey.

Stichwort: was macht das Schluesselwort 'static'?

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.