Форум РадиоКот https://radiokot.ru/forum/ |
|
TWI-> проблема-> помогите https://radiokot.ru/forum/viewtopic.php?f=57&t=149971 |
Страница 1 из 1 |
Автор: | Catdawr [ Ср ноя 15, 2017 21:54:22 ] | ||
Заголовок сообщения: | TWI-> проблема-> помогите | ||
Здраствуйте, пролема простая, наверняка даже легко решаемая, но я не вдуплю. Кароче хочу, для понимания, чтобы просто заработал следующий код: [Код из атмел студии 7, на atmega 8, протеус 8] Код: #define F_CPU 1000000UL #include <avr/io.h> #include <util/delay.h> #define ds3231 0b11010001 int main(void) { DDRB = 0xFF; DDRD = 0x00; // Insert code uint8_t addrW; // созидание и подготовка адреса с битом записи addrW = (ds3231); uint8_t addrDATA; addrDATA = 0x01; uint8_t DATA; DATA = 0b01010101; while(1){ _delay_ms(200); TWBR = 255; //При частоте 1 МГц TWSR = (1 << TWPS1)|(0 << TWPS0); //Пред делитель на 4 TWCR |= (1 << TWEN); //Включение модуля TWI // ******настройки TWCR =(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE); // старт while (!(TWCR &( 1<<TWINT))); // ожидание подъема twint if ((TWSR & 0xF8) != 0xF8); else PORTB |= (1 << 2); // ежели ошибка- загорится лампа TWDR= addrW; TWCR= (1<<TWINT)|(1<<TWEN); while (!(TWCR &( 1<<TWINT))); // ожидание подъема twint TWDR= addrDATA; TWCR= (1<<TWINT)|(1<<TWEN); while (!(TWCR &( 1<<TWINT))); // ожидание подъема twint if ((TWSR & 0xF8) != 0xF8) ;else PORTB |= (1 << 3); // ежели ошибка- загорится лампа TWDR= DATA; TWCR= (1<<TWINT)|(1<<TWEN); while (!(TWCR &( 1<<TWINT))); // ожидание подъема twint if ((TWSR & 0xF8) != 0xF8);else PINB |= (1 << 4); // ежели ошибка- загорится лампа TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); } return 0; } проблему видно на скрине дебагера протеуса. ![]() В общем, летит старт, летит адрес, адрес прилетает нормально, * далее летит неправильный (обычно пустой или, 4 раза генерирует некую белибирду) адрес пакета, шлет меня НАКуй... дальше уже не столь важно. не пойму в чем дело, ломаю голову не первую неделю. Жду лапку помощи
|
Автор: | mas123 [ Чт ноя 16, 2017 00:32:57 ] |
Заголовок сообщения: | Re: TWI-> проблема-> помогите |
#define ds3231 0b11010001 "...младший бит, определяет направление пересылки данных. "Ноль" означает, что ведущий будет записывать информацию в выбранного ведомого. "Единица" означает, что ведущий будет считывать информацию из ведомого."Т.е. ты хочешь читать из ведомого устройства. А не нужно ли ему вначале передать что хочется прочитать, адрес регистра, например? TWCR =(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE); // старт Зачем включать прерывание, если не используешь его? (TWIE)while (!(TWCR &( 1<<TWINT))); // ожидание подъема twint if ((TWSR & 0xF8) != 0xF8); else PORTB |= (1 << 2); // ежели ошибка- загорится лампа Статус удачного старта - 0x08, т.е. для зажигания при ошибке нужно if ((TWSR & 0xF8) != 0x08) PORTB |= (1 << 2); TWDR= addrW; После передачи адреса устройства хорошо бы проверить результат, код успешного передачи адреса (TWSR & 0xF8) == 0x18 TWCR= (1<<TWINT)|(1<<TWEN); while (!(TWCR &( 1<<TWINT))); // ожидание подъема twint TWDR= addrDATA; Здесь, видимо, передаётся адрес регистра. Кстати, код успешной передачи данных (TWSR & 0xF8) == 0x28TWCR= (1<<TWINT)|(1<<TWEN); while (!(TWCR &( 1<<TWINT))); // ожидание подъема twint if ((TWSR & 0xF8) != 0xF8) ;else PORTB |= (1 << 3); // ежели ошибка- загорится лампа Но i2c-адрес говорит "читаем из ведомого". Таким образом, ведомый начал что-то отвечать, но что? В это же время ведущий начал что-то передавать - получили коллизию. В общем, летит старт, летит адрес, адрес прилетает нормально, * далее летит неправильный (обычно пустой или, 4 раза генерирует некую белибирду) i2c работает так, как ты ей сказал. А не так, как хотел чтобы оно работало. ![]() В даташите описан алгоритм приема и передачи в/из ведомого. |
Автор: | Catdawr [ Чт ноя 16, 2017 21:21:21 ] |
Заголовок сообщения: | Re: TWI-> проблема-> помогите |
Отлично, всё работает.... спасибо тебе, дружище. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |