PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : pgmspace wirkt nicht



Christoph2
22.04.2013, 20:55
Hi,

ich habe hier ein sehr kurzes Programm - es macht nur eine AD Wandlung von einem Poti und gibt das Ergebnis als 8 Bit PWM aus. Das PWM Signal nutze ich, um eine Led zu dimmen. Das funktioniert alles super.

Jetzt wollte ich das ganze aber noch an das menschliche Auge anpassen, also exponentiell ansteigen lassen. Dazu habe ich eine Tabelle mit 256 Werten (uint8_t) gemacht, die die Exponentiell steigenden Werte enthält. Beim Zugriff auf das Array wird als Index einfach der AD gewandelte Wert des Potts (umgerechnet auf 8 Bit) verwendet.

Leider hat mein ATtiny13A nur 64 Byte Speicher für Variablen, aber dafür 1kByte Programmspeicher. Das Programm braucht nur 400 Byte, also würde sich das Array, das 256 Byte braucht, im Programmspeicher noch ausgehen.

Aber ich schaffe es nicht, dem Compiler beizubringen, dass er es dahin speichern soll. Er schreibt es immer in den 64 Byte Speicher...
Ich habe pgmspace.h includiert, das Schlüsselwort PROGMEM verwendet, und zugreifen tue ich über pgm_read_byte.

Hier ist der Code:



#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include "leddimmer_avr_software.h"
#include "tiny_pwm.h"


int main(void)
{
uint16_t wert=0;
uint8_t wert8=0;
uint8_t logvalue=0;

const uint8_t pwmtable[] PROGMEM = {
0,10,10,10,10,11,11,11,11,11,11,11,12,12,12,12,12, 12,12,13,13,13,13,13,13,14,14,14,14,14,14,15,15,15 ,15,15,16,16,16,16,16,17,17,17,17,18,18,18,18,18,1 9,19,19,19,20,20,20,20,21,21,21,21,22,22,22,23,23, 23,23,24,24,24,25,25,25,26,26,26,27,27,27,28,28,28 ,29,29,30,30,30,31,31,32,32,32,33,33,34,34,34,35,3 5,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43, 44,44,45,46,46,47,47,48,49,49,50,50,51,52,52,53,54 ,55,55,56,57,57,58,59,60,60,61,62,63,64,64,65,66,6 7,68,69,69,70,71,72,73,74,75,76,77,78,79,80,81,82, 83,84,85,86,87,88,90,91,92,93,94,96,97,98,99,101,1 02,103,104,106,107,109,110,111,113,114,116,117,119 ,120,122,123,125,126,128,130,131,133,135,137,138,1 40,142,144,146,147,149,151,153,155,157,159,161,163 ,165,167,170,172,174,176,178,181,183,185,188,190,1 93,195,198,200,203,205,208,211,213,216,219,222,224 ,227,230,233,236,239,242,245,249,252,255
};

DDRB |= (1<<0); // PWM PIN
DDRB &= ~(1<<4); // ADC PIN

adc_config();
pwm_init();

while(1)
{
_delay_ms(10);
wert=adc(2)>>2;

if(wert<2) wert8=(uint8_t)0;
if(wert>253) wert8=(uint8_t)255;
else wert8= (uint8_t)wert;

logvalue = (uint8_t) pgm_read_byte(&pwmtable[wert8]);

pwm(logvalue);

}
}


Beim Compilieren schreibt er die beiden Fehlermeldungen:
in extract insn, at recog.c:2109
unrecognizable insn:

Wenn ich das Array kleiner mache, z.B. 10 Werte, compiliert er ohne Fehler.
Vergrößere ich es schrittweise, kann ich beobachten wie der Variablenspeicher immer voller wird (das zeigt er ja beim compilieren an), der Programmspeicher aber immer gleich voll bleibt.
Wenn er dann bei 100% ist, kommen wieder die Fehlermeldungen...

Findet ihr einen Fehler?

lg
Christoph

markusj
22.04.2013, 21:19
PROGMEM funktioniert nur bei globalen oder statischen Variablen. Mit -Wall bekommst du vom Compiler auch folgende Meldung: "warning: ‘__progmem__’ attribute ignored"

Also: Entweder static const uint8_t etc. oder das ganze als globale "Variable" anlegen. Vermutlich ist letztere Variante schöner.

mfG
Markus