Zufallszahlen & Watch-Window (AVR-Studio)

Gast #1514762
Lesenswert?

Hallo zusammen!

Folgende Situation bei mir...hab ein STK500 mit Tiny13, funktioniert 
alles prima bisher. Hier gleich eine kleine Frage am Rande: Hab 
folgendes Programm:
1
#include <avr/io.h> 
2
#include <stdint.h>
3
#include <avr/delay.h> 
4
#include <stdlib.h>
5
 
6
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin) //Tasterentprellung
7
{
8
    if ( ! (*port & (1 << pin)) )
9
    {
10
        /* Pin wurde auf Masse gezogen, 100ms warten   */
11
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
12
        _delay_ms(50); 
13
        if ( *port & (1 << pin) )
14
        {
15
            /* Anwender Zeit zum Loslassen des Tasters geben */
16
            _delay_ms(50);
17
            _delay_ms(50); 
18
            return 1;
19
        }
20
    }
21
    return 0;
22
}
23

24
unsigned short get_seed() //Startwert für rand() erzeugen
25
{
26
   unsigned short seed = 0;
27
   unsigned short *p = (unsigned short*) (RAMEND+1);
28
   extern unsigned short __heap_start;
29
    
30
   while (p >= &__heap_start + 1)
31
      seed ^= * (--p);
32
    
33
   return seed;
34
}
35

36

37
int main (void)
38
{            
39
  DDRB = 0b001111; //PB4 als Eingang, PB0-3 als Ausgang
40

41
  PORTB &= ~ ((1<<PB2) | (1<<PB3)); // PB2 und 3 einschalten
42
  PORTB |= (1<<PB0) | (1<<PB4); // PB0 ausschalten, PB4 internen Pull-up deaktivieren
43

44
  uint16_t zufall;
45
  
46
  while(1)
47
  {
48
    if (debounce(&PINB, PB4))   
49
    {
50
      PORTB = PINB ^ (1<<PB1) ^ (1<<PB0);
51
      srand(get_seed());
52
      zufall = rand();  
53
    }
54
  }                       
55
  return 0;                 
56
}
Hab mit diesem Programm schon 63% des Programmspeichers vom ATtiny13 
verbraucht, hätte echt nicht gedacht, dass der so schnell voll wird. Und 
dazu meine Frage: wirken sich die inkludierten Header-Files auf die 
Größe des Programms aus oder werden nur die benötigten Funktionen am µC 
gespeichert? Das würde ja irgendwie erklären warum dieses Miniprogramm 
schon so viel Platz benötigt...

Aber jetzt zur richtigen Frage. Will letztlich mit diesem µC einen 
Würfel ansteueren. Hab mich über die Erzeugung von Zufallszahlen schon 
ausreichend informiert und mich letztendlich für die Variante mit dem 
SRAM entschieden, da sie für diese Anwendung vollkommen ausreicht. Wie 
kann ich jetzt
1) den Zufallszahlenbreich auf 1-6 eingrenzen und
2) wenn ich im Watch-Window im AVR-Studio die Variable "zufall" ansehen 
will, steht bei Value immer nur "Location not valid". Was ist hier 
falsch?

Zu 1) Wäre das eine Möglichkeit?
1
int zufallszahl ()
2
{
3
  int x;
4

5
  while( (x = rand()) >= RAND_MAX - (RAND_MAX % 6) )
6
    ; 
7
  return x % 6;
8
}

Danke schon mal,
Lg Andi
#1514809
Lesenswert?

Zu 1): Nach langem Nachdenken bin ich zur Überzeugung gekommen, dass 
dieser Code wahrscheinlich sehr schlau ist. Ich hätte nie daran gedacht, 
dass es nicht gleich viele Zufallszahlen kongruent zu 0,1,2,3,4,5 gibt, 
wenn RAND_MAX kein Vielfaches von 6 ist. Aber wenn der 
Zufallszahlengenerator so gut ist, wie die halt normalerweise so sind, 
dann ist dass auch nur Zuckerguss auf einem Sandkuchen. Allerdings gibst 
Du einen int zurück, wo ein uint16 erwartet wird und ein uint8 reichen 
würde. Das ist unordentlich.

Zu 2): Das kann ich beantworten: Die Variable wurde wegoptimiert, weil 
sie nur beschrieben und nie gelesen wurde.

Aber warum verwendest Du überhaupt rand() aus der stdlib? Hast Du 
Zugriff auf die Numerical Recipes? Da gibt's doch sicherlich einen 
10-Zeiler, der gut genug ist für einen Würfel. Ich nehme mal an, dass 
sich dann auch Dein Speicherverbrauch besser in den Griff bekommen 
lässt.
#1514841
Lesenswert?

Und solltest du bei rand() bleiben dann zieh den Aufruf der srand vor 
die while Schleife.

Zufallszahlengeneratoren funktionieren nur dann vernünftig, wenn man sie 
in Ruhe arbeiten lässt. Den ersten Seed gibt man vor (ev. in irgendeiner 
Form von einer Benutzeraktion abhängig) und dann lässt man den Seed 
tunlichst in Ruhe! Nur so kann der Generator seine Normalverteilung 
(oder was er sonst für eine Verteilung hat) aufbauen.
Gast #1514843
Lesenswert?

Also sollte "zufall" als uint8_t und nicht als uint16_t definiert sein, 
um es sauber zu machen?

Naja, aus den Numerical Recipes werd ich nicht schlau, aber diese 
Variante des Zufallsgenerators ist eh schon recht kurz. Wie könnte ich 
den am einfachsten diese Zufallszahl einfach an Port B mit 4 Leds 
(einfach in BCD Code) ausgeben?
Gast #1514848
Lesenswert?

Das hatte ich ganz vergessen dass das srand() aus der Schleife raus 
gehört. Ich hab jetzt einfach mal ganz plump PORTB = zufall; 
geschrieben, so sehe ich in der Simulation, dass sich bei jedem 
Tastendruck dann an Port B etwas ändert, also dass sollte dann schon mal 
funktionieren. Jetzt fehlt nur noch die Eingrenzung auf 1 bis 6.
#1514851
Lesenswert?

Andreas Brunner schrieb:
> Das hatte ich ganz vergessen dass das srand() aus der Schleife raus
> gehört. Ich hab jetzt einfach mal ganz plump PORTB = zufall;
> geschrieben, so sehe ich in der Simulation, dass sich bei jedem
> Tastendruck dann an Port B etwas ändert, also dass sollte dann schon mal
> funktionieren. Jetzt fehlt nur noch die Eingrenzung auf 1 bis 6.

Deine Funktion zufallszahl() macht das schon.
Die macht das sogar sehr gut.
#1514878
Lesenswert?

Andreas Brunner schrieb:
> Scheint zu funktionieren. Mein Problem ist jetzt wie gesagt die Ausgabe
> über die vier Leds...

Versteh ich nicht.
Das ist doch der leichteste Teil der Übung.
Einfach an den Port rausgeben, so wie du das schon gemacht hast.

   PORTB = zufall | ( 1 << PB4 );  // damit der Pullup nicht flöten geht
Gast #1514892
Lesenswert?

Achso, na dann scheint es doch eh irgendwie zu stimmen ^^ Aber auch eben 
nur irgendwie, denn die Leds sind wenn ich mich richtig entsinne 
active-Low, also hab ich mal geschaut, welche Werte da mit den Leds zu 
Tage kommen, und habe festgestellt, dass 6 nicht vorkommt. Es war nur 
0-5 zu sehen...hab ich doch glatt das "+1" bei der Berechnung vergessen. 
Jetzt scheint der Generator fertig zu sein!

Alles weitere wird hoffentlich kein Problem mehr...und braucht auch 
hoffentlich nicht mehr zu viel Speicherplatz ^^

Danke für die Hilfe,
Lg Andi

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