2013-01-10 4 views
0

J'essaie d'écrire un code pour un programme de base de simulateur de dés. Quand un commutateur est pressé, les deux affichages à sept segments changeront rapidement entre 1-6. Lorsque le bouton est relâché, le nombre aléatoire s'affiche sur l'affichage à sept segments.Simulateur de dés avec programmation C

Ce code sera connecté à un PIC16F877 dans ISIS et j'utilise MPLAB pour la programmation C. Je suis vraiment nouveau dans ce domaine de la programmation, donc c'est difficile pour moi de comprendre ce que je fais.

#include <pic.h> 
const char patterns[]={0X3F, 0X06, 0X5B, 0x4F, 0X66, 0X6D, 0X7D} 
char rand_num1=0; 
char rand_num2=0; 

void main(void) 

{ 
    TRISB=0x00; 
    TRISC=0x01; 
    TRISD=0x00; 

    for(;;) 
      { 
       if(RCO==0) 
       { 
         rand_num1=rand()%6+1; 
         rand_num2=rand()%6+1; 
       } 

       if (RC0==1) 
        { 
         const char patterns[]; 
        } 
      } 
} 
+4

Quelle est votre question? – hmatar

+0

@HassanTM fait fonctionner '(;;)'? ou il devrait écrire 'for (; 1;)' **? ** –

+0

ouais pour (;;) fonctionne. C'est ISIS MPLAB de toute façon. – user1966947

Répondre

0

Permettez-moi de préciser mes commentaires ci-dessus un peu:

D'abord, vous n'avez pas besoin d'appeler rand(). L'utilisateur va appuyer sur le bouton pendant un certain temps (avec une précision de 10 ou 20 nanosecondes, ce qui est une horloge raisonnable pour un microcontrôleur). Cet intervalle, et compte tenu de la précision sera probablement plus aléatoire que d'appeler rand(). Par conséquent, vous pouvez avoir un seul compteur (c'est-à-dire jusqu'à 256) et saisir deux nombres aléatoires de ce compteur. Dans le code, ce serait quelque chose comme:

int counter = 0; 
int lo_chunk, hi_chunk; 
if(RCO == 0) { // assuming that RCO == 0 means the button is pressed 
    counter = (counter + 1) % 256; // keep one byte out of the int 
            // we'll use that byte two get 2 4-bit 
            // chunks that we'll use as our randoms 
    lo_chunk = (counter & 0xF) % 6; // keep 4 LSBits and mod them by 6 
    hi_chunk = ((counter >> 4) & 0xF) % 6; // shift to get next 4 bits and mod them by 6 
    // Now this part is tricky. 
    // since you want to display the numbers in the 7seg display, I am assuming 
    // that you will need to write the respective patterns "somewhere" 
    // (either a memory address or output pins). You'll need to check the 
    // documentation of your board on this. I'll just outline them as 
    // "existing functions" 
    write_first_7segment(patterns[lo_chunk]); 
    write_second_7segment(patterns[hi_chunk]); 

} else if(RCO == 1) { // assuming that this means "key released" 
    rand_num1 = lo_chunk; 
    rand_num2 = hi_chunk; 
    // probably you'll also need to display the numbers. 
} 

J'espère que ce que j'ai écrit dans les commentaires ci-dessus a plus de sens maintenant.

Gardez à l'esprit, que de ne pas connaître les détails exacts de votre conseil, je ne peux pas vous dire comment écrire réellement les motifs à l'affichage à 7 segments, mais je suppose qu'il y aura une fonction quelconque.

+0

Il pourrait y avoir des arguments sur le biais des nombres aléatoires produits du fait que nous utilisons un modulo 6 sur 16 éléments. Cela signifie que pendant un cycle, certains des nombres résultants apparaissent plus fréquemment que d'autres, mais je ne suis pas entièrement sûr si cela affecte la qualité des nombres aléatoires. – nvlass

+0

Comment savez-vous que l'implémentation de rand() n'utilise pas un peu de fiddling basé sur le temps? ou un autre algorithme "plus" aléatoire. – Adrian

+0

@Adrian vous pourriez avoir raison, et je ne peux pas savoir sans réellement regarder dans la mise en œuvre de stdlib - sur "l'élan" j'ai supposé un LCG ou plus. En fait, après avoir regardé [ici] (http://ww1.microchip.com/downloads/en/devicedoc/mplab_c18_libraries_51297f.pdf) et en supposant que j'ai obtenu le bon MPLAB, il mentionne un pseudo-RNG (qui aurait aussi du sens pour un implémentation de stdlib car elle permet des résultats reproductibles pendant le débogage). – nvlass

0

Commençons par la décomposer en plusieurs parties et abordons-les individuellement. C'est une bonne pratique de toute façon, et vous devriez vous retrouver avec beaucoup de petits problèmes qui sont individuellement faciles à résoudre.

Nous pouvons commencer par pseudocode pour la boucle principale:

for ever { 
    while button is pushed { 
     roll the dice 
     update the displays 
    } 
    /* this^loop ends when the button is released 
     and is never entered until the button is pushed 
    */ 
} 

qui se traduit par quelque chose comme:

int main(void) 
{ 
    /* somewhere to keep the current value of each die, 
     initialized to zero */ 
    char dice[2] = {0,0}; 
    for (;;) { 
     while (button_pushed()) { 
      roll(dice); 
      display(dice); 
     } 
    } 
} 

maintenant nous devons écrire button_pushed:

/* return true (non-zero) if RC0 is zero/one (delete as appropriate) */ 
int button_pushed(void) 
{ 
    return RC0 == 0; 
} 

. .. et roll, et display. Cela vous a-t-il permis de démarrer?