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

[AVR-GCC] TWI sprzętowe - potwierdzenie adresu

gothye 10 Sie 2009 13:12 2242 7
  • #1 6876507
    gothye
    Poziom 33  
    Witam

    chciałbym napisać mały program poszukujący układy na sprzętowym interfeisie TWI w procesorze AVR [m32]. więc napisałem to :

    unsigned char error ;
    void TWI_sla_rw (unsigned char adres, unsigned char rw) 
    { 
     TWDR = ((adres<<1) | rw); 
     TWCR |= _BV(TWINT) | _BV(TWEN); 
    
     while (!(TWCR & (1<<TWINT)));{} 
    
     if ((TWSR&0xF8)!=0x40)                       //sprawdzenie odebrania ACK 
      { 
             error = 1 ; 
      }  
    }


    ale kiedy podaje adres slave którego napewno nie ma ,zmienna error nie ulega zmianie ,czemu ?
  • #2 6876798
    m.bartczak
    Poziom 16  
    Hmm...

    Przeglądałem protokół i z tego co widzę to powinien on wyglądać tak:

    
    TWCR |= _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);  // Tryb Master
    while (!(TWCR & (1<<TWINT))); // Czekamy na przesłanie START
    if ((TWSR & 0xF8) != START) ERROR(); // Sprawdzamy czy START został przesłany
    TWDR = ((adres<<1) | rw); // Przesyłamy albo master write albo master read
    TWCR = (1<<TWINT) | (1<<TWEN); // Rozpoczynamy transmisję
    while (!(TWCR & (1<<TWINT))); // Czekamy na zakończenie transmisji
    // i teraz...
    if ((TWSR & 0xF8) != MT_SLA_ACK) ERROR(); // sprawczamy czy mamy ACK czy NACK
    
  • #3 6877223
    gothye
    Poziom 33  
    zastosowałem się do Twojego kodu ,i teraz zwraca mi zmienną = 1 ,dla prawidłowego adresu również :(
  • #5 6877519
    m.bartczak
    Poziom 16  
    Możesz podrzucić kod którego teraz używasz? Tak z ciekawości...

    UPDATE czemu:

    a) unsigned char error; // Powinno być volatile
    b) Jak i kiedy inicjalizujesz error na 0?
  • #7 6877706
    m.bartczak
    Poziom 16  
    "Przydomek volatile wyłącza stosowaną przez kompilator optymalizację w stosunku do zmiennej. Używa się go wtedy, gdy dana zmienna jest modyfikowana przez nieznaną kompilatorowi formę (np. funkcję przerwania, itp.)."

    Zawsze to ustawiam aby nie pozwolić GCC na bycie 'za mądrym'.

    Przykład - mój kod w poście: [Atmega16][C] Menu - obsługa przycisków

    Bez użycia volatile w liniach:
    
    volatile struct Work state;
    volatile struct Menu menu;
    


    aplikacja nie działa :) Kod poniżej zostaje brutalnie zoptymalizowany do punktu nie działania:

    
    	while(1)
    	{
    		// A tutaj znajduje się obsługa klawiszy
    		if((PINB & 0x1)==1)
    		{
    			if(menu.state!=MENU_STATE_NORMAL)
    			{
    				menu.state = MENU_STATE_REDRAW_INFO;
    			}
    		} else {
    			if(menu.state!=MENU_STATE_MENU_DISPLAYED)
    			{
    				menu.state = MENU_STATE_DISPLAY_MENU;
    			}
    		}
    	}
    
  • #8 6877996
    gothye
    Poziom 33  
    Jak zwykle sam sobie odpowiedziałem na pytanie :)

    >>>Freddie Chopin Nie sądziłem ze napiszesz ,a przecież nic niewiesz ?!
REKLAMA