www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wo die Daten speichern?


Autor: Knalltöner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seit ich in meinem Programm für den ATtiny25 eine etwas größere Tabelle 
mit 1364 Eintragen habe geht nix mehr:
const unsigned char My_data[]={
0x7E,0x78,0x78,0x79,0x7B,0x7D,0x78,0x78,
0x7F,0x7D,0x7D,0x77,0x6D,0x6A,0x68,0x6E,
// usw.
0x79,0x79,0x7A,0x7A,0x7A,0x7B,0x7B,0x7B,
0x7C,0x7C,0x7D,0x7D,0x7D,0x7E,0x7E,0x7F,
0x7F,0x80,0x80,0x80
};
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?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Die 1066% lassen mich stutzig werden, aber was tun?

data ist RAM. Also PROGMEM draus machen;)

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Daten werden bei dir im RAM abgelegt.
Und soviel hat der kleine nicht.
Lies mal:
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Knalltöner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, jetzt klappt es, fast ...  :-(
#include <avr/io.h>
#include <avr/pgmspace.h>

void PWM_Pulse(unsigned char);
const unsigned char My_sin[] PROGMEM ={
0x80,0x81,0x81,0x82,0x82,0x83,0x83,0x84,
0x85,0x85,0x86,0x86,0x87,0x87,0x88,0x89,
//usw.
0x75,0x75,0x76,0x76,0x77,0x78,0x78,0x79,
0x79,0x7A,0x7A,0x7B,0x7C,0x7C,0x7D,0x7D,
0x7E,0x7E,0x7F,0x80,
};
int main(void)
{
  DDRB  = (1 << DDB4);  // PB4=Pin3 als Output
  PORTB =  0;

  while(1)
  {
    unsigned short int n;
    unsigned char x;
    for(n=0;n<1364;n++) 
    {
      x = My_sin[n];
      PWM_Pulse(x);
    }
  }
}
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?!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>      x = My_sin[n];

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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was macht PWM_Pulse genau? also Code zeigen?

Autor: Knalltöner (Gast)
Datum:

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

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

Autor: Knalltöner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
//***********************************************
void PWM_Pulse(unsigned char Zeit_high)
{
  unsigned char Zeit_low = ~Zeit_high;

  PINB = (1 << PIN4);  // Portleitung toggeln => high
  switch(Zeit_high & 0b00000111)
  {
    case 7:  asm volatile("NOP");
    case 6:  asm volatile("NOP");
    case 5:  asm volatile("NOP");
    case 4:  asm volatile("NOP");
    case 3:  asm volatile("NOP");
    case 2:  asm volatile("NOP");
    case 1:  asm volatile("NOP");
    case 0:  asm volatile("NOP");
  }
  Zeit_high >>= 3;
  while(Zeit_high > 0)
  {
    asm volatile("NOP");//1
    asm volatile("NOP");//2
    asm volatile("NOP");//3
    asm volatile("NOP");//4
    Zeit_high--;
  }

  PINB = (1 << PIN4);  // Portleitung toggeln => low
  switch(Zeit_low & 0b00000111)
  {
    case 7:  asm volatile("NOP");
    case 6:  asm volatile("NOP");
    case 5:  asm volatile("NOP");
    case 4:  asm volatile("NOP");
    case 3:  asm volatile("NOP");
    case 2:  asm volatile("NOP");
    case 1:  asm volatile("NOP");
    case 0:  asm volatile("NOP");
  }
  Zeit_low >>= 3;
  while(Zeit_low > 0)
  {
    asm volatile("NOP");//1
    asm volatile("NOP");//2
    asm volatile("NOP");//3
    asm volatile("NOP");//4
    Zeit_low--;
  }
}
//***********************************************
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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.