Witam
Piszę program wpółpracujący z kilkoma urządzeniami I2C min z DS3232 i PCF8574. Obsługuję je za pomocą sprzętowego TWI. Program niestety okresowo się zawiesza, tym częściej im szybsze taktowanie MCU. Przy 1MHz czasem, przy 8MHz za każdym razem.
Zbadałem, że zawieszanie następuje w pętli while w funkcji twistop()
Znalazłem następujący tekst o tym zjawisku
"Gdy ze względu na stan magistrali AVR nie potrafi wygenerować sygnału STOP, program zawiesza się w tym fragmencie. Zjawisko to nie występuje w sprawnym układzie, pod warunkiem nie wygenerowania zbędnych sygnałów stop przez samego użytkownika, dlatego nie rozwiązywałem go na poziomie biblioteki - wystarczający będzie Watchdog lub ręczne ograniczenie ilości obiegów pętli oczekującej."
niestety, wyeliminowanie pętl while a wstawienie zamiast niej _delay_ms(10); powoduje nie wykonywanie wszystkich poleceń do pcf8574 szczególnie jak następuja szybko po sobie. Z kolei wprowadzenie powoduje zawieszanie. Na początku programu ustawiam TWBR=72; - bez rezultatu. Czy ktoś spotkał sie z takim problemem?
Czy sama komenda
na początku programu dostatecznie przy 4MHz spowolni i2C?
Z góry dzięki za zainteresowanie tematem.
Pozdrawiam
Piszę program wpółpracujący z kilkoma urządzeniami I2C min z DS3232 i PCF8574. Obsługuję je za pomocą sprzętowego TWI. Program niestety okresowo się zawiesza, tym częściej im szybsze taktowanie MCU. Przy 1MHz czasem, przy 8MHz za każdym razem.
Zbadałem, że zawieszanie następuje w pętli while w funkcji twistop()
Znalazłem następujący tekst o tym zjawisku
"Gdy ze względu na stan magistrali AVR nie potrafi wygenerować sygnału STOP, program zawiesza się w tym fragmencie. Zjawisko to nie występuje w sprawnym układzie, pod warunkiem nie wygenerowania zbędnych sygnałów stop przez samego użytkownika, dlatego nie rozwiązywałem go na poziomie biblioteki - wystarczający będzie Watchdog lub ręczne ograniczenie ilości obiegów pętli oczekującej."
niestety, wyeliminowanie pętl while a wstawienie zamiast niej _delay_ms(10); powoduje nie wykonywanie wszystkich poleceń do pcf8574 szczególnie jak następuja szybko po sobie. Z kolei wprowadzenie powoduje zawieszanie. Na początku programu ustawiam TWBR=72; - bez rezultatu. Czy ktoś spotkał sie z takim problemem?
Czy sama komenda
TWBR=72;
na początku programu dostatecznie przy 4MHz spowolni i2C?
Z góry dzięki za zainteresowanie tematem.
Pozdrawiam
#include "TWI.h"
// procedura transmisji sygnału START
void twistart(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
}
// procedura transmisji sygnału STOP
void twistop(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
while ((TWCR & (1<<TWSTO)));
}
// procedura transmisji bajtu danych
void twiwrite(char data)
{
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
}
//procedura odczytu bajtu danych
char twiread(char ack)
{
TWCR = ack
? ((1 << TWINT) | (1 << TWEN) | (1 << TWEA))
: ((1 << TWINT) | (1 << TWEN)) ;
while (!(TWCR & (1<<TWINT)));
return TWDR;
}