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

Atmega][C] I2C dwie atmega w sieci , brak odpowiedzi

krzysiekk_20 29 Cze 2011 16:12 2305 1
REKLAMA
  • #1 9662475
    krzysiekk_20
    Poziom 12  
    Witam,

    Chcę połączyć ze sobą dwie atmegi po TWI korzystam ze standardowej biblioteki do obsługi sprzętowego TWi tak jak w datasheetach. Jak podłączę jednego AVR do np Ds1307 to obsługa jest ok w dwie strony. Problem mam gdy połączę Atmega32 (master) z Atmega8 (slave) tzn gdy z Atmegi32 wysyłam coś np literkę 'q' to jest ona wrzucana do buf2 i ma się wyświetlić na lcd napis oraz do innej tablicy ma być wpisana wartość buf[0]="1" a Atmega8. Ale jednocześnie Atmega32 ma odczytać tą informację i na swoim lcd ma wyświetlić literkę "A".

    Kod atmegi8:

    
    volatile static uint8_t Status_I2C;
    volatile static char Buf[30];
    volatile static char Buf2[30];
    volatile static uint8_t m,n;
    
    ISR (TWI_vect)
    {
    Status_I2C = TWSR&0xFC;
    switch(Status_I2C)
    {
    //TRANSMITTER
    case 0xA8: n=0; TWDR=Buf[n]; break;//odebrano bit startu i bajt adresu do odczytu
    case 0xB0: n=0; TWDR=Buf[n]; break;//odebrano bit startu i bajt adresu do odczytu
    case 0xB8: n++; TWDR=Buf[n]; break;//odebrano wyslanie znaku z ACK
    case 0xC0: break;//odebrano wyslanie znaku bez ACK
    case 0xC8: break;//odebrano wyslanie znaku bez ACK
    
    // RECEIVER:
    case 0x60: m=0; break;//odebrano bit startu i bajt adresu do zapisu
    case 0x80: Buf2[m]=TWDR; m++; break;// odebrano bajt
    case 0xA0: // odebrano bit STOP lub kolejny START
    TWCR = TWCR & ~0x44;
    TWDR=0;
    TWCR = TWCR | 0x44;
    m=0;
    break;
    
    default: break;
    
    }
    TWCR = TWCR | 0x80;
    }
    
    char str01[] PROGMEM = "q";
    
    int main (void)
    {
    
    sei();
    glcdInit();
    lcdOn();
    lcdCls();
    
    //SREG|=_BV(7);
    //TWBR=72;
    TWBR=0x00;
    TWAR=0x18;
    TWCR=0x45;
    TWSR=0x00;
    for(;;)
    
    {
    if (strncmp_P(Buf2,str01,1)==0)
     {
    lcdCls();
    lcdGoTo(10,1);
    lcdWriteString("Odebralem q");
    Buf[0]="1";
    }
    _delay_ms(500);
    }
    return 0;
    }
    
    


    kod Atmega32 (master):
    
    
    #define Ack 1
    #define Nack 0
    char str01[] PROGMEM = "1";
    char str02[] PROGMEM = "2";
    char str03[] PROGMEM = "3";
    char buf[30];
    
    int main (void)
    {
    lcd_init();
    LCD_DISPLAY(LCDDISPLAY);
    TWBR=72;
    sei();
    
    
    for(;;)
    {
    
    if (strncmp_P(buf,str01,1)==0)
     {
     LCD_CLEAR;
     lcd_puts("A");
     }
    
    if (strncmp_P(buf,str02,1)==0)
     {
     LCD_CLEAR;
     lcd_puts("B");
     }
    
    uint8_t ret;
    	TWI_start();
    	TWI_write(0x18);
            TWI_write('q');
    	TWI_start();
            TWI_write(0x18);
              ret=TWI_read(Nack);	
    	TWI_stop();
    	buf[0]=ret;
    	
    lcd_puts(buf);
     _delay_ms(1000);
    }
    
    return 0;
    }
    

    Po linijce TWI_write('q'); jeśli użyję powtórzonego startu lub stopu to na Atmega8 komunikat dojdzie i napis się pojawi ale nie otrzymuje nic. Nie wiem czy to wina adresu tego drugiego czyli zamiast 0x18 musze mieć 0x19. Próbowałem i nic
  • REKLAMA
  • #2 9666763
    krzysiekk_20
    Poziom 12  
    Rozwiązałem już problem. W kodzie Atmega32 dodałem opóźnienie czasowe oraz zmieniłem adres i działa bez problemu

    
    uint8_t ret; 
       TWI_start(); 
       TWI_write(0x18); 
       TWI_write('q'); 
       TWI_stop();
       TWI_start(); 
       TWI_write(0x19); 
       ret=TWI_read(Nack);    
       TWI_stop(); 
    
    

    do tego doszło jeszcze cykliczne odczytywanie kilku bajtów aż do wysłania Nack.
    Temat do zamknięcia
REKLAMA