Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Keil] [C] [DS89C430] Wywoływanie funkcji w przerwaniu

Ganz 16 Lip 2008 10:38 2028 1
  • #1 16 Lip 2008 10:38
    Ganz
    Poziom 17  

    Napisałem sobie takie oto funkcje do obsługi DS18S20:

    Code:

    #include <DS89C4xx.H>   // biblioteka uC DS89C430
    typedef unsigned char    BYTE;   // definicja typow danych
    typedef unsigned int    WORD;

    sfr led_10 = 0x80;   // port P0 wyswietla cyfre dziesiatek
    sfr led_01 = 0xA0;   // port P2 wyswietla cyfre jednosci

    sbit DQ = P0^7;               
    sbit run = P1^0;   
    sbit error_sensor = P1^1;
    sbit run_heating = P1^2;         
    sbit run_air = P1^3;
    sbit man_mode = P1^4;
    sbit auto_mode = P1^5;
    sbit setting_temperature_on = P1^6;
    sbit setting_temperature_off = P1^7;
    sbit save = P3^0;   
    sbit set_temperature_on = P3^1;
    sbit set_temperature_off = P3^2;   
    sbit up = P3^3;
    sbit down = P3^4;
    sbit man_auto = P3^5;
    sbit heat = P3^6;
    sbit air = P3^7;
          // tablica do dekodowania liczb dziesietnych na format wyswietlacza 7-segmentowego
    char code value[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
          // numery seryjne pastylek zapisane w ich pamieci ROM
    code int ROM1[] = {0x10, 0x4A, 0xDA, 0x63, 0x01, 0x08, 0x00, 0x67};
    code int ROM2[] = {0x10, 0x9D, 0xD3, 0x63, 0x01, 0x08, 0x00, 0xD5};

    #define on 0;
    #define off 1;
    #define start 1;
    #define stop 0;
                      
    int  temperature;


    //----------------------------------------------------------------
    void delay(int useconds)
    {
       WORD s;
       for (s = 0; s < useconds; s++); //opoznienie programowe
    }   
    //----------------------------------------------------------------
    BYTE ow_reset(void)
    {
       BYTE presence;
       DQ = 0;          // magistrala ustawiona na stan niski
       delay(239);       // poczekaj 480 us
       DQ = 1;          // magistrala ustawiona na stan wysoki
       delay(34);          // poczekaj 70 us na sygnal obecnosci
       presence = DQ;       // pobierz sygnal obecnosci
       delay(209);       // poczekaj 420 us na koniec slotu czasowego
       return(!presence);  // 1 = obecnosc pastylki, 0 = brak pastylki
    }   
    //----------------------------------------------------------------




    unsigned char read_bit(void)
    {
       DQ = 0;    // magistrala ustawiona na stan niski
       delay(1);    // poczekaj 2.5 us
       DQ = 1;    // magistrala ustawiona na stan wysoki
       delay(7);    // poczekaj 16 us
       return(DQ); // zwroc wartosc linii DQ
    }
    //----------------------------------------------------------------
    BYTE read_byte(void)
    {
       BYTE i,value = 0;
       for (i = 0; i < 8; i++)
       {                                  // odczutuje wartosci kolejnych bitow
          if(read_bit())   value |= (0x01 << i);    // i potem je przesuwa w lewo                                         
          delay(50);                           // poczekaj na koniec slotu
       }
       return(value);
    }              
    //----------------------------------------------------------------
    void write_bit(char bitval)
    {
       DQ = 0;             // magistrala ustawiona na stan niski
       delay(1);             // poczekaj 2.5 us
       if(bitval == 1) DQ = 1; // magistrala ustawiona na stan wysoki jesli chcemy zapisac 1
       delay(50);             // poczekaj na koniec slotu
       DQ = 1;             // na koniec magistrala ustawiona na stan wysoki
    }
    //----------------------------------------------------------------
    void write_byte(char val)
    {
       BYTE i, temp;
       for (i = 0; i < 8; i++)
       {
          temp = val >> i;    // przesuwa bajt w prawo
          temp &= 0x01;       // filtruje do postaci umozliwiajacej odczyt najmlodszego bitu
          write_bit(temp);    // zapisuje bit
       }
       delay(50);             // poczekaj na koniec slotu
    }
    //----------------------------------------------------------------   
    int read_temperature(int *source)
    {
       BYTE interupt_state; // zmienna do zapamietania stanu przerwan
       BYTE get[10];       // bufor do zapisu danych
       BYTE temp_lsb, temp_msb, temp_c;// zmienne pomocnicze mlodszy i starszy bajt
       int k;            // zmienna indeksowa

       interupt_state = EA;// zapamietanie stanu przerwan
       EA = 0;            // zablokowanie przerwan

       ow_reset();         // reset 1-wire
       write_byte(0x55);    // komenda wygaszenia pastylek o numerze innym od podanego
       for (k = 0; k < 8; k++) { write_byte(*(source+k)); }   // przeslanie numeru seryjnego
       write_byte(0x44);    // komenda rozpoczecia konwersji
       delay(50);

       ow_reset();         // reset 1-wire
       write_byte(0x55);    // komenda wygaszenia pastylek o numerze innym od podanego
       for (k = 0; k < 8; k++){ write_byte(*(source+k)); }      // przeslanie numeru seryjnego
       write_byte(0xBE);    // komenda odczytu Scratch Pad
       for (k = 0; k < 9; k++){ get[k] = read_byte(); }// odczutuj i zapisuj dane do bufora
       
       temp_msb = get[1];    // z bufora wyciagnij starszy bit
       temp_lsb = get[0];    // z bufora wyciagnij mlodszy bit
       if ( temp_msb == 0x00 )   { temp_c = (temp_lsb/2); }
       else                  { temp_c = 0x00; }
       if (temp_c > 99)         { temp_c = 99; }
       
    //   if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);}    // jesli teperatura ujemna
    //   temp_msb &= 0x80;                            // jesli teperatura ujemna
    //   if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;}   // jesli teperatura ujemna
    //   if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}   // jesli teperatura ujemna
    //   if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);}   // jesli teperatura ujemna   
    //   if (temp_msb == 0x00) {temp_c = (temp_lsb/2);}       //jesli teperatura ujemna
    //   else {temp_c = 0x00;}                         //jesli teperatura ujemna
       delay(50);
       EA = interupt_state; // przywrocenie stanu przerwan   
       return((int)temp_c); // zwrot wartosci      
    }
    //----------------------------------------------------------------   
                 
    //----------------------------------------------------------------
    // Przyklad wywolania: show(temperature);
    void show(int temp)
    {   
       BYTE msb, lsb;

       msb = temp / 10;       // wyciagniecie cyfry dziesietnej
       lsb = temp % 10;       // wyciagniecie cyfry jednosci
       led_10 = value[msb];   // dekodowanie cyfry dziesietnej
       led_01 = value[lsb];   // dekodowanie cyfry jednosci
    }   
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    // TO_INT - Funkcja przerwania od przepelnienia Timera 0
    void T0_int(void) interrupt 1 using 1
    {
       static BYTE count;

       TH0 = 0x4B;   // zerowanie Timera 0
       TL0 = 0xFF;
       
       count++;

       if (count >= 20)   count = 0;   // miganie diody          
       if (count >= 10)   {run = off;}
       else            {run = on;}   
    }
    //----------------------------------------------------------------
    void main(void)
    {         
       WORD loop_small, loop_big;   // petle opozniajace   

       PMR = 0x9D;      // ustawienie sposobu pracy
       P0 = 0xFF;
       P1 = 0xFF;
       P2 = 0xFF;
       P3 = 0xFF;

       TH0 = 0x4B;    // ladowarie wartosci do Timera 0
       TL0 = 0xFF;
       TMOD = 0x01;// rejestry TH0 i TL0 tworza licznik 16-bitowy   
       ET0 = 1;   // zezwolenie na przerwania od Timera 0
       EA = 1;   // globalne zezwolenie na przerwania
       TR0 = 1;      // uruchominie Timera

       while(1)
                   {
                    temperature = read_tempearture(ROM1)
                    //temperature = read_tempearture(ROM2)
                    show(temperature);
                    }
    }   


    Program działa bez zarzutu. Chciałbym jednak funkcje

    Code:

    temperature = read_tempearture(ROM1)
    //temperature = read_tempearture(ROM2)
    show(temperature);


    wywoływać w przerwaniu od tajmera T0, czyli w funkcji T0_int. Niestety nawet jak dodam parametr "reentrant" do definicji funcji "show" i "read_temperature" to nie działa mi program. Co zrobić, aby funkcje te można było wywoływać w przerwaniu?

    0 1
  • #2 14 Sie 2008 08:23
    94075
    Użytkownik usunął konto