ATmega16-Funktioniert dieser Code bis jetzt?

OP #2380642
Lesenswert?

hi,

Ich bin noch sehr neu in der Microcontroller Welt, wollte jetzt aber 
einfach mal versuchen einen zu programmieren. Da ich aber weder 
Programmiergerät, noch Microcontroller besitze kann ich meinen code 
leider nicht austesten :/

Es handelt sich um diesen Code(mit AVR Studio 5 für einen ATmega16 
geschrieben):
1
/*
2
 * LED_4Mode_Control.c
3
 *
4
 * Created: 13.10.2011 17:41:07
5
 *  Author: Markus
6
 */ 
7

8
#include <avr/io.h>
9

10
typedef unsigned char byte;
11

12
#define RAND_MAX   0b1000
13
int rand(void);
14

15
int main(void)
16
{
17
  
18
  byte test;
19
  
20
  
21
  
22
    while(1)
23
    {
24
        if( PINA & (1<<PINA0) )
25
    {
26
      test = rand();
27
    }
28

29
    }
30
}
derzeit sollte das programm eigentlich nur wenn an PinA0 eine Spannung 
anliegt eine zufallszahl generiert werden, und diese in der variable 
test gespeichert werden.

Ich hab wirklich fast keine Ahnung von der Materie, es wäre also toll 
wenn mir jemand sagen könnte ob ich völlig falsch liege, bzw. etwas 
vergessen habe.

danke
markus
OP #2380698
Lesenswert?

Peter II schrieb:
> Markus B. schrieb:
>> also so?
>
> nein, du brauche eine header datei wo die rand() funktion deklariert
> ist. (keien Ahnung wo das bei den AVRs ist, ich habe sie noch nie
> gebraucht). Aber das macht eh keinen Sinn weil du test überhaupt nicht
> verwendest, damit wird der code eh wegoptimiert.

rand() ist offenbar in der stdlib.h deklariert, habe aber vorher auch 
keinen fehler beim erstellen bekommen?!

hab jetzt einen testlauf ohne der bedingung gemacht, und hab bemerkt das 
zufallszahlen die größer als 7 sind generiert werden.  eigentlich wollte 
ich es einschränken durch
1
#define RAND_MAX   0b1000
wie es hier zu finden ist
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html

"#define RAND_MAX   0x7FFF

Highest number that can be generated by rand()."
Gast #2380704
Lesenswert?

Ich formuliere es mal so, wer mit uCs rumwuseln will, sollte gute 
Kenntnisse in C habe. Die Reihenfolge lautet C lernen, uCs verstehen und 
denn uCs programmieren. Der Irrglaube mit uCs C zu lernen ist totaler 
Blödsinn.

Also die Reihenfolge ist:

1. Grundlagen von C können.
2. Wissen wie uCs funktionieren bzw. aufgebaut sind und warum ein uCs 
nicht die gleichen Eigenschafen hat wie der PC, vor dem man sitzt.
Andere Frage, was sind die Unterschiede und wie müssen sie bei der 
Programmierung berücksichtigt werden.

Wenn 1. und 2. vorhanden sind, dann kann man sich an Schritt 3. wagen.
3. "echtes" Programmieren von uCs. Das bedeutet, dass ich mich nicht 
durch die Programmierung durchraten muss, da ich weiss, was ich mache.
OP #2380707
Lesenswert?

Peter II schrieb:
> Markus B. schrieb:
>> "#define RAND_MAX   0x7FFF
>
> das wird wohl fest einkompiliert sein, vermutlich kann man es nicht
> ändern ohne das man die lib selber baut.

und wenn ich dannach noch durch 32 rechne? damit könnte ich es doch auch 
einschränken?!

EDIT:
Wie schaffe ich es dann den PINDtest(also z.B. PIND5) als ausgang zu 
setzten?
danke für die ganzen antworten :)
OP #2380738
Lesenswert?

ich schrieb:
> Ich formuliere es mal so, wer mit uCs rumwuseln will, sollte gute
> Kenntnisse in C habe. Die Reihenfolge lautet C lernen, uCs verstehen und
> denn uCs programmieren. Der Irrglaube mit uCs C zu lernen ist totaler
> Blödsinn.
>
> Also die Reihenfolge ist:
>
> 1. Grundlagen von C können.
> 2. Wissen wie uCs funktionieren bzw. aufgebaut sind und warum ein uCs
> nicht die gleichen Eigenschafen hat wie der PC, vor dem man sitzt.
> Andere Frage, was sind die Unterschiede und wie müssen sie bei der
> Programmierung berücksichtigt werden.
>
> Wenn 1. und 2. vorhanden sind, dann kann man sich an Schritt 3. wagen.
> 3. "echtes" Programmieren von uCs. Das bedeutet, dass ich mich nicht
> durch die Programmierung durchraten muss, da ich weiss, was ich mache.

also C lerne ich jetzt seit einem Schuljahr. 
Mircocontrollerprogrammierung erlerne ich jetzt seit diesem 
Schuljahr(jedoch nur jeweils 2h/14 Tage)
Ich hab auch schon versucht einige Tutorials zu uCs zu lesen, bzw. zu 
verstehen, diese habe ich aber leider nur teilweise verstanden und auch 
nur wenige Anfängerfreundliche Beispiele gefunden(und wenn auch nur der 
reine Programmcode ohne einen dazu passenden Schaltplan)
#2380924
Lesenswert?

Markus B. schrieb:
> Peter II schrieb:
>> Markus B. schrieb:
>>> also so?
>>
>> nein, du brauche eine header datei wo die rand() funktion deklariert
>> ist. (keien Ahnung wo das bei den AVRs ist, ich habe sie noch nie
>> gebraucht). Aber das macht eh keinen Sinn weil du test überhaupt nicht
>> verwendest, damit wird der code eh wegoptimiert.
>
> rand() ist offenbar in der stdlib.h deklariert, habe aber vorher auch
> keinen fehler beim erstellen bekommen?!
>
> hab jetzt einen testlauf ohne der bedingung gemacht, und hab bemerkt das
> zufallszahlen die größer als 7 sind generiert werden.  eigentlich wollte
> ich es einschränken durch
>
1
> #define RAND_MAX   0b1000
2
>
> wie es hier zu finden ist
> http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html
>
> "#define RAND_MAX   0x7FFF
>
> Highest number that can be generated by rand()."

dann macht ein "C" Programmierer...
1
test = rand() % RAND_MAX;
oder, wenn RAND_MAX eine 2er Potenz ist
1
test = rand() & (RAND_MAX-1);
Der Compiler macht warscheinlich den gleichen Binärcode daraus.
OP #2389440
Lesenswert?

ich hab jetzt ein wenig mehr gelernt und selbst weiterhin versucht das 
programm zu schreiben.
Die Fragen stehen in den Kommentaren, Danke im Voraus :)
1
/*
2
 * LED_4Mode_Control.c
3
 *
4
 * Created: 13.10.2011 17:41:07
5
 *  Author: Markus
6
 */ 
7

8
#include <stdlib.h>
9
#include <avr/io.h>
10
#include <util/delay_basic.h>
11

12
typedef unsigned char byte;
13

14

15
void wait(byte hsec);
16

17
int main(void)
18
{
19
  
20
  byte zufall;
21
  
22
  //PIN => PORT abfragen
23
  
24
  
25
  DDRD = 0xFF;  //PORTD als AUSGANG setzten
26
  DDRA = 0x00;  //PORTA als EINGANG setzten
27
  PORTD = 0x00;  //PORTD Ausgänge AUSSCHALTEN
28
  
29
  
30
  
31
    while(1)
32
    {
33

34
        if(PINA & (1<<PINA0)) //Zufallsausgabe
35
/* Wenn eine Spannung an PINA0 anliegt soll eine Zufallszahl zw. 0 und 7 generiert werden, und dannach der generierte PORTDx aktiviert werden, funktioniert das?*/
36
    {
37
    PORTD = 0x00;
38
    
39
    zufall = (rand() & (255))/32;
40
    
41
    zufall;
42
    PORTD |= (1 << zufall);
43
    wait(50);
44
    
45
    PORTD = 0x00;
46
    
47
    }
48
    if(PINA & (1<<PINA1) ) //genaue Reihenfolge
49
/* Wenn eine Spannung an PINA1 anliegt soll eine genaue Reihenfolge, wie eine Art Lauflicht gestartet werden, Funzt das so?*/
50
    {
51
    PORTD = 0x00;
52
    PORTD = 0b00000001;
53
    wait(500);
54
    PORTD = 0b00000010;
55
    wait(500);
56
    PORTD = 0b00000100;
57
    wait(500);
58
    PORTD = 0b00001000;
59
    wait(500);
60
    PORTD = 0b00010000;
61
    wait(500);
62
    PORTD = 0b00100000;
63
    wait(500);
64
    PORTD = 0b01000000;
65
    wait(500);
66
    PORTD = 0b10000000;
67
    wait(500);
68
    PORTD = 0x00;
69
    }  
70
  
71
    if(PINA & (1<<PINA2) ) /*Blinken, Alles aus, Alles ein, funktioiert das so? */
72
    {  
73
      PORTD = 0x00;
74
      PORTD = 0xFF;
75
      wait(20);
76
      PORTD = 0x00;
77
      wait(20);
78

79
    }
80
  }    
81
}
82

83
void wait(byte hsec)//F = 1MHz
84
{
85
  
86
  byte i;
87
  for(;hsec;hsec--)
88
  {
89
    for(i = 20; i; i--) //10ms
90
    {
91
      
92
      _delay_loop_1(167); //500 μs
93
      
94
    }
95
  }
96
}

nochmals danke
markus
Persönliche Seite #2389554
Lesenswert?

Werner B. schrieb:
> Markus B. schrieb:
>> hab jetzt einen testlauf ohne der bedingung gemacht, und hab bemerkt das
>> zufallszahlen die größer als 7 sind generiert werden.  eigentlich wollte
>> ich es einschränken durch
1
>> #define RAND_MAX   0b1000
>> wie es hier zu finden ist
>> http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html
>>
>> "#define RAND_MAX   0x7FFF
>>
>> Highest number that can be generated by rand()."

RAND_MAX hat *rein* informativen Character.

> dann macht ein "C" Programmierer...
1
> test = rand() % RAND_MAX;
Dies ist bereits durch rand sichergestellt, d.h. es gilt
1
unsigned int r = rand();
2
if (r == r % ((unsigned) RAND_MAX+1))
3
{
4
    // Ist *immer* erfüllt
5
}
6
else
7
{
8
    // Ist *nie* erfüllt
9
}
Persönliche Seite #2389655
Lesenswert?

rand liefert ganze Zahlen von 0 bis 0x7fff = 32767.

Wenn du kleinere Zahlen wie 0...N brauchst geht das per
1
int i = rand() % (N+1);
Vorteil: Leicht zu berechnen, insbesondere wenn N+1 2er Potenz ist.
Nachteil: Die Werte sind nur dann gleichverteilt,  wenn N+1 ein Teiler 
von RAND_MAX+1 ist.
1
unsigned int i;
2
do
3
{
4
    i = rand();
5
} while (i >= N+1);
hat den Nachteil, daß es ineffizient ist, keine Mindestlaufzeit 
angegeben werden kann. Vorteil: gleichverteilte Werte (unter der 
Voraussetzung, daß rand gleichverteilt isr).

Dies lässt sich etwas effizienter machen mit
1
unsigned int i;
2
do
3
{
4
    i = rand();
5
} while (i >= K*(N+1));
6
i = i % (N+1);
für eine geeignete Konstante K, zB:
allerdings bleibt das grundlegende Problem der Schleife bestehen.
Gast #2389713
Lesenswert?

Johann L. schrieb:
> Nachteil: Die Werte sind nur dann gleichverteilt,  wenn N+1 ein Teiler
> von RAND_MAX+1 ist.

Auch dann nicht unbedingt, da bei den für diese Funktion häufig 
verwendeten Zufallsgeneratoren die Verteilung der unteren Bits nicht so 
gut ist wie die der oberen Bits. Daher wird auch gerne die Division 
statt Modulo verwendet.

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