Mikrokontroller in C++ programmieren: Zufallsgenerator mit LED-Anzeige

Nordmende

Semiprofi
Thread Starter
Mitglied seit
03.05.2006
Beiträge
2.054
Ort
Terra Incognita
Hallo !

In der Schule programmieren wir zurzeit einen Atmel Atmega16 Mikrokontroller.

Dieser soll, sobald ein Knopf gedrückt wird und wieder los gelassen wird, eine zufällige Zahl von 1 bis 6 ausgeben.

Hier unser Code:

Code:
#include <inttypes.h>
#include <avr/io.h>

int main(void)
{
    uint8_t   led; 
    uint8_t   keys;
   

    DDRB  = 0xff;                  // use all pins on PortB for output 
    DDRD  = 0x00;                  // use all pins on port D for input
    
    PORTD = 0xff;                  // activate internal pull-up
    PORTB = 0xff;                  // set output high -> turn all LEDs off
    
    for (;;) {                     // loop forever   
        keys = ~PIND;              // read input port with switches (active-low)
         

        if ( keys & 1 )
		    {
            led = 164;      // Zahl 1
                    }

       else if ( keys & 1 )
		    {
            led = 148;      // Zahl 2
                    }

       else if ( keys & 1 )
		    {
            led = 210;      // Zahl 3
                    }
	     
	else	if ( keys & 1 )
		    {
            led = 152;     // Zahl 4
                    }
	    
	else	if ( keys & 1 )
		    {
            led = 136;     // Zahl 5
                    }

	else	if ( keys & 1 )
		    {
            led = 215;     // Zahl 6
	            }

    else led=0              // Alle Segmente Leuchten, Zahl 8
           
			PORTB = ~led;            Set corresponding LED if switch pressed
    }
}

Wenn jetzt die Taste gedrückt wird, zeigt die 7-Segment-LED Anzeige alle Segmente an, es leuchtet also eine 8 mit dem Punkt unten.

Unser Problem ist jetzt aber: Sobald die taste losgelassen wird, wird immer die Zahl 2 angezeigt und an diesem Punkt kommen wir nicht weiter :shake:
Weiß einer von euch Rat ?
 
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Hallo

ich habe das Program jetzt nicht genau analysiert und kenne auch deine Schaltung nicht. Wohl habe ich aber mit diesen Controllern programmiert...du mußt auf jeden Fall ne kleine Verzögerung reinbauen ... oder eine loop_until_bit_is_set schleife...also die Quasi den Code Unterbricht...wartet bis die Taste losgelasen wird und erst denn weiter macht.
Außerdem würde ich nicht den kompletten Port einlesen sondern nur das was brauchst bzw. es durch ne Bitmaske jagen sonst bekommst da evtl. Infos die alles verfälschen.
Bei WinAvr gibt es auch ein Simulator der dir vielleicht auch klarheit verschafft.

Edit: jetzt habe ich es mir nochmal genau angeschaut ... du willst ja Zufallszahl haben ;) aber dennoch du mußt warten und den code zumindest kurz unterbrechen lassen damit er die Anzeige in Ruhe anzeigen kann...sonst flimmert das ja alles. Die If Abfrage ist glaube in dem Fall einfach nicht ideal die kann nur ein Ergebniss liefern :d ... weil nur einmal eingelesen wird und der Wert ja nur 1 oder eben 0 sein kann...das heißt es wird nur die erste Bedingung verarbeitet (oder auch nicht) die anderen werden nie abgefragt ... lass doch ein Timer laufen und lasse ihn durch die Taste unterbrechen und wenn er sich im Bereich von 0 bis 43 befindet machst 1 und wenn er zwischen 43 und 86 ist 2 usw. Die Bitmaske hast ja in der If Abfrage drin ok :)


mfg
Sebastian
 
Zuletzt bearbeitet:
Das komische ist ja: Bei unserem Lehrer funktioniert es mit dieser If-Abfrage, nur er hat noch eine kleine Änderung drin auf die wir nur nicht kommen...

Wenn wir die taste drücken, geht er ja die Schleife immer wieder durch.
Und weil er das so schnell macht, können wir, wenn wir die taste loslassen, unmöglich immer die gleiche Zahl hintereinander treffen. Es ist also mehr ein Pseudo-Zufallsfallsgenerator.

Das mit dem Flimmern ist überhaupt nicht schlimm, hauptsache er zeigt eine Zufallszahl an.

Weiter muss das ganze nächste Woche stehen - für Experimente haben wir keine Zeit.
Auch befindet sich der Kontroller samt LED Schaltung nur in der Schule, wir haben also keien möglichkeit den Code vorher zu testen :(
 
Code:
if ( keys & 1 )
else if ( keys & 1 )
else if ( keys & 1 )
else if ( keys & 1 )
else if ( keys & 1 )
else if ( keys & 1 )
Merkste selbst, oder?
 
entweder du benutzt den integrierten timer oder noch einfacher, du holst dir eine hilfvariable (int tick) die bei jedem schleifendurchlauf erhöht wird... (tick++)
danach ne einfache modulo berechnung (rest) mit modulo 8: "zufallszahl = tick % 8;" -> schon können nur noch 8 werte rauskommen (0-7). zufallszahl +1 und du bist in dem wertebereich den du haben willst.

wenns probleme mit (zu schnellem) hochzählen der variable gibt, machst du einfach eine schleife drum, so dass der tick nur noch alle 100 durchläufe erhöht wird.


--> wenn ich's richtig interpretiere ist "keys" = knopf gedrückt. dann sieht das programm ungefähr so aus:

while (keys) // (solange keys = true)
{
tick++; // erhöhe den counter
}

zufallszahl = tick % 8; // zufallszahl = rest von tick geteilt durch 8
zufallszahl = zufallszahl + 1; // damit werte von 1-8 rauskommen

if zufallszahl == 1
{led = 164;
}
.
.
.
 
Zuletzt bearbeitet:
@ chrizZztian

Habe das jetzt entsprechend umgeändert, trotzdem gibt es einen Syntax-Error in der vierten Zeile:(

Building project...
AVRASM: AVR macro assembler 2.0.28 (build 121 Jan 11 2005 10:28:51)
Copyright (C) 1995-2005 ATMEL Corporation
C:\Users\Nordmende\Desktop\gaga.asm(4): error: syntax error, unexpected FUNCTION
Assembly failed, 1 errors, 0 warnings

Der Code:

#include <inttypes.h>
#include <avr/io.h>

int main(void)
{
uint8_t led;
uint8_t keys;


DDRB = 0xff; // use all pins on PortB for output
DDRD = 0x00; // use all pins on port D for input

PORTD = 0xff; // activate internal pull-up
PORTB = 0xff; // set output high -> turn all LEDs off


while (keys) // (solange keys = true)
{
tick++; // erhöhe den counter
}

zufallszahl = tick % 6; // zufallszahl = rest von tick geteilt durch 6
zufallszahl = zufallszahl + 1; // damit werte von 1-6 rauskommen

if zufallszahl == 1
{led = 164;
}

if zufallszahl == 2
{led = 148;
}

if zufallszahl == 3
{led = 210;
}

if zufallszahl == 4
{led = 152;
}

if zufallszahl == 5
{led = 136;
}

if zufallszahl == 6
{led = 215;
}

PORTB = ~led; // Set corresponding LED if switch pressed

}
 
Der Fehler ist nicht in der 4. Zeile deines Codes, sondern in der 4. Zeile des Krams, den der Compiler generiert hat und dem Assembler gefüttert hat.

€1: Deine if-Statements sind syntaktisch falsch.
€2: Übrigens benutzt du keys uninitialisiert.
€3: Und dein main() gibt keinen Rückgabewert.
€4: zufallszahl = zufallszahl + 1 ist Rechenzeitverschwendung.
€5: tick ist undeklariert.
€6: Dein Code ist von vorn bis hinten kompletter Mist. Wie kannst du nur auf die Idee kommen, dass das jemals auch nur annähernd funktionieren könnte?
€7: Ach und nochwas: Wofür Kommentare bei absolut trivialen Dingen, aber dafür bei Magic wie led = 164; nichts dergleichen?
€8: Du hast ja einfach nur den Pseudocode von nem anderen Poster cuntpasted. Nächstes Mal besser einfach mal nachdenken bevor du was änderst.
 
Zuletzt bearbeitet:
und die while(keys) schleife wird auch ne ganze weile laufen...
 
Naja oder mit einer Wahrscheinlichkeit von 2^-(8*sizeof(keys)) halt auch nicht.
 
Zuletzt bearbeitet:
Es ist denke ich recht offentsichtlich, dass ich davon nicht so viel verstehe.
Trotzdem danke für eure wertvollen Tipps und die Mühe die ihr euch gemacht habt.

Für den Ausgangscode gibs dank eines gnädigen Lehrers trotzdem eine gute Note.
Und da dies heute die letzte Stunde in dem Fach ist, schließe ich mal lieber mit dem Kapitel ab, um euch vor grausamen Code zu schützen ;)
 
Also die While Schleife SOLL sogar immer laufen. Sobald der µC an ist, läuft die Schleife. Ist dies nicht der Fall, so durchläuft er einmal die Schleife und ist danach quasi aus.
Ich progge seit einer Weile auch immer mit diese Grundkonstellation:
int main (void)
{
while (1)
{
//MAGIC
}
return 0;
}

Ob Return 0 notwendig ist, weiß ich nicht genau, da ich es einfach immer hinschreibe.
Die Kommentare sind wirklich sehr sehr komisch gewählt, ich als Lehrer würde dich zb fragen was 0xff zu bedeuten hat, und was led= bla zu bedeuten hat. Für mich sieht das aus als hätte man den Code irgendwie zusammenkopiert und die ganze Ansteuerung drum herum vergessen.
Bei mir steht z.B. oben im Prog Text(hier aus ner 7 Segment Anzeige welche Zahlen, wie definiert sind:
//Defines für Jeweilige Zahlen
#define Z0 0x04;
#define Z1 0x1F;
#define Z2 0x42;
#define Z3 0x0A;
#define Z4 0x19;
#define Z5 0x28;
#define Z6 0x20;
#define Z7 0x1E;
#define Z8 0x00;
#define Z9 0x08;
Wenn du verzögerungen reinmachen willst, solltest du oben noch folgendes Include setzen:
#include <util/delay.h>
Danach einfach
und er verzögert 1Sekunde.

Naja, sei froh das dein Lehrer sowas durchgehen lässt, warscheinlich hat er selber auch nicht viel mehr Ahung :d Mit sowas kommt man im Studium übrigens nicht durch.... :P

MFG Jubeltrubel
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh