Forum Coders' city Strona Główna Coders' city
Nasza pasja to programowanie!
 

 PomocPomoc   SzukajSzukaj   UżytkownicyUżytkownicy   GrupyGrupy  RejestracjaRejestracja 
Archiwum starego forum + teoria    RSS & Panel/SideBar
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 

Potrzebuję szybkiej odpowiedzi na moje pytanie... Zasady

Czujnik lm35 i lpc2138



 
Odpowiedz do tematu    Forum Coders' city Strona Główna -> Elektronika, programowanie niskopoziomowe
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
alycja



Dołączył: 02 Sty 2013
Posty: 3

PostWysłany: Sro Sty 02, 2013 11:10 pm  OP    Temat postu: Czujnik lm35 i lpc2138 Odpowiedz z cytatem Pisownia

Witam.
Jestem tutaj nowa i całkowicie zielona w programowaniu mikroprocesorów (może nie do końca zielona, ale prawie że :) ), ale bardzo chciałabym się czegoś nauczyć.
Dostałam za zadanie zaprogramować wykrywanie temperatury za pomocą czujnika nm35- wynik ma się wyświetlać na lcd podłączonego do procesora lpc2138 - zarówno w trybie polling, jak i wykorzystując przerwanie. Okej, wiem, że należy wykorzystać konwerter AD , jednak nie bardzo wiem, co dalej.
Program piszę w C.
Czy ktoś może mnie nakierować, pomóc, jak poradzić sobie z tym zadaniem?
Czy ktoś zna także jakiś symulator, na którym mogłabym testować wyniki pracy bez posiadania w domu tego sprzętu?
Byłabym wdzięczna za każdą pomoc.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
biernik



Dołączył: 06 Wrz 2008
Posty: 1148
Skąd: 63°59'39''N 22°38'11''W

PostWysłany: Czw Sty 03, 2013 12:02 am      Temat postu: Odpowiedz z cytatem Pisownia

Co daje na wyjściu ten czujnik? Wyszukiwarka nic mi nie zwraca na "nm35 sensor".
Ja się bawiłem jakąś czujką która na wyjściu dawała napięcie rosnące liniowo z temperaturą, chyba 10mV/1C to było dosyć proste z przerywaniem, coś mniej więcej takiego:
Włączyć przerywanie ADC;
W obsłudze przerywania odczytać wartość ADC, przeliczyć na temperaturę. Jak przeliczyć, będzie zależało od tego co wypluwa Twoja czujka, od dokładności twojego ADC(mój był chyba 10bitowy), i od Twojego reference-voltage;
Wpisać na LCD;

pzdr.

_________________
I like cheese.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
alycja



Dołączył: 02 Sty 2013
Posty: 3

PostWysłany: Czw Sty 03, 2013 12:05 am  OP    Temat postu: Odpowiedz z cytatem Pisownia

ups, mała literówka lm35 xD w sumie jedna literka a kolosalne znaczenie.

(Tytuł tematu zmieniłem wg Twojej poprawionej informacji - Samolot)
Jednak jesli sie zarejestrowałaś, to swoje posty możesz eytoważć używając przycisku Zmień
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
biernik



Dołączył: 06 Wrz 2008
Posty: 1148
Skąd: 63°59'39''N 22°38'11''W

PostWysłany: Czw Sty 03, 2013 12:28 am      Temat postu: Odpowiedz z cytatem Pisownia

Więc to samo: 10mV/1C, czyli proste bo zależność napięcie-temperatura jest liniowa.
Gotowca Ci nie dam bo ja to robiłem PICem, więc kod będzie całkiem inny, ale z grubsza algorytm masz.
Mój niezawodny sposób na poskromienie dowolnej funkcjonalności mikrusa(w tym przypadku ADC+przerywania):
Weź data-sheeta do swojego procka, otwórz sekcję o ADC, przeczytaj. Otwórz sekcję o przerywaniach, przeczytaj. Z grubsza powinno to dać pojęcie o tym jak to zrobić.
Teraz weź kartkę, przeleć jeszcze raz, zrób notki co i w jakiej kolejności trzeba zrobić.
Napisz kod - powinno pójść dość sprawnie po przeczytaniu odpowiednich paragrafów i z notkami pod pachą.
Ja tak zawsze robię i dla mnie ta metoda działa dość skutecznie.

Jak już mówiłem, musisz wiedzieć jaką rozdzielczość ma Twój ADC, jaki masz reference-voltage i w przerywaniu odczytujesz wartość ADC, kilka mnożeń/dzieleń/dodawań i masz swoją temperaturę.

pzdr.

_________________
I like cheese.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
alycja



Dołączył: 02 Sty 2013
Posty: 3

PostWysłany: Nie Sty 13, 2013 11:53 pm  OP    Temat postu: Odpowiedz z cytatem Pisownia

Hm... Po przejrzeniu wielu przykładów udało mi się stworzyć coś takiego:
Kod:

#include <LPC214x.h>
#include "lcd.h"

#define BUTTON0 (1<<4)
#define BUTTON1 (1<<5)

int licznik;
static unsigned short ADCresult[4];


// zmienne do obslugi klawiatury 'Debouncing'
unsigned int buttonState;
unsigned int newButtonState, oldButtonState;

void ADC_Isr(void) __irq
{

    ADCR  = 0x0020780F;                // Init ADC (Pclk = 12MHz)
    ADCR |= 0x00010000;                // start burst mode now, see errata ADC.2
      
        unsigned int r,ch;
    r = ADDR;                          // Read Data Register and clear DONE flag
    ch = (r >> 24) & 0x07;             // which channel was converted
    ADCresult[ch] = (r>>6) & 0x03FF;   // bit 6:15 is 10 bit AD value
    VICVectAddr = 0;                   // reset VIC
}

static unsigned short ADC_Read(unsigned char ch)
{
    unsigned int i;
    ADCR = 0x00200300 | ch; ADCR |= 0x01000000;
    do
    {
        i = ADDR;
    } while ((i & 0x80000000) == 0);
    return (i >> 6) & 0x03FF;
}

void process_temp_sensor_adc_polling(void)
{
    unsigned short adc_value = 0;
    unsigned char buf[16] = {0};
  
    adc_value = ADC_Read(3);
    sprintf((char *)buf, "Temp:%2d", adc_value);
    LcdSetCursor(0x40);
    LcdPrint((char *)buf);
}

void process_temp_sensor_adc_interrupt(void)
{
    unsigned short adc_value = 0;
    unsigned char buf[16] = {0};
  
    adc_value = ADCresult[3];
    sprintf((char *)buf, "Temp:%2d", adc_value);
    LcdSetCursor(0x40);
    LcdPrint((char *)buf);
}


int     main(void)
{
    // Inicjalizacja zmiennych
        buttonState = newButtonState = oldButtonState = 0;
        buttonState = (BUTTON0 | BUTTON1);

      
        licznik=0;
  
        delay(20000);
        delay(20000);
        delay(20000);
        delay(20000);

        LcdInit();
        LcdClear();
        LcdSetCursor(0x0);
        LcdPrint("CZUJNIK TEMPERATURY");

        delay(20000);
        delay(20000);

        while( 1 )
        {
            // Czytaj?c IOPIN musimy zamaskowac tylko te piny ktUre nas interesuj?
            newButtonState = (~IOPIN0 & (BUTTON0 | BUTTON1));
            // negacja IOPIN ('~'), pozwala miec w zmiennej wcisniety klawisz reprezentowany 1
          
            // je˙li stan klawiszy siÕ zmieni? od ostatniego razu
            if (oldButtonState != newButtonState)
            {
                // po krotkim czasie (20ms)...
                delay(20000);
                // ... ponownie sprawdzamy stan ("debouncing")
                buttonState = (~IOPIN0 & (BUTTON0 | BUTTON1));
              
                // sprawdzamy czy nowy stan jest stabilny
                if(buttonState == newButtonState)
                {
                    // je˙li stan siÕ zmieni? i klawisze zosta?y oczyszczone
                    // 'debounced' (przez ponowne sprawdzenie po ustalonym czasie
                    // moona byE pewnym oe to rzeczywiste wci˙niecie klawisza
                    // a nie zak?Ucenie lub 'szpilka'
                  
                    //teraz obs?uga klawiatury
                    if(buttonState & BUTTON0 ) //je˙li SW0 nie jest wci˙niÕty
                    {
                        
                        licznik++ ;
                    }
                  
                    if(buttonState & BUTTON1 ) //je˙li SW1 nie jest wci˙niÕty
                    {
                        delay(300000);
                        process_temp_sensor_adc_interrupt();
                    }
                  
                    if(licznik ==1){
                        delay(300000);
                        LcdSetCursor(0x0);
                        LcdPrint("MANUAL");
                      
                        VICVectAddr0  = (unsigned int) &ADC_Isr; //ustawienia przrwania - ustawienie funkcji obs≥ugujacej przerwanie
                        VICVectCntl0  = 0x32;              // Channel0 on Source#18 ... enabled
                        VICIntEnable |= 0x40000;           // 18th bit is the ADC
                      
                    }
                    else if (licznik == 2){
                        delay(300000);
                        LcdSetCursor(0x0);
                        LcdPrint("AUTO");
                        process_temp_sensor_adc_polling();
                    }
                    else if (licznik>2){
                        licznik = 0;
                    }
                  
                }
              
                // przepisanie nowego stanu
                oldButtonState = buttonState;
            }
          
          
                }
      

        return 0;
}




Jednakże problem polega na tym... że to nie działa. Nie za bardzo tylko wiem w czym polega problem - czy w programie czy w może w jakiś połączeniach, które robię źle. Dlatego też moja ogromna prośba - jakby znalazł się ktoś, kto mógłby spojrzeć na ten kod i mniej więcej powiedzieć, czy jest poprawny (wiem, że bez debugowania na rzeczywistym urządzeniu może być ciężko, ale może ktoś na tyle się zna, że zauważy jakieś rażące błędy, których ja, kompletnie zielona osoba nie dostrzegam) byłabym ogromnie, ogromnie wdzięczna :)

Co więcej, nie działa już sam początek a mianowicie wysiwtlanie menu. W sensie wyswietla się napis "czujnik temperatury" , ale po przyciśnieciu przycisków nie zmieniają się napisy na te, które umiescilam w programie. Wydaje mi się, że coś pokręciłam z warunkami, ale próbując coś zmieniać.. dalej nie działało.
Pozdrawiam.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
biernik



Dołączył: 06 Wrz 2008
Posty: 1148
Skąd: 63°59'39''N 22°38'11''W

PostWysłany: Pon Sty 14, 2013 4:52 pm      Temat postu: Odpowiedz z cytatem Pisownia

Ciężko coś powiedzieć bo nie znam tego procka, ale ja bym zaczął od zmiany debouncingu z softwarowego na hardwarowy - czyli po prostu zwykły kondensatorek kilkadziesiąt nF w poprzek przycisku.
To powinno znacząco skrócić kod - będzie Ci się łatwiej połapać.
No i przynajmniej ja mam tak, że jak coś nie działa a wydaje się, że powinno, to w 90% okazuje się, że coś jest źle podłączone.

Aha, jeszcze jedna rzecz ze szklanej kuli:
Sprawdź czy nie masz tam jakiś stanów nieustalonych. Jak jest reprezentowane zero na przycisku, wysokim czy niskim stanem? Może wystarczy dorzucić pull up/down?

pzdr.

_________________
I like cheese.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
Wyświetl posty z ostatnich:   
Odpowiedz do tematu    Forum Coders' city Strona Główna -> Elektronika, programowanie niskopoziomowe Wszystkie czasy w strefie CET (Europa)

Strona 1 z 1

 
Skocz do:  
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Możesz dodawać załączniki na tym forum
Możesz pobierać pliki z tego forum




Debug: strone wygenerowano w 0.12544 sekund, zapytan = 11
contact

| Darmowe programy i porady Jelcyna | Tansze zakupy w Helionie | MS Office Blog |