На этом уроке мы с Вами разберём вариант аппаратной реализации передатчика по последовательному интерфейсу 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 во вложении.