f
Warning: Cannot modify header information - headers already sent by (output started at /home/anderian/ftp/www_forum/db/mysql4.php:1) in /home/anderian/ftp/www_forum/includes/sessions.php on line 548

Warning: Cannot modify header information - headers already sent by (output started at /home/anderian/ftp/www_forum/db/mysql4.php:1) in /home/anderian/ftp/www_forum/includes/sessions.php on line 549

Warning: Cannot modify header information - headers already sent by (output started at /home/anderian/ftp/www_forum/db/mysql4.php:1) in /home/anderian/ftp/www_forum/includes/page_header.php on line 343
And-Tech :: Zobacz temat - ADC - brak danych w pełnym zakresie potencjometru

Strona korzysta z plików cookie w celu realizacji usług zgodnie z Politykš prywatnoœci.

Możesz okreœlić warunki przechowywania lub dostępu do cookie w Twojej przeglšdarce lub konfiguracji usługi.

And-Tech Strona Główna And-Tech
Forum firmy And-Tech

FAQFAQ  SzukajSzukaj  UżytkownicyUżytkownicy  GrupyGrupy
RejestracjaRejestracja  ZalogujZaloguj  AlbumAlbum  DownloadDownload

Poprzedni temat «» Następny temat
ADC - brak danych w pełnym zakresie potencjometru
Autor Wiadomość
Pawlo 

Dołączył: 07 Lut 2014
Posty: 12
Wysłany: Pon Kwi 21, 2014 8:27 pm   ADC - brak danych w pełnym zakresie potencjometru

Mam mały problem z ADC. Mianowicie nie działa mi do końca ADC tak jakbym chciał. Nie bardzo też potrafię wytłumaczyć sam przed sobą dlaczego tak właśnie jest.
Otóż otrzymuję wartości od 0 - 1023 jednak nie w pełnym zakresie potencjometru. Kręcąc potencjometrem od 0 w kierunku MAX dopiero (mniej więcej) w połowie zakresu potencjometru zaczynają pojawiać się wartości. Tłumaczę to sobie (nieudolnie) napięciem ref 2.56V (w przybliżeniu połową 5V).
Przeglądając (testując program) przykład dostarczony z płytką ADC_PWM widać że w całym zakresie potencjometru jest reakcja "diody". Niestety, ale programy przykładowe do płytki nie do końca są dla mnie zjadliwe.
Oczywiście płytka jest "niezmienna sprzętowo" :smile:
Czy ktoś może na podstawie załączonego kodu coś podpowiedzieć :?:

Kod:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <util/delay.h>

#include "MYUART/myuart.h"

uint16_t pomiar (uint8_t kanal);

#define REF_256 (1<<REFS1)|(1<<REFS0)
#define REF_VCC (1<<REFS1)|(0<<REFS0)

int main(void){

    //inicjalizacja ADC
    ADCSRA |= (1<<ADEN);    //włączenie ADC
    ADCSRA |= (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);    //preskaler = 32

    ADMUX |= REF_256;    //ustawiamy wewn. żródlo odniesienia 2,56V

        USART_Init(__UBRR);

    uint16_t WynikADC=0;

    int czas = 400;

    while (1){


        WynikADC = pomiar ( PA1 );

        uart0_putlong (WynikADC, 10);

           _delay_ms(czas);
    }

uint16_t pomiar (uint8_t kanal)
{
    ADMUX |= (ADMUX & 0b11111000) | kanal;
    ADCSRA |= (1 << ADSC);    // start konwersji

    while (ADCSRA & (1 << ADSC) );

    return ADCW;    //ADCW - funkcja pozwalająca na odczyt dwóch bitów z danymi (odpowiednio przekonwertuje pozrzucane bity)
}


P.S.
Starałem się pousuwać z programu to co nie istotne w przedstawionym problemie. Mogłem coś usunąć z rozpędu - program tak czy siak działa.
 
     
piotr94 
Site Admin

Dołączył: 02 Lut 2010
Posty: 606
Skąd: Kraków
Wysłany: Pon Kwi 21, 2014 8:45 pm   

Witam,
Polecam zapoznanie się z nowymi programami - ten dla ADC będzie bez problemu działał zarówno na płytkach 4.3 jak i 5.1:
http://and-tech.pl/zestaw-evb-5-1/
_________________
http://www.piotr94.net21.pl/
 
     
Pawlo 

Dołączył: 07 Lut 2014
Posty: 12
Wysłany: Nie Kwi 27, 2014 2:30 pm   

Znacznie lepiej wyglądają te nowe programy - dla mnie zdecydowanie bardziej przyswajalne :wink:
Jednak do rzeczy.
Przeanalizowałem przykładowy kod i swój, i nie bardzo widzę co może być źle. Zmieniłem cześć kodu odnoszącą się do Vref
Kod:
ADMUX |= (1<<REFS0);//ustawiam napięcie odniesienia na AVCC (napięcie zasilania układu ~5V)

jednak nie widzę różnicy w działaniu. Wg noty technicznej powinienem połączyć AVCC z Aref przez kondensator
Cytat:
AVCC with external capacitor at AREF pin
Czy tak to ma być :?: W dokumencie do przykładowych projektów nic nie jest wspomniane na ten temat. Jeżeli tak to jaka pojemność kondensatora :?:
Chyba że nie tędy droga :?:

Zauważyłem przez przypadek, że po maksymalnym rozkręceniu potencjometru wartość którą dostaję to ok 839 i jeżeli nie zmieniam ustawień, to wartość ta samoczynnie rośnie. nie wiem do ilu jest w stanie urosnąć, ale ja doszedłem do ponad 900. Może to coś pomoże w rozwiązaniu :wink:
 
     
piotr94 
Site Admin

Dołączył: 02 Lut 2010
Posty: 606
Skąd: Kraków
Wysłany: Wto Kwi 29, 2014 7:06 pm   

Pokaż cały program jeszcze raz, w takiej wersji jak masz teraz.
_________________
http://www.piotr94.net21.pl/
 
     
Pawlo 

Dołączył: 07 Lut 2014
Posty: 12
Wysłany: Sob Maj 03, 2014 10:06 am   

Nie ma problemu
Kod:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <util/delay.h>

#include "MYUART/myuart.h"
#include "MYLCD/mylcd.h"

uint16_t pomiar (uint8_t kanal);

#define REF_256 (1<<REFS1)|(1<<REFS0)
#define REF_VCC (1<<REFS1)|(0<<REFS0)
#define REF_5V (0<<REFS1)|(1<<REFS0);//ustawiam napięcie odniesienia na AVCC (napięcie zasilania układu ~5V)

#define LED (1<<PC1)
#define LED_ON PORTC |= LED
#define LED_OFF PORTC &= ~LED
#define LED_TOG PORTC ^= LED
#define LED1 (1<<PC0)
#define LED1_ON PORTC |= LED1
#define LED1_OFF PORTC &= ~LED1
#define LED1_TOG PORTC ^= LED1

int main(void){

    DDRC |= LED;
    DDRC |= LED1;

    //inicjalizacja ADC

    //ADCSRA |= (0<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);    //preskaler = 4
    //ADCSRA |= (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);    //preskaler = 8
    //ADCSRA |= (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);    //preskaler = 16
    //ADCSRA |= (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);    //preskaler = 32
    ADCSRA |= (1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);//ustawienie prescalera na 128 = częstotliwość taktowania 125kHz

    ADMUX |= REF_5V;    //ustawiamy wewn. żródlo odniesienia
    ADCSRA |= (1<<ADEN);    //włączenie ADC

    USART_Init(__UBRR);

    DDRA = 0xFF; //dotyczy portu A na którym siedzi wyswielacz

    char buf[50];

    uint16_t WynikADC=0;

    int czas = 400;

    lcd_init();         //inicjalizacja LCD
    lcd_xy(0,0);
    write_text("z ADC:");
    lcd_xy(1,0);
    write_text("z RS232:");

    while (1){

        WynikADC = pomiar ( PA1 );

        sprintf(buf,"%04d",WynikADC);//konwertuję go na ciąg znaków i dopisuję zera
        lcd_xy(0,9);
        write_text(buf);

        LED_TOG;

        uart0_putlong (WynikADC, 10);

        _delay_ms(czas);
    }
}

uint16_t pomiar (uint8_t kanal)
{
    ADMUX |= (ADMUX & 0b11111000) | kanal;
    ADCSRA |= (1 << ADSC);    // start konwersji

    while (ADCSRA & (1 << ADSC) );

    return ADC;    //ADCW - funkcja pozwalająca na odczyt dwóch bitów z danymi (odpowiednio przekonwertuje  pozrzucane bity)
}


Mam nadzieję że coś wykryjesz :wink:
 
     
Pawlo 

Dołączył: 07 Lut 2014
Posty: 12
Wysłany: Sob Maj 10, 2014 4:20 pm   

Po bojach i walkach i braku podpowiedzi doszedłem do rozwiązania :grin:

Otóż rozwiązanie tego problemu był "proste". W oryginalnym kodzie na porcie A działał wyświetlacz LCD (7 pinów) i na jednym (ostatnim wolnym) pinie było zadeklarowane odczyt ADC. Testując, przełożyłem obsługę wyświetlacza na inny port. Teraz działa prawidłowo :grin:

Moje wytłumaczenie jest takie, że w programie miałem zadeklarowany cały port jako wyjścia.
Kod:
    DDRA = 0xFF; //dotyczy portu A na którym siedzi wyświetlacz

Zakładam, że wystarczyło wprowadzić prawidłową wartość (szesnastkową w powyższym kodzie) aby pin, na którym jest pomiar ustawić jako wejście. Swoją drogą jest to (dla mnie) dziwne, że nawet przy błędnym ustawieniu portu pojawiały się jakieś wskazania :!: .
 
     
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie 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
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group