logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[AVR] [ATMEGA8] [ASM] Przetwornik ADC

Pawel_361 25 Sty 2010 18:51 6606 43
REKLAMA
  • #1 7590551
    Pawel_361
    Poziom 17  
    Witam
    Walczę z przetwornikiem ADC w atmedze8.
    Napisałem prosty kod w asemblerze:
    
    rcall	initlcd
    rcall ustaw_ADC
    lop:
    sbi		adcsra,6
    czekaj_na_ADC:
    sbic	adcsra,6
    rjmp	czekaj_na_ADC
    in	r21,adcl
    rcall	LCDznak
    rjmp lop
    ustaw_ADC:
    	ldi	r25,0b00000101
    	out	admux,r25; kanał pomiaru 4
    	ldi	r25,0b11000011;
    	out	adcsra,r25; f/8
    	ret
    

    Do wejścia ADC5 mam podpięty środek potencjometra 47K przez rezystor 10K.
    Rezystor jest podpięty do 5V i masy.
    Wejście AREF jest podłączone do 5V.
    Zasilanie przetworników jest podłączone.

    Rejestr admux:
    bity 7 i 6 są ustawione na 00 - napięcie odniesienia na AREF
    bit 5 ustawiony na 0 - przesuń wynik do prawej (ADCL)
    bit 4 - bez znaczenia
    bity 3..0 ustawione na 0101 - pomiar z wejścia ADC5

    Rejestr adcsra:
    11000011;
    bit 7 ustawiony na 1 - włączony przetwornik
    bit 6 ustawiony na 1 - rozpocznij pierwszy pomiar
    bit 5 ustawiony na 0 - praca w trybie "pomiar na żądanie"
    bit 4 ustawiony na 0 - flaga przerwania wyłączona
    bit 3 ustawiony na 0 - przerwania wyłączone
    bity 2...0 ustawione na 011 - dzieli f/8
    Taktowanie procesora z wewnętrznego oscylatora 1mhz.
    Częstotliwośc powinna sie zawierać w granicach 50-200khz - 1000000/8 = 125khz

    Program odczytuje dane z ADCL i wysyła je na lcd jako kod znaku.
    Algorytm wysyłania znaku na lcd jest poprawny.
    Rozumiem, że w tym wydaniu na lcd powinny się pojawiać "krzaki" które zmieniają się po zmianie pozycji potencjometra.
    Problem w tym, że na lcd wyświetla się cały czas ten sam znak.
    Proszę o pomoc :(
  • REKLAMA
  • #2 7590566
    Konto nie istnieje
    Poziom 1  
  • #3 7590577
    Pawel_361
    Poziom 17  
    To tylko błędny komentarz - robiłem próby na różnych kanałach i na każdym to samo :(
  • #4 7590607
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #5 7590617
    Pawel_361
    Poziom 17  
    Zmienia się wtedy - dodałem jeszcze opóźnienie 1 sek aby to zaobserwować ;p
    Ale ta komenda tylko zwiększa zawartość R21 - chyba tylko po to aby przetestować wyświetlanie na lcd. Nie ma się w żaden sposób do odczytu wyniku przetwornika.

    Dodano po 2 [minuty]:

    Kurde Facet, jesteś wielki - działa ;d
    A teraz troche inne pytanie.
    Jak to oszlifować aby uzyskać cyfry na lcd ??
  • #6 7590747
    Konto nie istnieje
    Poziom 1  
  • #7 7590784
    Pawel_361
    Poziom 17  
    Hmm, szczerze mówiąc nie bardzo rozumiem co w rejestrach ADCL i ADCH zapisuje przetwornik a nie widzę w sieci dokładnych informacji na ten temat. Czy to jest wartość napięcia zapisana w formacie binarnym ??
  • #8 7590816
    rodzio
    Poziom 12  
    ADC=(1024*Vm)/Vref

    ADC - zawartość ADCH...ADCL
    Vm - napięcie na wybranym wejściu ADCn
    Vref - napięcie odniesienia
  • #10 7592125
    Pawel_361
    Poziom 17  
    Zgadza się. Moje przeoczenie.
    Mam jeszcze jedno pytanie.
    Docelowo wynik z ADC będzie dosuwany do lewej czyli do ADCH.
    Interesuje mnie wynik w formie 8 bitowej czyli pozostałe 2 bity w ADCL ignoruję.
    Aby otrzymać wartość w woltach przy napięciu referencyjnym 5V muszę 8bitową liczbę z ADCH pomnożyć przez ok 0.0195.
    Nie znalazłem nigdzie w sieci jak mnożyć w asemblerze przez ułamek.
    Czy mógłbym mi ktoś pomóc co dalej z tym robić ??
    Jak pomnożę liczbę z ADCH przez liczbę całkowitą i wynik operacji nie zmieści się na 8 bitach to co stanie się z wynikiem ??
  • #11 7592271
    Balu
    Poziom 38  
    W asmie nie ma liczb zmiennopozycyjnych :)
    A już na pewno nie w 8 bitowym avrze;)
    Trzeba sobie policzyć na stałoprzecinkowych.


    A jak wyjdzie poza granicę wynik, to zostanie obcięty;)
    Ale ze złej strony :)
  • #12 7592431
    Pawel_361
    Poziom 17  
    A jest jakiś algorytm, który w prosty sposób potrafi zmienić wynik z adc na postać bcd ??
  • #13 7592462
    rodzio
    Poziom 12  
    Można by kombinować, zamienić liczbę na ułamek i mnożyć i dzielić:) Przy pewnej stracie dokładności można by otrzymać jakiś wynik.
  • #14 7592506
    Balu
    Poziom 38  
    Oczywiście że jest;)
    bin2bcd ;) ale to chyba nie jest to końca to co byś chciał zobaczyć:)

    Rodzio nie truj koledze o ułamkach w asmie bo to wtedy nie są ułamki tylko byte'y i jego wielokrotności, tak czy siak;)
  • #15 7592532
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #16 7593109
    Pawel_361
    Poziom 17  
    Wyżej napisałem, że to tylko błędny komentarz.

    Balu, wynik z ADC muszę najpierw pomnożyć przez 0.0195 a później zamienić na BCD aby otrzymać wynik w woltach. Zgadza się ??
  • REKLAMA
  • #17 7593139
    Balu
    Poziom 38  
    Nie jestem pewien co do wartości (nie mówię, że jest zła), ale tak:)
    Tylko zabierasz się do tego jak pies do jeża;)
    Naucz się raz na zawsze że nie korzysta się z floatów, chyba, że jest to bezwzględnie koniecznie...wtedy...analizujesz projekt i dochodzisz do wniosku, że...nie korzysta się z floatów...Jeśli jednak wciąż chcesz użyć float'a, może masz jeden z 0,001% przypadków kiedy to jest koniecznie, bądź też... źle przemyślałeś założenia.

    Anyway pomnóż przez 10000 swój wynik (w pamieci:P) i zobacz jak ta liczba wygląda bez przecinka;)
    pomnóż ją przez tyle ile uznasz po przemyśleniach za stosowane a następnie dzieląc rób całkowite do przecinka potem wstaw przy wyświetlaniu przecinek bo jestes programistą i wiesz gdzie on ma się znaleźć, a następnie... dopisz liczbę po przecinku która również jest całkowita;)

    Reszta twojej inwencji pozostawiona;)
  • #18 7593183
    Pawel_361
    Poziom 17  
    Dopiero zaczynam programować, więc słowo programista jest chyba za duże a słowo float kojarzy mi sie co najwyżej z wodą :P

    Używając słowa wynik masz na myśli zawartość komórki ADCH w moim przypadku ??
  • #20 7593233
    Pawel_361
    Poziom 17  
    Balu napisał:

    Anyway pomnóż przez 10000 swój wynik (w pamieci:P) i zobacz jak ta liczba wygląda bez przecinka;)


    Aktualnie na lcd wypluwa mi literki G więc po ascii widzę, że w przetworniku jest 01000111. Po przeliczeniu to liczba 71 i nie widzę w niej przecinka :P.
    Mnożę przez 0.0195 i wynik to ok 1.38V i po sprawdzeniu miernikiem wynik się zgadza.
  • #22 7593309
    Pawel_361
    Poziom 17  
    O ile dobrze wiem to do mnożenia służy komenda MUL.
    A wynik jest równy 13845 i nie da sie go zapisac na 8 bitach i w tym momencie nie wiem co dalej robić ;/
  • #24 7593339
    rodzio
    Poziom 12  
    Poszukaj w instrukcji czegoś takiego jak X Y Z :) Na pewno Ci pomogą w tym zadaniu:)
  • #25 7593341
    Pawel_361
    Poziom 17  
    Dzieki za pomoc ;p moze sobie dam jakos rade ;p
  • #26 7593368
    Balu
    Poziom 38  
    Jak znajdziesz sobie gdzies stronę która jest zawarta w tym pdfie: http://www.scribd.com/doc/11057004/AVR-assembly-Examples#about
    To tam masz "biblioteki do asma" chyba najlepszy taki zbiór w necie.
    Niestety nie udało mi się znaleźć strony właściwej tylko ten pdf czy co to jest...
  • #27 7593371
    Pawel_361
    Poziom 17  
    No wiem, że są to rejestry 16bitowe.
    Mam jednak jeszcze jedno pytanie.
    W sytuacji, gdy w adch jest wartość 1111 1111 = 256
    po pomnożeniu dostanę wynik 49920 a ten już się nie zmieści na 16 bitach.
    Trzeba zmniejszyć tą stałą 195 kosztem dokładności czy jest jeszcze jakiś inny trick ??
  • #28 7593381
    rodzio
    Poziom 12  
    Ja polecam, pierw mnożyć przez mniejszą liczbę i dzielić, tak kolejno na zmianę, żeby nie ucięło nam przodu.

    Hmm chociaż można by to jeszcze ręcznie robić na 3 rejestrach:)
  • #29 7593387
    Pawel_361
    Poziom 17  
    Zdaje się, że to ta strona.

    Dodano po 5 [minuty]:

    Dzielenie wykonam poleceniem DIV ??
  • #30 7593548
    Balu
    Poziom 38  
    Pawel_361 napisał:

    W sytuacji, gdy w adch jest wartość 1111 1111 = 256

    Bzdura!
    Pawel_361 napisał:

    po pomnożeniu dostanę wynik 49920 a ten już się nie zmieści na 16 bitach.

    Bzdura!

    Co to div? skrót od divide lub czegoś w ten deseń:P
REKLAMA