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

[Attiny2313][C] i2c - procesor <-> przetwornik pcf8591

dan50 11 Lut 2011 00:10 1919 4
REKLAMA
  • #1 9134401
    dan50
    Poziom 12  
    Witam. Mam taki problem z magistralą i2c a dokładnie z funkcjami. Na zajęciach programowałem 8051 w c i teraz ten sam kod przerabiałem tak aby działał pod attiny2313 (pisze w WinAvr). Bit startu/stopu działa - program przechodzi dalej i zatrzymuje się na wysyłaniu kodu urządzenia - adres jeszcze przechodzi prawidłowo. Poniżej zamieszczam fragmenty kodu:

    deklaracje:
    #define I2CDIR DDRD
    #define I2COUT PORTD
    #define I2CIN  PIND
    
    #define SDA 6
    #define SCL 5
    
    #define SET_SDA I2COUT |= (1 << SDA)
    #define CLR_SDA I2COUT &= ~(1 << SDA)
    
    #define SET_SCL I2COUT |= (1 << SCL)
    #define CLR_SCL I2COUT &= ~(1 << SCL)
    
    #define SDA_OUT I2CDIR |= (1 << SDA)
    #define SDA_IN I2CDIR &= ~(1 << SDA)
    
    #define SCL_OUT I2CDIR |= (1 << SCL)
    #define SCL_IN I2CDIR &= ~(1 << SCL)
    
    #define GET_SDA (I2CIN & (1 << SDA))


    zapis i odczyt:

    void I2C_WRITE(unsigned char licz_wys) 		//licz_wys wartoć liczby wysyłaniej na I2C
    {
     	char x;
    	SDA_OUT; 
    	SCL_OUT; //ustawienie lini sda i scl jako wyjscie
    
     	for(x = 8  ; x > 0 ;x--)
     	{
    		CLR_SCL;
     		if( ( ( licz_wys>>(x-1) ) & 1 ) )
    			{
    			SET_SDA;
    			}
    		else
    			{
    			CLR_SDA;
    			}
    		SET_SCL;	
     	}
    	
     	CLR_SCL;
    	SET_SDA;
    	
    	SDA_IN;
    	while(GET_SDA)	//potwierdzenie - jeżeli jest ustawiony idzie dalej
    	{	};		
    	SDA_OUT;
    	SET_SCL;
    	CLR_SCL;
    }
    
    unsigned char I2C_READ(void)
    {
    char wart=0;
    	int x;
    	SDA_OUT;
    	SET_SDA;
    	SDA_IN;
    	for(x=8;x>0;x--)
    	{
    		CLR_SCL;	
    		wart <<= 1;
    		if(GET_SDA) wart++;
    		SET_SCL;
    	}
    	SDA_OUT;
    //potwierdzenie
    	CLR_SCL;
    	CLR_SDA;
    	SET_SCL;
    	CLR_SCL;
    return wart;
    }

    program główny:
    
    		I2C_START();
    		
    		I2C_WRITE(0X90);//KOD URZADZENIA
    
    		I2C_WRITE(0X40);//KOD PRACY	
    		
    		I2C_START();
    		
    		while(1)
    			{	
    			I2C_WRITE(0X91);
    			
    			przet = I2C_READ();
    			
    			ILE(przet);
    			
    			for(wyswietlacz = 4; wyswietlacz>0 ;wyswietlacz--)							
    				{
    					screen(tab[tys], tab[set], tab[dzi], tab[jed], wyswietlacz);
    				};
    			}
    


    Z tego co zauważyłem na mierniku to linia scl ma stan niski a sda wysoki. Wg mnie program zatrzymuje się po wysłaniu kodu do urządzenia, a dokładnie po potwierdzeniu. Jak wywale te potwierdzenie to działa prawie dobrze, ale powinno działać z potwierdzeniem. Tak jest w standardzie i2c że 9 bit jest potwierdzeniem - ACK. Po to on jest żeby go używać.
  • REKLAMA
  • #2 9134441
    piotrva
    VIP Zasłużony dla elektroda
    Po pierwsze są rezystory podciągające 4,7 k na sda i scl?
    Dalej to wogóle nie masz w programie opóźnień w funkcjach i moim zdaniem transmisja ma za dużą częstotliwość
  • REKLAMA
  • #3 9134734
    LordBlick
    VIP Zasłużony dla elektroda
    1. Sprawdź najpierw częstotliwość zegara (SCL), czy jest zgodna z parametrami układu w nocie katalogowej...
    2. Brak deklaracji zegara i uzależnienia od niego linii taktującej I²C...
  • REKLAMA
  • #4 9135245
    dan50
    Poziom 12  
    piotrva napisał:
    Po pierwsze są rezystory podciągające 4,7 k na sda i scl?
    Dalej to wogóle nie masz w programie opóźnień w funkcjach i moim zdaniem transmisja ma za dużą częstotliwość


    Rezystory podciągające są.

    Light-I napisał:
    1. Sprawdź najpierw częstotliwość zegara (SCL), czy jest zgodna z parametrami układu w nocie katalogowej...


    Jeżeli dobrze przeczytałem i przeliczyłem to attiny ma SCL 250 kHz a przetwornik ma max SCL 100 kHz. Dałem opóźnienia no i już coś się pokazuje. Układ miał mierzyć napięcie podawane na jedno z wejść przetwornika i jak na razie to pokazuje 0, 1, i 2. Tylko jak sprawdzam woltomierzem to zmiana na 1 i 2 nie następuje w tedy gdy na woltomierzu są te dwa czy jeden wolt. Pewnie gdzieś będzie błąd z przeliczaniem lub w transmisji i2c.

    Light-I napisał:
    2. Brak deklaracji zegara i uzależnienia od niego linii taktującej I²C...


    tzn, bo nie rozumiem o co dokładnie chodzi?
  • #5 9135265
    piotrva
    VIP Zasłużony dla elektroda
    no o to chodzi, że powinieneś uzależniać częstotliwość pracy zegara od F_OSC (F_CPU), które powinno być zdefiniowane w programie lub opcjach projektu
REKLAMA