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

[Atmega][C] Touch panel odczyt 2 współrzędnych

krzysiekk_20 18 Lip 2011 07:47 2210 9
REKLAMA
  • #1 9730150
    krzysiekk_20
    Poziom 12  
    Witam,

    Ma panel dotykowy 4-przewodowy. Czytałem dokumentację atmela AV341 ale mam pewien problem. Chodzi o to że gdy chę odczytać dwie współrzędne w programie to nic mi nie mierzy. Jak wyłączę którąś z nich to wszystko jest ok i pomiar jest dobry. Nawet gdy mam tylko rozpoznawanie dotyku a potem odczyt x i y to i tak działa tylko odczyt dotyku i jedna oś. Nie wiem czy są dobrze ustawione porty. Próbowałem nawet przez tranzystory zasilać np X+ a jeden kanał adc do masy programowo, drugi do ADC na pomiar(chodziło o to by był HiZ gdy nie zasilam odpowiedniego kanału). I też mierzy dobrze tylko gdy jest jeden kanał.

    
    void gadc_x(void)
    {
    ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0);// wybór kanału ADC1
    DDRD |=_BV(5);
    DDRA |=_BV(0);
    PORTA &=~_BV(0);
    PORTD &=~_BV(5);
    ADCSRA|=(1<<ADSC)|(1<<ADEN); //start
    }
    void gadc_y(void)
    {
    ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);// wybór kanału ADC0
    DDRD |=_BV(5);
    DDRA |=_BV(1);
    PORTA &=~_BV(1);
    PORTD |=_BV(5);
    ADCSRA|=(1<<ADSC)|(1<<ADEN); //start
    }
    


    a tutaj w main oraz for:
    
    ADMUX|=(1<<REFS0)|(0<<REFS1); //Avcc z zewn kond przy Aref
    ADMUX|=(0<<ADLAR); //bez przesuniecia w rejestrach ADCH i ADCL
    ADCSRA|=(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
    volatile uint8_t Low,High; 
    volatile uint16_t wynik;
    double nap,x,y;
    
    
    gadc_x();
    _delay_ms(5);
    Low=ADCL; 
    High=ADCH;
    wynik=High<<8;
    wynik=wynik|Low;
    x=(wynik*5.05)/1024;
    //gadc_y();
    _delay_ms(5);
    Low=ADCL; 
    High=ADCH;
    wynik=High<<8;
    wynik=wynik|Low;
    y=(wynik*5.05)/1024;
    


    wydłużanie opóźnień też nic nie daje
  • REKLAMA
  • REKLAMA
  • #3 9730642
    krzysiekk_20
    Poziom 12  
    Tak jest zaremowana bo akurat taką wersję wrzuciłem. Ale obojętnie którą zaremuję to ta druga będzie działać. Problem jest jak są dwie w programie. Nawet jeśli usunę opóźnienie i dam najpierw przepisanie wartości to nic nie zmieni. Jęsli mam np tylko roapoznawanie osi X to napięcie zmienia się od 0.5 do 4.6V a jak ddam dwie osie to już od 0.01 do 0.12V. Podobnie jest z drugą osią jak jest sama.
    Mam podłączone na Atmega32:
    PA0 X+
    PA1 Y+
    PA2 X-
    Pa3 Y-
    kanały ADC są sprawne. Tak samo mam na inny AVR.
    W powyższym przykładzie podłączone są PA0 i PA1 a dwa pozostałe do jednego portu przez dwa równoległe tranzystory PNP i NPN. To z tego portu daję zasilanie 5V lub 0V więc działa jeden albo drugi tranzystor. Zmiany polaryzacji X+ i X- nie mają wpływu bo to w zasadzie dzielnik rezystancyjny.
  • REKLAMA
  • REKLAMA
  • #6 9787190
    krzysiekk_20
    Poziom 12  
    To zacznę jeszcze raz od nowa. Podłaczenie jest bezposrednio do nóżek Atmega32 bez żadnych rezystorów dodatkowych tak jak w nocie AVR341..
    PA0 X+
    PA1 Y+
    PA2 X-
    Pa3 Y-

    A oto cały mój kod programu:
    
    #include <avr/io.h>
    #include <stdio.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <string.h>
    #include "hd44780.h"
    #define F_CPU 16000000UL 
    
    char buf[30];
    double nap,x,y;
    
    void gadc_x(void)
    {
    
    DDRA |=_BV(0);
    DDRA |=_BV(2);
    DDRA &=~_BV(3);
    PORTA |=_BV(0);
    PORTA &=~_BV(2);
    //PORTA &=~_BV(3);
    ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0)|(1<<REFS0)|(0<<REFS1)|(0<<ADLAR);// wybór kanału ADC1
    ADCSRA|=(1<<ADSC)|(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);; //start
    volatile uint8_t Low,High; 
    volatile uint16_t wynikx;
    _delay_ms(1);
    while(ADCSRA & (1<<ADSC));
    Low=ADCL; 
    High=ADCH;
    wynikx=High<<8;
    wynikx=wynikx|Low;
    x=(wynikx*5.05)/1024;
    }
    void gadc_y(void)
    {
    DDRA |=_BV(1);
    DDRA |=_BV(3);
    DDRA &=~_BV(2);
    PORTA |=_BV(1);
    PORTA &=~_BV(3);
    //PORTA &=~_BV(2);
    ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0)|(1<<REFS0)|(0<<REFS1)|(0<<ADLAR);// wybór kanału ADC0
    ADCSRA|=(1<<ADSC)|(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);; //start
    volatile uint8_t Low1,High1; 
    volatile uint16_t wyniky;
    _delay_ms(1);
    while(ADCSRA & (1<<ADSC));
    Low1=ADCL; 
    High1=ADCH;
    wyniky=High1<<8;
    wyniky=wyniky|Low1;
    y=(wyniky*5.05)/1024;
    }
    
    
    
    int main (void)
    {
    lcd_init();
    LCD_DISPLAY(LCDDISPLAY);
    LCD_CLEAR;
    lcd_puts("ok");
    sei();
    
    for(;;)
    {
    
     
    LCD_CLEAR;
    lcd_puts(tab);
    
    gadc_x();
    _delay_ms(1);
    gadc_y();
    _delay_ms(1);
    
    sprintf(tab,"%1.2f""V  ""%1.2f""V",x,y);
    
     _delay_ms(100);
    }
    
    return 0;
    }


    I cały problem tkwi w tym, że jak są dwie funkcje gadc_x i gadc_y to wartości napięć się nie zmieniają. Jak wyremuję jedną z nich to wszystko jest ok tj. jak będzie np //gadc_x(); to oś Y jest odczytywana prawidłowo. Przy dwóch napięcia się praktycznie nie zmieniają.

    Sugerowałem się postem:
    https://www.elektroda.pl/rtvforum/topic1893890.html#9061704
  • #7 9787203
    piti___
    Poziom 23  
    Jeśli ADMUX służy do wybierania kanału to czy czasem w obu funkcjach nie masz wybieranego tego samego kanału ?
    ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0)|(1<<REFS0)|(0<<REFS1)|(0<<ADLAR);

    Do tego jeśli będziesz przełączał kanały uważaj na "OR |" w ADMUX|=

    Przesuwanie zera (0<<MUX0) i sumowanie go do tego co jest już w ADMUX nic nie da.
  • #8 9787535
    krzysiekk_20
    Poziom 12  
    Kanały ADC nie są te same, różnią się - bit MUX0. Poza tym pojedyńcze funkcje działają dobrze.
  • #9 9787543
    piti___
    Poziom 23  
    Oczywiście że nie są te same. Jednak twój zapis "ADMUX|=" spowoduje wybranie jeszcze innego kanału.

    Napisz "ADMUX =" zamiast "ADMUX|=". I zastanów się dlaczego.
  • #10 9788127
    krzysiekk_20
    Poziom 12  
    Ok poprawiłem. Ale problem jest dalej i nie jest to wina panelu bo sprawdzałem na rezystorach. To samo. Zapisywałem też w ten sposób ADMUX = 0b01000000 i ADMUX = 0b01000001. Nic
REKLAMA