Forum: Mikrocontroller und Digitale Elektronik Wo die Daten speichern?


von Knalltöner (Gast)


Lesenswert?

Seit ich in meinem Programm für den ATtiny25 eine etwas größere Tabelle 
mit 1364 Eintragen habe geht nix mehr:
1
const unsigned char My_data[]={
2
0x7E,0x78,0x78,0x79,0x7B,0x7D,0x78,0x78,
3
0x7F,0x7D,0x7D,0x77,0x6D,0x6A,0x68,0x6E,
4
// usw.
5
0x79,0x79,0x7A,0x7A,0x7A,0x7B,0x7B,0x7B,
6
0x7C,0x7C,0x7D,0x7D,0x7D,0x7E,0x7E,0x7F,
7
0x7F,0x80,0x80,0x80
8
};
Das sollte eigentlich noch in den ATtiny25 reinpassen...
Ich bekomme (AVR Studio) die Meldungen:

Program: 1650 bytes (80.6% Full)
(.text + .data + .bootloader)

Data:    1365 bytes (1066.4% Full)
(.data + .bss + .noinit)

Build succeeded with 0 Warnings...

Die 1066% lassen mich stutzig werden, aber was tun?

von holger (Gast)


Lesenswert?

>Die 1066% lassen mich stutzig werden, aber was tun?

data ist RAM. Also PROGMEM draus machen;)

von Tim (Gast)


Lesenswert?

Die Daten werden bei dir im RAM abgelegt.
Und soviel hat der kleine nicht.
Lies mal:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

von Andreas F. (aferber)


Lesenswert?

So wie du deine Tabelle definierst wird diese vom Compiler ins RAM 
gepackt. Der Startup-Code kopiert die Initialisierungsdaten dann aus dem 
Flash ins RAM.

Das RAM ist bei dir nur 128 Byte gross. 1365/128=1066%.

Informationen dazu, wie du deine Tabelle im Flash lassen kannst, findest 
du hier: http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

Andreas

von Knalltöner (Gast)


Lesenswert?

Danke, jetzt klappt es, fast ...  :-(
1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
3
4
void PWM_Pulse(unsigned char);
5
const unsigned char My_sin[] PROGMEM ={
6
0x80,0x81,0x81,0x82,0x82,0x83,0x83,0x84,
7
0x85,0x85,0x86,0x86,0x87,0x87,0x88,0x89,
8
//usw.
9
0x75,0x75,0x76,0x76,0x77,0x78,0x78,0x79,
10
0x79,0x7A,0x7A,0x7B,0x7C,0x7C,0x7D,0x7D,
11
0x7E,0x7E,0x7F,0x80,
12
};
13
int main(void)
14
{
15
  DDRB  = (1 << DDB4);  // PB4=Pin3 als Output
16
  PORTB =  0;
17
18
  while(1)
19
  {
20
    unsigned short int n;
21
    unsigned char x;
22
    for(n=0;n<1364;n++) 
23
    {
24
      x = My_sin[n];
25
      PWM_Pulse(x);
26
    }
27
  }
28
}
Habe den PWM auf einen Lautsprecher gegeben, ist nur ein rytmisches 
Kratzen zu hören.
Habe die PWM (24,5kHz) auf einen Tiefpaß mit 10k & 10nF gegeben,
auf dem Oszilloskop sind nur kratzige Kurven zu sehen, nix mit Sinus.
Irgendwie greife ich falsch auf die Tabelle zu?!

von holger (Gast)


Lesenswert?

>      x = My_sin[n];

Da musst du pgm_read_byte() benutzen;)
Deine Tabelle liegt ja jetzt im Flash.

von Flo (Gast)


Lesenswert?

Was macht PWM_Pulse genau? also Code zeigen?

von Knalltöner (Gast)


Lesenswert?

holger schrieb:
> Da musst du pgm_read_byte() benutzen;)
> Deine Tabelle liegt ja jetzt im Flash.

Jetzt geht's JIPPIE
1
      for(n=0;n<1364;n++) 
2
      {
3
        x =  pgm_read_byte(&(My_sin[n]));
4
        PWM_Pulse(x);
5
      }
Besten Dank holger!   :-)

von Knalltöner (Gast)


Lesenswert?

Flo schrieb:
> Was macht PWM_Pulse genau? also Code zeigen?
Leider kann ich mich nicht verschließen, dieser höflich vorgebrachten 
Bitte Folge zu leisten:
1
//***********************************************
2
void PWM_Pulse(unsigned char Zeit_high)
3
{
4
  unsigned char Zeit_low = ~Zeit_high;
5
6
  PINB = (1 << PIN4);  // Portleitung toggeln => high
7
  switch(Zeit_high & 0b00000111)
8
  {
9
    case 7:  asm volatile("NOP");
10
    case 6:  asm volatile("NOP");
11
    case 5:  asm volatile("NOP");
12
    case 4:  asm volatile("NOP");
13
    case 3:  asm volatile("NOP");
14
    case 2:  asm volatile("NOP");
15
    case 1:  asm volatile("NOP");
16
    case 0:  asm volatile("NOP");
17
  }
18
  Zeit_high >>= 3;
19
  while(Zeit_high > 0)
20
  {
21
    asm volatile("NOP");//1
22
    asm volatile("NOP");//2
23
    asm volatile("NOP");//3
24
    asm volatile("NOP");//4
25
    Zeit_high--;
26
  }
27
28
  PINB = (1 << PIN4);  // Portleitung toggeln => low
29
  switch(Zeit_low & 0b00000111)
30
  {
31
    case 7:  asm volatile("NOP");
32
    case 6:  asm volatile("NOP");
33
    case 5:  asm volatile("NOP");
34
    case 4:  asm volatile("NOP");
35
    case 3:  asm volatile("NOP");
36
    case 2:  asm volatile("NOP");
37
    case 1:  asm volatile("NOP");
38
    case 0:  asm volatile("NOP");
39
  }
40
  Zeit_low >>= 3;
41
  while(Zeit_low > 0)
42
  {
43
    asm volatile("NOP");//1
44
    asm volatile("NOP");//2
45
    asm volatile("NOP");//3
46
    asm volatile("NOP");//4
47
    Zeit_low--;
48
  }
49
}
50
//***********************************************
Das geht mit Timer & Interrupt sicher besser & eleganter.
Falls also jemand meint, da was besseres zu haben, so sei ihm 
freigestellt, den Code hier doch zum Gefallen aller zu posten!

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.