Sari la conținut
ELFORUM - Forumul electronistilor

Exercitii programare de la zero


Vizitator ciocanaru

Postări Recomandate

  • 2 ani mai târziu...

Salutare,  daca  mai citeste cineva topicul, am si eu o intrebare. Am facut urmatorul joc de lumini, am mai modificat eu efectele si nu functioneaza cum trebuie programul, nu reia jocul numarul 1 se blocheaza la un efect si il ruleaza doar pe ala. Cum fac sa ruleze doar jocul numarul 1?

 

#define BUTON   RA0_bit
#define INPUT   1
#define OUTPUT  0

#define APASAT  0

#define NR_JOCURI    4

unsigned int  i = 0 ;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
void InitTimer0(){
  OPTION_REG = 0x81;
  TMR0 = 6;
  INTCON = 0xA0;
}

void init_sys(){
  CMCON = 0x07;        // To turn off comparators
  VREN_bit = 0;        // Disable voltage reference

  TRISB = 0b00000000;  // portul B este numai IESIRI
  PORTB = 0b00000000;  // se porneste cu toti pinii port B in stare LOW

  TRISA0_bit = INPUT;  // RA0 este intrare digitala - asigura-te ca ai un rezistor de pull-up connectat de pe pin catre VCC
}

void Interrupt(){
  static unsigned char counter = 0;
  static unsigned char ultima_apasare_reala = 0;

  if (TMR0IF_bit){
    TMR0IF_bit = 0;
    TMR0 = 6;

    // daca chiar si numai odata butonul nu este apasat atunci
    // ori avem bouncing ori butonul nu mai este apasat asadar in 'else' facem variabila counter = 0
   if (BUTON == APASAT){
      counter++;
      /* Daca var. counter ajunge la 10 atunci au trecut 10ms cu butonul apasat,
        deci suntem siguri ca avem o apasare reala
      */
      if (counter >= 10){
        counter = 0;
        if (ultima_apasare_reala == 0){
          // i este un contor care numara circular la fiecare apasare reala pana la NR_JOCURI
          // daca NR_JOCURI este 4 ca in cazul curent atunci variabila i va lua valorile: 0,1,2,,3,0,1,2,3 samd
          if (i >= NR_JOCURI-1) i = 0;
          else i++;
          ultima_apasare_reala = 1;
        }
      }
    }
    else {
      counter = 0;
      ultima_apasare_reala = 0;
    }
  }
}

void joc_lumini_1(){
  /* Aici vom avea definit jocul de lumini nr 0
  */
    int j;

      for (j = 0; j < 8; j++){
    PORTB = (1 << j);
    delay_ms(50);
  }
  for (j = 7; j >= 0; j--){
    PORTB = (1 << j);
    delay_ms(50);
   }
  PORTB = 0xCC;
  delay_ms(300);
  PORTB = 0x33;
  delay_ms(300);
  PORTB = 0x55;
  delay_ms(300);
  PORTB = 0xAA;
  delay_ms(300);
  PORTB = 0x55;
  delay_ms(300);
  PORTB = 0xAA;
  delay_ms(300);
  PORTB = 0xCC;
  delay_ms(300);
  PORTB = 0x33;
  delay_ms(300);
  for (j = 0; j < 8; j++){
    PORTB = (1 << j);
    delay_ms(50);
  }
  for (j = 7; j >= 0; j--){
    PORTB = (1 << j);
    delay_ms(50);
   }


  PORTB = 0xF0;
  delay_ms(500);
  PORTB = 0x0F;
  delay_ms(500);
  PORTB = 0x99;
  delay_ms(500);
  PORTB = 0x66;
  delay_ms(500);
  PORTB = 0x99;
  delay_ms(500);
  PORTB = 0x66;
  delay_ms(500);

  PORTB = 0x80;
  delay_ms(100);
  PORTB = 0xC0;
  delay_ms(100);
  PORTB = 0xE0;
  delay_ms(100);
  PORTB = 0xF0;
  delay_ms(100);
  PORTB = 0xF8;
  delay_ms(100);
  PORTB = 0xFC;
  delay_ms(100);
  PORTB = 0xFE;
  delay_ms(100);
  PORTB = 0xFF;
  delay_ms(100);
                 for (j = 0; j < 8; j++){
    PORTB = (1 << j);
    delay_ms(50);
  }
  for (j = 7; j >= 0; j--){
    PORTB = (1 << j);
    delay_ms(50);
   }
}

void joc_lumini_2(){
  /* Aici vom avea definit jocul de lumini nr 1
  */

PORTB = 0x80;
  delay_ms(100);
  PORTB = 0xC0;
  delay_ms(100);
  PORTB = 0xE0;
  delay_ms(100);
  PORTB = 0xF0;
  delay_ms(100);
  PORTB = 0xF8;
  delay_ms(100);
  PORTB = 0xFC;
  delay_ms(100);
  PORTB = 0xFE;
  delay_ms(100);
  PORTB = 0xFF;
  delay_ms(100);

}

void joc_lumini_3(){
  /* Aici vom avea definit jocul de lumini nr 2
  */
  int j;

  for (j = 0; j < 8; j++){
    PORTB = (1 << j);
    delay_ms(50);
  }
  for (j = 7; j >= 0; j--){
    PORTB = (1 << j);
    delay_ms(50);
   }
    for (j = 0; j < 8; j++){
    PORTB = (1 << j);
    delay_ms(1000);
  }
  for (j = 7; j >= 0; j--){
    PORTB = (1 << j);
    delay_ms(1000);
  }
}
void void joc_lumini_4() {
  /* Aici vom avea definit jocul de lumini nr 3
  */

     PORTB = 0x80;
  delay_ms(100);
  PORTB = 0xC0;
  delay_ms(100);
  PORTB = 0xE0;
  delay_ms(100);
  PORTB = 0xF0;
  delay_ms(100);
  PORTB = 0xF8;
  delay_ms(100);
  PORTB = 0xFC;
  delay_ms(100);
  PORTB = 0xFE;
  delay_ms(100);
  PORTB = 0xFF;
  delay_ms(100);

}

void main(){
  init_sys();
  InitTimer0();

  // bucla infinita
  while (1) {

    switch (i){
      case 0:
        joc_lumini_1();
        break;
      case 1:
        joc_lumini_2();
        break;
      case 2:
        joc_lumini_3();
        break;
      case 3:
        joc_lumini_4();
        break;
    }

  }
}

Editat de The_Reaper
Link spre comentariu

in intrerupere se modifica i-ul

dar ar trebui facut o versiune fara delay-uri, eventual cu delay pe timer, sa fie responsive.

eventual cu state machines sa fie mai usor de citit, si cu array de parametri (port value, delay value) care se pot procesa toate intr-o iteratie.

Link spre comentariu

poti incerca sa vezi ce face codul asta:

#include <pic.h>
#include <pic16f628.h>

#define BUTON RA0
#define INPUT 1
#define OUTPUT 0

#define APASAT 0

#define NR_JOCURI 4

#define SIZE( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )

static volatile unsigned int i;
static volatile unsigned int s_pos;
static volatile unsigned int counterMs;

struct Step
{
    unsigned char data;
    unsigned short time;
};

const struct Step c_joc1[] =
{
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 },
    { 0xCC, 300 }, { 0x33, 300 }, { 0x55, 300 }, { 0xAA, 300 }, { 0x55, 300 }, { 0xAA, 300 }, { 0xCC, 300 }, { 0x33, 300 },
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 },
    { 0xF0, 500 }, { 0x0F, 500 }, { 0x99, 500 }, { 0x66, 500 }, { 0x99, 500 }, { 0x66, 500 },
    { 0x80, 100 }, { 0xC0, 100 }, { 0xE0, 100 }, { 0xF0, 100 }, { 0xF8, 100 }, { 0xFC, 100 }, { 0xFE, 100 }, { 0xFF, 100 }, 
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 },
};

const struct Step c_joc2[] =
{
    { 0x80, 100 }, { 0xC0, 100 }, { 0xE0, 100 }, { 0xF0, 100 }, { 0xF8, 100 }, { 0xFC, 100 }, { 0xFE, 100 }, { 0xFF, 100 }, 
};

const struct Step c_joc3[] =
{
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 },
    { 0x01, 1000 }, { 0x02, 1000 }, { 0x04, 1000 }, { 0x08, 1000 }, { 0x10, 1000 }, { 0x20, 1000 }, { 0x40, 1000 }, { 0x80, 1000 },
    { 0x80, 1000 }, { 0x40, 1000 }, { 0x20, 1000 }, { 0x10, 1000 }, { 0x08, 1000 }, { 0x04, 1000 }, { 0x02, 1000 }, { 0x01, 1000 },
};

const struct Step c_joc4[] =
{
    { 0x80, 100 }, { 0xC0, 100 }, { 0xE0, 100 }, { 0xF0, 100 }, { 0xF8, 100 }, { 0xFC, 100 }, { 0xFE, 100 }, { 0xFF, 100 }, 
};

const const struct Step* c_jocuri[] = { c_joc1, c_joc2, c_joc3, c_joc4 };
const const int c_jocuriSize[] = { SIZE( c_joc1 ), SIZE( c_joc2 ), SIZE( c_joc3 ), SIZE( c_joc4 ) };

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
void InitTimer0()
{
    OPTION_REG = 0x81;
    TMR0 = 6;
    INTCON = 0xA0;
}

void init_sys()
{
    CMCON = 0x07; // To turn off comparators
    VREN = 0; // Disable voltage reference

    TRISB = 0b00000000; // portul B este numai IESIRI
    PORTB = 0b00000000; // se porneste cu toti pinii port B in stare LOW

    TRISA0 = INPUT; // RA0 este intrare digitala - asigura-te ca ai un rezistor de pull-up connectat de pe pin catre VCC
}

void interrupt ISR()
{
    static unsigned char counter = 0;
    static unsigned char ultima_apasare_reala = 0;

    if (TMR0IF)
    {
        TMR0IF = 0;
        TMR0 = 6;
        ++counterMs;

        // daca chiar si numai odata butonul nu este apasat atunci
        // ori avem bouncing ori butonul nu mai este apasat asadar in 'else' facem variabila counter = 0
        if (BUTON == APASAT)
        {
            counter++;
            /* Daca var. counter ajunge la 10 atunci au trecut 10ms cu butonul apasat,
               deci suntem siguri ca avem o apasare reala
            */
            if (counter >= 10)
            {
                counter = 0;
                if (ultima_apasare_reala == 0)
                {
                    // i este un contor care numara circular la fiecare apasare reala pana la NR_JOCURI
                    // daca NR_JOCURI este 4 ca in cazul curent atunci variabila i va lua valorile: 0,1,2,,3,0,1,2,3 samd
                    if (i >= NR_JOCURI - 1)
                        i = 0;
                    else
                        i++;
                    s_pos = 0;
                    ultima_apasare_reala = 1;
                }
            }
        }
        else
        {
            counter = 0;
            ultima_apasare_reala = 0;
        }
    }
}

void main()
{
    init_sys();
    InitTimer0();

    // bucla infinita
    while (1)
    {
        if ( counterMs >= c_jocuri[ i ][s_pos].time )
        {
            counterMs = 0;
            if ( ++s_pos >= c_jocuriSize[ i ] )
                s_pos = 0;
            PORTB = c_jocuri[ i ][s_pos].data;
        }
    }
}

 

Editat de core
verificare pe simulator
Link spre comentariu

Sigur?

Atunci ce cauta

#include <pic.h>
#include <pic16f628.h>

in cod?

La xc8 trebuie inclus xc.h, cu restul se descurca singur:

Citat

5.3.3
 Device Header Files
There is one header file that is typically included into each C source file you write. The
file is <xc.h> and is a generic header file that will include other device- and
architecture-specific header files when you build your project.

 

 

Link spre comentariu

Da, am folosit xc8.

Am facut modif si pentru mikroc, dar pe simulator ledurile clipesc mai repede la mine, fata de compilarea pe xc8. O fi ceva in neregula cu setarea timer-ului. E xc8, timpul de clipire corespunde.

#define BUTON RA0_bit
#define INPUT 1
#define OUTPUT 0

#define APASAT 0

#define NR_JOCURI 4

#define SIZE( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )

struct Step
{
    unsigned char portData;
    unsigned short time;
};

static volatile unsigned int i;
static volatile unsigned int s_pos;
static volatile unsigned int counterMs;

const struct Step c_joc1[] =
{
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 },
    { 0xCC, 300 }, { 0x33, 300 }, { 0x55, 300 }, { 0xAA, 300 }, { 0x55, 300 }, { 0xAA, 300 }, { 0xCC, 300 }, { 0x33, 300 },
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 },
    { 0xF0, 500 }, { 0x0F, 500 }, { 0x99, 500 }, { 0x66, 500 }, { 0x99, 500 }, { 0x66, 500 },
    { 0x80, 100 }, { 0xC0, 100 }, { 0xE0, 100 }, { 0xF0, 100 }, { 0xF8, 100 }, { 0xFC, 100 }, { 0xFE, 100 }, { 0xFF, 100 }, 
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 }
};

const struct Step c_joc2[] =
{
    { 0x80, 100 }, { 0xC0, 100 }, { 0xE0, 100 }, { 0xF0, 100 }, { 0xF8, 100 }, { 0xFC, 100 }, { 0xFE, 100 }, { 0xFF, 100 }, 
};

const struct Step c_joc3[] =
{
    { 0x01, 50 }, { 0x02, 50 }, { 0x04, 50 }, { 0x08, 50 }, { 0x10, 50 }, { 0x20, 50 }, { 0x40, 50 }, { 0x80, 50 },
    { 0x80, 50 }, { 0x40, 50 }, { 0x20, 50 }, { 0x10, 50 }, { 0x08, 50 }, { 0x04, 50 }, { 0x02, 50 }, { 0x01, 50 },
    { 0x01, 1000 }, { 0x02, 1000 }, { 0x04, 1000 }, { 0x08, 1000 }, { 0x10, 1000 }, { 0x20, 1000 }, { 0x40, 1000 }, { 0x80, 1000 },
    { 0x80, 1000 }, { 0x40, 1000 }, { 0x20, 1000 }, { 0x10, 1000 }, { 0x08, 1000 }, { 0x04, 1000 }, { 0x02, 1000 }, { 0x01, 1000 },
};

const struct Step c_joc4[] =
{
    { 0x80, 100 }, { 0xC0, 100 }, { 0xE0, 100 }, { 0xF0, 100 }, { 0xF8, 100 }, { 0xFC, 100 }, { 0xFE, 100 }, { 0xFF, 100 }, 
};

const const struct Step* c_jocuri[] = { c_joc1, c_joc2, c_joc3, c_joc4 };
const const int c_jocuriSize[] = { SIZE( c_joc1 ), SIZE( c_joc2 ), SIZE( c_joc3 ), SIZE( c_joc4 ) };

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
void InitTimer0()
{
    OPTION_REG = 0x81;
    TMR0       = 6;
    INTCON     = 0xA0;
}

void init_sys()
{
    CMCON = 0x07;  // To turn off comparators
    VREN_bit  = 0;     // Disable voltage reference

    TRISB = 0b00000000; // portul B este numai IESIRI
    PORTB = 0b00000000; // se porneste cu toti pinii port B in stare LOW

    TRISA0_bit = INPUT; // RA0 este intrare digitala - asigura-te ca ai un rezistor de pull-up connectat de pe pin catre VCC
}

void Interrupt()
{
    static unsigned char counter = 0;
    static unsigned char ultima_apasare_reala = 0;

    if (TMR0IF_bit)
    {
        TMR0IF_bit = 0;
        TMR0       = 6;
        ++counterMs;

        // daca chiar si numai odata butonul nu este apasat atunci
        // ori avem bouncing ori butonul nu mai este apasat asadar in 'else' facem variabila counter = 0
        if (BUTON == APASAT)
        {
            counter++;
            /* Daca var. counter ajunge la 10 atunci au trecut 10ms cu butonul apasat,
               deci suntem siguri ca avem o apasare reala
            */
            if (counter >= 10)
            {
                counter = 0;
                if (ultima_apasare_reala == 0)
                {
                    // i este un contor care numara circular la fiecare apasare reala pana la NR_JOCURI
                    // daca NR_JOCURI este 4 ca in cazul curent atunci variabila i va lua valorile: 0,1,2,,3,0,1,2,3 samd
                    if (i >= NR_JOCURI - 1)
                        i = 0;
                    else
                        i++;
                    s_pos = 0;
                    ultima_apasare_reala = 1;
                }
            }
        }
        else
        {
            counter = 0;
            ultima_apasare_reala = 0;
        }
    }
}

void main()
{
    init_sys();
    InitTimer0();

    // bucla infinita
    while (1)
    {
        if ( counterMs >= c_jocuri[ i ][s_pos].time )
        {
            counterMs = 0;
            if ( ++s_pos >= c_jocuriSize[ i ] )
                s_pos = 0;
            PORTB = c_jocuri[ i ][s_pos].portData;
        }
    }
}

 

Link spre comentariu
  • 3 săptămâni mai târziu...

MCLR se leaga intotdeauna la VCC printr-o rezistenta de 10k si la GDN printr-un buton de reset.. Este activ LOW. 

Eu dezactivez pinul MCLR doar daca nu mai am pini disponibili. 

Dezactivand MCLR pierzi posibilitatea de a reseta uC-ul, altfel decat intrerupandu-i alimentarea.

Un exemplu de conectare a pinului MCLR se poate gasi la https://microchipdeveloper.com/8bit:guide

Cand ai lasat pinul MCLR liber ai buimacit uC-ul, saracul nemaistiind ce sa creada pe intrarea aia, asa ca intra in reset aleatoriu.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări