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

TWI,atmega8,C- brak potwerdzenia odbioru adresu

szefopiotr 17 Gru 2008 12:42 1155 1
REKLAMA
  • #1 5870056
    szefopiotr
    Poziom 9  
    Witam,
    Czytalem wiele postow na ten temat, skorzystalem z wielu kodow i dalej nie moge uruchomic komunikacji pomiedzy dwoma atmega8. Siedze nad tym od dobrych paru dni i nie wiem czy to wina sprzetu czy programu?? (miedzy innymi bazowalem na kodzie z postu Link).

    Chce uruchomic najprostszy przypadek MT nadaje do SR. Rezystory podciagajace maja wartosc 2,6kOHM.

    slave
    
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <stdlib.h> 
    #include <math.h> 
    #include "moje.h"
    #include <avr/delay.h>
    #define status (TWSR & 0xF8)             
    ///////////////////////////////////////////////////////////// 
    //recv data 
    //////////////////////////////////////////////////////////// 
    void error(void)
    {	LCD_clr();
    	 LCD_xy(0,0);
         write_text("blad1");
    	 _delay_ms(1000);
    }
    
    
    volatile uint8_t g_recvd_char;                    
    
    
    ISR(SIG_2WIRE_SERIAL) 
    { 	
    	
    	//if ((TWSR & 0xF8)!=0x60)   
    	//{LCD_clr();
    	// write_text("nieok");
    	
    	//}    
        //LCD_clr();
    	//write_text("ok");
    	
    	
    	switch (status) {         
            case 0x60:			 //sprawdza czy aders zostal odebrany i wystawione ACK
        
    		//	TWCR &= ~_BV(TWEA); 
                break; 
            case 0x80:break;		// dane odebrane wystawione ACK 
            case 0x88: 			// dane odebrane wystawione NACK 
                g_recvd_char = TWDR; 
                break; 
            case 0xA0:   // otrzymany stop 
                TWCR = (1<<TWEA)|(1<<TWEN)|(1<<TWIE); 
        // 
                break; 
            default: 
             {error();
    		 } // error handling here. 
        } 
        TWCR |= _BV(TWINT); 
    }  
    
    
    //////////////////////////////////////////////////////////// 
    //// main 
    //////////////////////////////////////////////////////////// 
    
    
    
    int main(void) 
    { 
    
    
    sei();
     
    
       TWAR = 0x98;         //ustawienie adresu
       TWCR = (1<<TWEA)|(1<<TWEN)|(1<<TWINT)|(1<<TWIE);
       
    //****************************************************************** 
    //pętla główna 
    //******************************************************************* 
       
       while(1) 
       { 
    
       } 
    
    
    } 
    
    


    master
    
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <stdlib.h> 
    #include "moje.h" 
    #include <util/delay.h>
    
    void error(void)
    {	LCD_clr();
    	 LCD_xy(0,0);
         write_text("blad1");
    	 _delay_ms(1000);
    }
    
    
    int main(void)
    {
    sei();
    
       TWSR = 0x00;                         /* no prescaler */ 
       TWBR = 0x20;//((8000000/100000)-16)/2;  /* must be > 10 for stable operation */ 
    	
    	DDRC=0x00;
    	PORTC=0xFF;
    	lcd_init();
     
     while(1)
     {
     
    	loop_until_bit_is_clear(PINC,0);
    
                   TWCR =  (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //wyslanie startu
                    
                 
                   while (!(TWCR & (1<<TWINT)));    // czeka aż wyśle
                  
    		
    				
    				if ((TWSR & 0xF8) != 0x08)    // spr startu
                   { 
                   error();
                   }
                  
    				
                  TWDR = 0X98;                  //wysyla adres 
                   TWCR = (1<<TWINT) | (1<<TWEN); 
              
                  
                   while(!(TWCR & (1<<TWINT))); 
                    
    		
    				
    
                   
                   if ((TWSR & 0xF8) != 0x18) // sprawdznie ACK 
                   { 
                   error();// nie ma ACK 
                   }
    			   
    			   else 
                   { 
    				//ok1();// wszystko OK jest ACK 
                   } 
                // ACK JUZ ODEBRANO 
    
    				
                   TWDR = 0XA1; //zapis bajtu danych
                   TWCR = (1<<TWINT) | (1<<TWEN); 
    
                   // czeka aż wyśle 
                   while(!(TWCR & (1<<TWINT))); 
    		
                   
                   if ((TWSR & 0xF8) != 0x30) // sprawdznie ACK 
                   { 
                   
                   }
    			   else 
                   { 
                    TWCR =  (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);// otrzymani NACK i podaje warunek stopu
                    LCD_xy(0,0);
    				write_text("koniec");
    				_delay_ms(1000);
    			   } 
    			   
    			   
    			   
    }
    }


    Bardzo prosze o pomoc bo naprawde nie wiem juz co robie zle, dokumentacje atmela przeczytalem chyba z 20 razy i wydaje mi sie ze jest ok, natomiast podlaczenie kontrolerow to dwa kable i rezystory podciagajace, takze raczej tez ok... Pozdrawiam...

    P.S. po przeanalizowaniu problemu wyglada to tak ze w przypadku slavea status po odebraniu adresu nie zmienia sie na 0x60(czyli odebrano adres wyslano ack) natomiast przerwanie jest wykonywane na slav'ie. Slave nie odpowiada wiec komunikacja dalej nie rusza...
  • REKLAMA
  • #2 5881523
    szefopiotr
    Poziom 9  
    chetnie ofiaruje punkty w zamian za pomoc bo naprawde kombinuje od tygodnia i nie wiem co jest nie tak??
REKLAMA