Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[DSM-51] Wyswietlanie liczb na 7segmentówce + timer + sym

mog123 11 May 2010 23:05 2934 1
  • #1
    mog123
    Level 15  
    Witam, napisałem taki o to program, którego zadaniem jest wyświetlenie wartości zmiennej w postaci dziesiętnej. Wszystko wydaje się być w 100% racjonalna, ale niestety nie działa poprawnie. Kod programu poniżej:

    Code:
    #include <reg51.h>
    
    #include <absacc.h>

    #define bit_get(p,m) ((p) & (m))
    #define bit_set(p,m) ((p) |= (m))
    #define bit_clear(p,m) ((p) &= ~(m))
    #define BIT(x) (0x01 << (x))

    main()
    {
    double czekaj;
    unsigned char i,stany_pop=0,stany,tab[10],zmienna=255;
    tab[0]=0x3F;
    tab[1]=0x06;
    tab[2]=0x5B;
    tab[3]=0x4F;
    tab[4]=0x66;
    tab[5]=0x6D;
    tab[6]=0x7D;
    tab[7]=0x07;
    tab[8]=0x7F;
    tab[9]=0x6F;
       while(1)
       {
          stany=0;            //przygotuj do odczytu nowych stanow
          for(i=0;i<6;i++)         //zbiera dane z przyciskow,ustawia odpowiedni wyswietlacz;
          {
             bit_set(XBYTE[0xf030],BIT(i));
             if(bit_get(P3,BIT(5))) bit_set(stany,BIT(i));    //sprawdz bit przycisku



             switch(i)
             {
             case 0: XBYTE[0xf038]=tab[zmienna%10];            break;   //wybor segmentow
             case 1: XBYTE[0xf038]=tab[(zmienna%100 - zmienna%10)/10];   break;
             case 2: XBYTE[0xf038]=tab[(zmienna - zmienna%100)/100];      break;
             default: XBYTE[0xf038]=tab[0];
             };
             bit_clear(P1,BIT(6));                   //wlacz wyswietlacz
             for(czekaj=0;czekaj<6;czekaj++);             //odczekaj chwile
             bit_set(P1,BIT(6));                    //wylacz wyswietlacz
             XBYTE[0xf038]=0;                    //wylacz segmenty
             bit_clear(XBYTE[0xf030],BIT(i));
          }

          if(bit_get(stany_pop,BIT(3))&&stany==0)
          zmienna++;   

          if(bit_get(stany_pop,BIT(4))&&stany==0)
          zmienna--;

          stany_pop=stany;      //uaktualnij stare stany
       }
    }


    Problem tego programu leży w tym iż:
    -wyświetlacz nr0(zupełnie po prawej) działa ok, nr1 nie wyświetla tego co powinien, natomiast nr 2 daje cały czas jedynkę.
    -przycisk "strzałka do góry" inkrementuje liczbę pierwszego wyświetlacza, ale przycisk "strzałka na dół" nie dekrementuje tej wartości.
    -Środkowe wyświetlacze (nr2 i nr3) świecą się znacznie słabiej.

    Inna sprawa, czy wie ktoś jak zainicjalizować timer0 do zliczania setnych częsci sekund?
    EDIT: na tym symulatorze wszystko wydaje sie dzialac:
    https://www.elektroda.pl/rtvforum/topic1452510.html
    Ale jak probowalem na sprzecie na zajeciach to nie trybilo.
  • #2
    andrzejlisek
    Level 29  
    W rzeczywistym DSM-51, program windowsowy do wrzucania programów zmienia komórki 0003h, 0004h i 0005h na inne wartości. Kompilator języka C może w ramach optymalizacji wrzucić w to miejsce część programu. Z tego powodu, w momencie uruchamiania programu na DSM-51, jest on przekłamany.

    W swoim programie umieść kod, który spowoduje wymusi wymienionych bajtów kodem, który nie jest używany w tym programie.

    Na przykład:

    Code:
    void Dummy() interrupt 0
    
    {
     unsigned int D;
     for (D=0;D<10;D++);
    }


    Odpal tak zmieniony program na następnych zajęciach, powinno działać, jeżeli to była przyczyna problemów.


    Mikrokontroler w DSM-51 pracuje z czestotliwością 9216600 cykli maszynowych na sekundę. Z tą samą częstotliwością jest inkrementowany timer podczas pracy. Z tego obliczysz, ile 1 setna sekundy trwa dokładnie 92166 cykli maszynowych.

    Aby wykonywać pewną czynność co okreslony czas, zdefiniuj przerwanie od timera, a w ramach przerwania, timer będzie od razu tak ustawiany, że następne przerwanie nastąpi 1ms później.