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

[ATmega128][C] Brak komunikacji z MCP4921 po SPI

gildor4 21 Wrz 2010 19:15 2038 1
REKLAMA
  • #1 8535297
    gildor4
    Poziom 1  
    Witam.
    Potrzebuje pomocy przy sprawnym uruchomieniu SPI na ATmega128. Chce wysyłać po SPI do 12 bitowego przetwornika DAC (MCP4921) dane. Przetwornik jest podłączony do standardowych wyjść SPI w atmedze, MOSI (PB2), SCK (PB1), LDAC(PB4), SC(PB5 lub PB0). Piny są ustawione jako wyjścia. Najpierw sygnał SC ściągany jest do zera, następnie następuje zapis danych do rejestru SPSR, potem standardowe podniesienie SC do 1 i zapis o na linie LDAC. Ale niestety przetwornik nie działa. Męczę się z tym już od trzech dni i nic. Nie wiem czy u mnie w kodzie jest gdzieś błąd czy przetwornik jest uszkodzony?

    
    #define DDR_SPI DDRB				//Definicje pinów używanych do SPI
    #define SPE 6
    #define MSTR 4
    #define SPI2X 0
    #define SPIF 7
    
    void init_masterSPI(void)		//Inicjalizacja modułu SPI
    {
    	DDR_SPI = 0x37;				//Ustawianie MOSI CS LDAC SCK SS jako wyj
    	PORTD=0x37;			        	//porty w stanie wysokim
    
    	sbi(SPCR,SPE);				//Włączenie modułu SPI
    	sbi(SPCR,MSTR);				//Moduł SPI w trybie master
    	sbi(SPSR,SPI2X);		        	//Podwojenie prędkości transmisji
    }
    
    void sent_SPI(char cData)	        	//Start transmisji
    {
    	SPDR = cData;			        	//Zapis danej do rejestru SPDR i jej wyslanie
    	while(!(tbi(SPSR,SPIF)));				//Czeka na koniec transmisji
    }
    
    
    int main(void)
    {
    .
    .
    .
     int warogrz;
    		 char mswarogrz;
    		 char lswarogrz;
    		 
    		 init_masterSPI();		//Wywolanie funkcji inicjującej moduł SPI
    		 sbi(PORTB,4);	        //Linia LDAC w stanie wysokim na czas zapisu 
    		 sbi(PORTB,0);     		//Start transmisji poprzez zmiane CS		
    		 cbi(PORTB,0);     		//Start transmisji poprzez zwolnienie CS								
    		 mswarogrz = warogrz >> 8;						
    		 lswarogrz = warogrz;
    		 
    		 sent_SPI((0x70) | mswarogrz);		//Zapis do DACa, Buforowany, Gain=1
    		 sent_SPI(lswarogrz);	        		//Output power down control bit lswarogrz
    		 sbi(PORTB,0);				        //Stop transmisji poprzez zmiane CS 
    		 cbi(PORTB,4);			        	//Zerowanie linii LDAC 
    		 sbi(PORTB,4); 										 
    }	
    


    Może ktoś miał do czynienia z tym przetwornikiem i miał podobny problem.
    Z góry dziękuje za wszelka pomoc.
  • REKLAMA
  • #2 8536969
    rpal
    Poziom 27  
    Zakładam że masz poprawnie wykonane połaczenia, sprawnie żródło napięcia odniesienia. W ogóle to przy starcie programu linię CS i LDAC ustaw w stan wysoki i już przy nich nie kombinuj z wyjątkiem ustawienia poziomu niskiego i powrotu do wysokiego. Przy założeniu że masz te linie w stanie wysokim
    Transmisja powinna wygładać tak:
    1) CS=LOW
    2) wpisujesz do spi MSB danej w tym 4 bity kontrolne
    3) wpisujesz do spi LSB danej
    4) CS=HIGH
    5) LDAC=LOW (teraz wystawiane jest napięcie na wyjście)
    6) LDAC=HIGH
    to wszystko to jest latwy w obsłudze przetwornik
    W zasadzie robisz to wszystko tylko że ci to nie wychodzi inaczej byś nie pisał postu więc podejżewam że masz coś w samej konstrukcji układu porąbane.
    Może pomyliłeś linie i zamieniłeś MISO z MOSI ?
    powinno byc tak : MOSI = SDI, SCK=SCK i CS, LDAC z dowolnego pinu.
    Albo też masz coś w tym czymś co powoduje że sciagasz linie SS od procka w stan niski za nim wyślesz cokolwiek do DAC wtedy cale spi przechodzi ci w tryb slave.
    Sprawdziłem jak u siebie sterowałem tym przetwornikiem i nieco inaczej niż w nocie ale napewno działa. Piersze mam ustawienie LDAC na LOW, potem CS na LOW dalej transmisja 2 bajtów a następnie ustawienie LDCA na HIGH i CS na HIGH. Też z tym wojowałem ale w końcu stanęło na takie a nie innej kolejności i na 100 % działa. Spróbuj tez bez buforowania czy pierwsze bity wyglądają tak 0b0011XXXX dla MSB danej.
    Jeśli to wszystko zawiedzie to sprawdź napięcie odniesienia, skąd je w ogóle czerpiesz ? i Jakiego rodzaju masz obciążenie samego przetwornika. Producent zaleca użyć jako bufora wzmacniacza operacyjnegonp. Rail-to-Rail.
    a tutaj :
    
           mswarogrz = warogrz >> 8;                   
           lswarogrz = warogrz; 
    

    dałbym coś takiego
    
           mswarogrz = (char)(warogrz >> 8);                   
           lswarogrz = (char)(warogrz & 0xff); 
    

    choćby tak tylko dla elegancji :)
REKLAMA