Машинка на ДУ управлении своими руками. Аппаратная реализация I2C. Передатчик

На этом уроке мы с Вами разберём вариант аппаратной реализации передатчика по последовательному интерфейсу I2C микроконтроллера AVR.

I2C — двунаправленный, последовательный интерфейс… Соединяем выводы SCL и SDA приёмника и передатчика. Подтягивает к питанию, я включаю встроенные подтягивающие резисторы.

NB! Для мониторинга переменных, регистров состояния и т.п. я буду использовать UART. Из материалов предыдущих уроков я скомпоновал библиотеку «uart_atm8.c», состоящую из функций инициализации UART, функции передачи байта и строки. Этого вполне достаточно для нужд отладки.

Первым делом инициализируем I2C, путём выбора скорости передачи…

 void initTWI() {    TWBR = 72; //Скорость 100кГц };

Подготовив данные для передачи…

 //Опрос клавиши направление движения. Загрузить полученные данные в commandBuffer    if (!(PINC & (1 << PC1))) commandBuffer |= (1 << 0); else commandBuffer &= ~(1 << 0);  //Опрос клавиш направления поворота. Загрузить полученные данные в commandBuffer    if (!(PINC & (1 << PC2))) commandBuffer |= (1 << 1); else commandBuffer &= ~(1 << 1); //Влево    if (!(PINC & (1 << PC3))) commandBuffer |= (1 << 2); else commandBuffer &= ~(1 << 2); //Вправо 

…начинаем сессию. Сначала передатчик формирует условие СТАРТ…

    TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN); //Старт!    while (!(TWCR & (1 << TWINT))); //Жду завершения

По завершению формирования условия СТАРТ проверяем регистр состояния TWSR. Код #08 сообщает об успешной передаче условия СТАРТ. Выведем значение регистра в терминал, для контроля передачи…

    USART_TransmitByte(TWSR);

…для удобства отладки введём паузы между отправками данных…

    _delay_ms(200); 

Следующим шагом передаём 7-битный адрес приёмника и бит для задания типа операции ЧТЕНИЕ или ЗАПИСЬ. Если приёмник распознаёт, что к нему происходит адресация, то приёмник формирует подтверждение.

 TWDR = 0b00000010; //Адрес устройства + запись! TWCR = (1 << TWINT)|(1 << TWEN); //Запуск while (!(TWCR & (1 << TWINT))); //Жду завершения

Код #18 сообщает о том, что был передан адрес приёмника и бит типа операции, принято ПОДТВЕРЖДЕНИЕ. Далее следует передача данных…

 //Передача байта commandBuffer    TWDR = commandBuffer; //Данные...    TWCR = (1 << TWINT)|(1 << TWEN); //Запуск    while (!(TWCR & (1 << TWINT))); //Жду завершения  //Передача байта мощности    TWDR = ADCH; //Данные...    TWCR = (1 << TWINT)|(1 << TWEN); //Запуск    while (!(TWCR & (1 << TWINT))); //Жду завершения 

Код #28 сообщает о том, что был передан байт данных, принято ПОДТВЕРЖДЕНИЕ. В завершении сессии передатчик формирует сигнал СТОП…

 TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTO); //Стоп! 

В нашем случае, когда приёмник отсутствует и коды ошибок регистра состояния передатчика не обрабатываются имеем…

По завершению формирования условия СТАРТ проверяем регистр состояния TWSR. Код #08 сообщает об успешной передаче условия СТАРТ.

Код #20 сообщает о том, что был передан адрес приёмника и бит типа операции, принято НЕТ ПОДТВЕРЖДЕНИЯ.

Код #30 сообщает о том, что был передан байт данных, принято НЕТ ПОДТВЕРЖДЕНИЯ.

ПРОЕКТ С ИСХОДНЫМ КОДОМ И СИМУЛЯЦИЯ В PROTEUS во вложении.