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

[AtMega8][C] Zewnętrzny ADC po SPI - błędne bajty.

Adam Pyka 24 Maj 2010 16:24 1698 2
REKLAMA
  • #1 8112624
    Adam Pyka
    Poziom 19  
    Witam!

    Mam problem z odczytem z zewnętrznego przetwornika ADC TLV2556 po SPI z AtMegi8.
    Konfiguruję przetwornik do pracy 8-bitowej, MSB first, unipolar.
    Potem wysyłam komendy testowania przetwornika, i pierwszy odczytany test (pierwszy bajt) jest ok, natomiast kolejne są błędne i wynoszą 47(dec).

    Poniżej fragment listingu programu:

    
    // DEFINICJE WYCIĄŁEM
    
    int main(void)
    {
    	//sets direction on PORTS
    	DDRB = 0b00101101;
    	DDRC =  0b00111111;
    	DDRD =  0b11110010;
    	//set state on ports
    	PORTB = 0b00000100; // SS default high (chip disabled)
    	PORTC = 0b00001111; //backlight default enable
    	PORTD = 0b11111000;
    	lcdInit();
    	//global interrupts on
    	SREG |= (1<<7);
    	lcdClear();
    	
    //********** test SPI ******************************
    // Enable SPI, Master, set clock rate fck/128
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
    
    // TRANSMIT
    char wynik1;
    char wynik2;
    
    //RAMKA 1 - inicjalizacja
    cbi(PORTB, PB2);
    _delay_us(1);
    //inicjalizacja ADC
    SPDR = 0xF0;
    // Wait for transmission complete
    while(!(SPSR & (1<<SPIF)));
    _delay_us(1);
    sbi(PORTB, PB2);
    _delay_ms(1);
    //poczekaj na ukonczenie konwersji adc
    while(!(PIND & (1<<2)));
    lcdMessage("OK ramka 1");
    
    //RAMKA 2 - wysłanie komendy test1 (połowa napięcia referencyjnego = 128)
    cbi(PORTB, PB2);
    _delay_us(1);
    //wysłanie ramki test 1
    SPDR = 0xB4;
    // Wait for transmission complete
    while(!(SPSR & (1<<SPIF)));
    _delay_us(1);
    sbi(PORTB, PB2);
    _delay_ms(1);
    //poczekaj na ukonczenie konwersji adc
    while(!(PIND & (1<<2)));
    lcdMessage("OK ramka 2");
    
    //RAMKA 3 - wysłanie komendy test2 (dolne napięcie referencyjne = 0)
    cbi(PORTB, PB2);
    _delay_us(1);
    //wysłanie ramki test 2
    SPDR = 0xC4;
    // Wait for transmission complete
    while(!(SPSR & (1<<SPIF)));
    _delay_us(1);
    sbi(PORTB, PB2);
    _delay_ms(1);
    //poczekaj na ukonczenie konwersji adc
    while(!(PIND & (1<<2)));
    lcdMessage("OK ramka 3");
    wynik1 = SPDR; //zapamiętaj wynik 1 (połowa nap. ref.)
    
    //RAMKA 4 - wysłanie komendy test3 (górne napięcie referencyjne = 255)
    cbi(PORTB, PB2);
    _delay_us(1);
    //wysłanie ramki test 3
    SPDR = 0xD4;
    // Wait for transmission complete
    while(!(SPSR & (1<<SPIF)));
    _delay_us(1);
    sbi(PORTB, PB2);
    //poczekaj na ukonczenie konwersji adc
    while(!(PIND & (1<<2)));
    lcdMessage("OK ramka 4");
    wynik2 = SPDR; //zapamiętaj wynik 2 (dolne nap. ref)
    
    
    // DISPLAY VALUES
    
    //teraz można odczytać - powinno wyść 128 i jest 128(dec) - tutaj ok
    lcd_set_int16((uint16_t) wynik1,1);
    //teraz można odczytać - powinno wyść 0, a jest 47(dec) - tutaj źle...
    lcd_set_int16((uint16_t) wynik2,3);
    
    while(1);
    } //main


    Sprawdzałem różne kombinacje, różne kanały przetwornika i zawsze pierwszy odczyt jest ok, a kolejne są błędne. Co robię nie tak?

    Pozdrawiam,
    Adam Pyka
  • REKLAMA
  • Pomocny post
    #2 8115073
    Paweł Sroka
    Poziom 1  
    Toż błąd widać jak na dłoni ;-)
    Kolega nie czeka po wysłaniu bajtu na rozpoczęcie konwersji i łapie od razu stan wysoki na linii EOC zanim zostanie ona ściągnięta na dół (warto się przyjrzeć timingom, że taka sytuacja jest bardzo realna). Linia potem jest przez pewną chwilę w dole, więc nic nie kosztuje dodać przed linijką:
    //poczekaj na ukonczenie konwersji adc
    while(!(PIND & (1<<2))); 


    jeszcze linię czekania na opuszczenie linii w dół
    while((PIND & (1<<2))); 


    Chyba powinno pomóc jeśli się nie narobi po drodze błędów ;-)

    Pozdrawiam.
  • #3 8116999
    Adam Pyka
    Poziom 19  
    Dziękuję za odpowiedź!

    Rozwiązaniem było dopisanie pętelki z oczekiwaniem na opuszczenie linii w dół.

    Pozdrawiam,
    Adam Pyka
REKLAMA