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

[Mega32][C] Programowe I2C.

zureczq 13 Kwi 2009 15:43 1348 3
REKLAMA
  • #1 6409684
    zureczq
    Poziom 2  
    Witam, chciałbym się zapytać czy mógłby znawca w tym temacie rzucić okiem i powiedzieć co mniej więcej jest źle w tym kodzie(staralem sie pisać zgodnie z standardem i2c. Wiem że atmega32 ma sprzętowe TWI ale moim zadaniem jest napisanie programowego co niestety sprawia mi trudnosci. Mianowicie układ przy wysłaniu adresu zwraca mi 1(NACK)


    void twi_init()
    {
    	//Ustawienie lini jako wyjscie
    	D_TWI|=(1<<SCL)|(1<<SDA);
    	//zwolnienie lini
    	P_TWI|=(1<<SCL)|(1<<SDA);
    }
    void start_twi(void)		//Funkcja wysylajaca bit startu
    {
    	P_TWI|=(1<<SCL)|(1<<SDA);
    	_delay_us(5);
    	P_TWI&=~(1<<SDA);		
    	_delay_us(5);
    	P_TWI&=~(1<<SCL);
    	
    }
    void stop_twi(void)			// Funkcja wysylajaca bit stopu
    {
    	P_TWI&=~((1<<SCL));	
    	P_TWI&=~((1<<SDA));
    	_delay_us(5);
    	//Generowanie bitu stopu
    	P_TWI|=(1<<SCL);
    	_delay_us(5);
    	P_TWI|=(1<<SDA);
    	_delay_us(5);
    }
    
    
    unsigned char send_8b(unsigned char DATA)
    {
    
    
    	for(int i = 7 ; i >0 ; i--)	//Petla wysylajaca 8 bitow 
    	{	
    
    
    		if(DATA&(1<<i))		//jezeli 1 to wysli 1 a jezeli 0 to wysli 0
    		{
    			P_TWI|=(1<<SDA);	
    		}
    		else
    		{
    			P_TWI&=~(1<<SDA);
    		}
    		_delay_us(5);
    		P_TWI|=(1<<SCL);
    		_delay_us(4);	// minimalny czas trwania poziomu 1 danych 4
    
    		P_TWI&=~(1<<SCL);
    //		_delay_us(5);	// minimalny czas trwania poziomu 0 danych 4.7
    	}
    	//Ustawienie jako wejscie aby odczytac ACK lub NACK
    	P_TWI|=(1<<SDA);
    	D_TWI&=~(1<<SDA);
    	
    	_delay_us(5);
    
    	// Ustawienie zegara na wysoki stan
    	P_TWI|=(1<<SCL);
    	
    	//Sprawdzenie jaki sygnal generuje SLAVE ACK lub NACK	
    	if((I_TWI&(1<<SDA)))	
    		ACK_TWI=1;
    	else
    		ACK_TWI=0;
    
    	_delay_us(5);
    
    
    	P_TWI&=~(1<<SCL);		//zegar w niskim poziomie
    
    	D_TWI|=(1<<SDA);	//ustawienie portu jako wyjscie
    
    	_delay_us(5);
    
    	//Funkcja zwraca potwierdzenie 0 ACK 1 NACK	
    	return ACK_TWI;
    }


    Poprawiłem tytuł - Regulamin. [c_p]
  • REKLAMA
  • REKLAMA
  • #3 6414557
    zureczq
    Poziom 2  
    o to i makra



    
      #define SCL     0       // Zegar
      #define SDA     1       //Data
    
      #define D_TWI		DDRD
      #define P_TWI		PORTD
      #define I_TWI		PIND
    
  • #4 6420165
    arturt134
    Poziom 27  
    Linie wolne (po zakończeniu nadawania lub inicjalizacji) to nie mogą być wyjścia w stanie wysokim, tylko wejścia z podciągnięciem.

    Weź oscyloskop i obejrzyj przebiegi. Jak nie masz oscyloskopu, to spróbuj analizując kod narysować na kartce papieru przebiegi i porównać z tymi w specyfikacji. To naprawdę pomaga.

    Sprawdź adres urządzenia - może tu jest jakaś pomyłka?
REKLAMA