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:
kod Atmega32 (master):
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
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