Соберите робота, следующего по линии, на микроконтроллере 8051
Работающий робот, следующий по линии, на микроконтроллере 8051 без Arduino, и ясное понимание каждого слоя, который Arduino обычно скрывает, — от схемы сброса до сигнала PWM.
Почти каждый инженерный курс по микроконтроллерам заканчивается одним заданием: собрать робота, следующего по линии, на 8051. Задание хорошее по причине, о которой обычно не говорят: микросхема не даёт ничего. Нет analogWrite() для задания скорости двигателя, нет analogRead() для датчиков, нет библиотеки для платы драйвера. Каждый обычно доступный слой здесь нужно реализовать самостоятельно.
Именно в этом различие между данным маршрутом сборки и роботом, следующим по линии, на Arduino. Робот тот же, но глубина другая. Вы напишете генератор широтно-импульсной модуляции (PWM), который в Arduino реализован кремнием, узнаете, почему вывод 8051 зажигает светодиод (LED) только при обратном подключении, и до покупки компонентов точно выясните, сколько CPU потребляет управление двигателями.
8051 — 8-битный микроконтроллер с гарвардской архитектурой в корпусе с 40 выводами, обычно AT89S52 с 8 KB Flash и 256 байт RAM. У него нет периферийного модуля PWM, его порты квазидвунаправленные (перед чтением входа нужно записать 1), а его выводы пропускают больше тока, чем подают, поэтому светодиод подключают со стороны стока, а для надёжного управления H-мостом драйвера двигателей нужны подтягивающие резисторы. Эти подробности кажутся примечаниями, пока робот вообще ничего не делает из-за неподключённого или заземлённого EA или потому, что схема сброса активна на верхнем уровне, а вы подключили её к нижнему.
Сначала вы работаете на макетной плате только с микросхемой, кварцевым резонатором 11.0592 MHz, двумя нагрузочными конденсаторами, схемой сброса и EA на верхнем уровне — это минимальная схема, действительно выполняющая код. Первые три руководства проводят вас через архитектуру и карту памяти, универсальный ввод-вывод (GPIO) и сопряжение с портами, а затем создание PWM из таймера 0 в 8-битном режиме автоматической перезагрузки: около 460.8 Hz с шагом 5%; это занимает примерно четверть CPU — плата за отсутствие периферийного модуля.
Далее пути объединяются с роботом, следующим по линии, на Arduino: тот же массив инфракрасных (IR) датчиков отражения сводится к взвешенной ошибке, тот же ПИД-регулятор (PID) с пропорциональной, интегральной и дифференциальной составляющими управляет движением, а в том же браузерном симуляторе вы находите коэффициенты для прохождения поворотов. Дерево проекта разделяет аппаратные и концептуальные узлы, поэтому первая половина требует только микросхемы и ISP-программатора, например USBasp, и лишь последним двум узлам сборки нужны шасси, двигатели и массив датчиков.
Выполните приведённое ниже дерево проекта по порядку. Первые три узла требуют только микросхемы на макетной плате, коэффициенты движения по линии настраиваются в браузерном симуляторе, и лишь последним двум этапам нужны шасси и двигатели. Ваш прогресс сохраняется на этом устройстве.
Перечень компонентов
| Компонент | Кол-во | Примерная стоимость | Примечания |
|---|---|---|---|
| AT89S52 в корпусе DIP с 40 выводами | 1 | $2 | Программируется в системе. Для AT89C51 нужен параллельный программатор, которого у вас нет |
| ISP-программатор USBasp | 1 | $3 | AT89S52 программируется по SPI — именно это делает подход практичным |
| Кварцевый резонатор 11.0592 MHz | 1 | $0.50 | Не 12 MHz. См. ниже — это не вопрос предпочтения |
| Керамические конденсаторы 33 pF | 2 | $0.20 | Нагрузочные конденсаторы резонатора |
| Электролитический конденсатор 10 µF + резистор 10 kΩ | 1 каждого | $0.20 | Схема сброса. Здесь сброс активен на верхнем уровне HIGH |
| Резисторная сборка 10 kΩ | 1 | $0.50 | Подтягивающие резисторы порта 0 — это порт с открытым стоком, который без них не может подать верхний уровень |
| ZIF- или DIP-панель на 40 выводов | 1 | $1 | Никогда не припаивайте микросхему напрямую: её потребуется извлечь |
| Массив ИК-датчиков отражения | 1 | $5–10 | Цифровой выход, либо добавьте внешний ADC: у 8051 нет аналогового входа |
| L298N | 1 | $3 | |
| Редукторный двигатель TT | 2 | $4 | |
| Шасси 2WD | 1 | $6–10 | |
| Аккумулятор | 1 | $6 | |
| Макетная плата и перемычки | — | $5 | Первые три этапа выполняются полностью на ней |
Итого: примерно $35–50.
Две покупки определяют, будет ли проект приятным или мучительным.
Кварцевый резонатор должен быть 11.0592 MHz. Контроллер 8051 формирует скорость
последовательной передачи через переполнение таймера 1, и при 11.0592 MHz каждая
стандартная скорость даёт целое значение перезагрузки: 9600 бод в точности
соответствует TH1 = 0xFD. Кварцевый резонатор 12 MHz даёт 10417 бод вместо
целевых 9600, то есть ошибку 8.5%, что значительно превышает примерно 3%,
допустимые для UART. Каждый символ приходит повреждённым. Микросхема работает
идеально, пока не попытаетесь вывести что-либо для отладки, — это худшее время
для такого открытия.
Массив датчиков должен иметь цифровые выходы, иначе необходимо добавить внешний ADC, например ADS7828 или ADC0808. У 8051 вообще нет аналогового входа. Это первое, что микросхема отнимает, но Arduino предоставляет бесплатно, и решение стоит принять осознанно: выходы компараторов проще, но не дают плавного пропорционального сигнала ошибки, необходимого для качественной настройки ПИД-регулятора.
Минимальная схема
До подключения любых датчиков и двигателей добейтесь, чтобы микросхема без дополнительной обвязки выполняла код на макетной плате. Шесть соединений:
| Вывод | Подключить к | Зачем |
|---|---|---|
40 (VCC) |
+5 V | |
20 (GND) |
«Земля» | |
31 (EA) |
+5 V | Выбирает внутреннюю память программы. Если вывод не подключён или заземлён, микросхема получает данные из отсутствующей внешней памяти и вообще ничего не делает |
18, 19 (XTAL2, XTAL1) |
Параллельно кварцевому резонатору | С конденсатором 33 pF от каждого вывода к «земле» |
9 (RST) |
10 µF к +5 V, 10 kΩ к «земле» | Сброс активен на верхнем уровне HIGH, в отличие от почти всех других микроконтроллеров |
Незаземлённый EA — самая частая причина того, что первая плата с 8051 кажется
нерабочей, и он не вызывает ни ошибки, ни света, ни каких-либо указаний. Проверяйте
его первым, каждый раз.
Светодиод на P1.0 — это «привет, мир»: подключите катод к выводу, анод через
резистор 330 Ω к +5 V и запишите 0, чтобы включить свет. Вывод пропускает около
10 mA, но подаёт лишь примерно 60 мкА, поэтому при обратном подключении
светодиод слабо светится и выглядит неисправным.
Сборка по этапам
Первые три этапа требуют только микросхемы на макетной плате, поэтому до покупки шасси можно продвинуться далеко по этому проекту.
| № | Этап | Проверка | Успешный результат |
|---|---|---|---|
| 1 | Микросхема работает | Мигать светодиодом на P1.0 | Светодиод мигает. Если нет, прежде всего проверьте EA |
| 2 | Проверено время | Мигать точно с частотой 1 Hz с подсчитанной задержкой | Секундомер на 60 миганиях отличается не более чем на секунду |
| 3 | Последовательная связь работает | Вывести счётчик на 9600 бод | Чистый текст — мусор означает неверный кварцевый резонатор |
| 4 | Ввод GPIO | Считать кнопку на P1.1 с подтягивающим резистором | Надёжное считывание. Не забывайте записать 1 перед чтением |
| 5 | Прерывание таймера | Переключать вывод из ISR таймера 0, проверить осциллографом или по времени | Период соответствует расчёту и остаётся стабильным |
| 6 | Программный PWM | Управлять светодиодом при скважности 0%, 25%, 50%, 100% | Заметно различающаяся яркость без мерцания |
| 7 | Измерена стоимость PWM | Переключать свободный вывод в основном контуре и измерить время | Можно назвать долю CPU, которую потребляет ISR |
| 8 | Двигатели приводятся | Оба колеса вперёд и назад при заданной скважности | Оба направления и обе скорости на опорах |
| 9 | Считываются датчики | Вывести все каналы над линией и над полом | Каждый канал различает две поверхности |
| 10 | Сигнал ошибки | Передвигать робота через линию вручную | Монотонное взвешенное положение без скачков |
| 11 | Следование по линии | Проехать овальный круг из ленты | Полностью проходит круги |
Этап 7 — ради него существует этот проект. Вызов analogWrite в Arduino ничего
не стоит: PWM генерируется кремнием. Здесь вы создали его через прерывание таймера,
и оно срабатывает десятки тысяч раз в секунду. Измерение доли CPU, которую это
потребляет, — главный урок: обычно это четверть микросхемы, и именно её
покупает аппаратный периферийный модуль PWM.
Как выглядит хороший результат
| Измерение | Типичное значение для этой сборки |
|---|---|
| Машинный цикл при 11.0592 MHz | 1.085 µs — можно подсчитывать инструкции и точно знать время |
| Частота программного PWM | ~460 Hz с шагом 5%, от таймера 0 в 8-битном режиме автоматической перезагрузки |
| Доля CPU, потребляемая ISR PWM | ~25% |
| Оставшаяся частота основного контура | По-прежнему с запасом выше 200 Hz для контура регулирования |
| Использованная RAM | Менее 100 байт из 256 — ограничение реальное, но здесь не критическое |
| Качество движения по линии | Сопоставимо со сборкой на Arduino; робот здесь не главная цель |
Последнюю строку стоит назвать прямо. Этот робот не превзойдёт
робота, следующего по линии, на Arduino. Это тот
же робот, собранный трудным способом, и польза заключается в понимании, а не в
производительности. Если нужен более качественный робот, следующий по линии,
настраивайте сборку на Arduino. Если нужно понять, что всё это время делал за вас
analogWrite, соберите этот вариант.
Диагностика неисправностей
| Симптом | Вероятная причина | Исправление |
|---|---|---|
| Микросхема вообще ничего не делает | EA не подключён или заземлён |
Соедините вывод 31 с +5 V |
По-прежнему ничего нет, EA на верхнем уровне |
Кварцевый резонатор не колеблется | Проверьте конденсаторы 33 pF и пайку резонатора |
| Постоянно перезагружается | RST удерживается на верхнем уровне | Сброс активен на верхнем уровне HIGH — проверьте сеть 10 µF / 10 kΩ |
| Последовательный вывод содержит мусор | Кварцевый резонатор 12 MHz | 11.0592 MHz или отказ от последовательной отладки |
| Светодиод едва светится | Подключён для подачи тока | Катод к выводу; запишите 0, чтобы включить свет |
| Порт 0 ничего не читает и не записывает | Открытый сток без подтягивающих резисторов | Резистор 10 kΩ от каждого вывода к +5 V |
| Период PWM колеблется | Таймер перезагружается слишком поздно в ISR | Выполните перезагрузку первым оператором либо используйте режим 2 |
| Программа возвращается по случайному адресу | Стек пересекается с банком регистров 1 | SP = 0x30; в начале main() |
| При росте кода поведение становится непредсказуемым | Закончилась RAM | Всего 256 байт — проверьте карту компоновщика |
| Программатор не видит микросхему | Выводы ISP заняты или отсутствует управление сбросом | Освободите P1.5–P1.7 и RST на время программирования |
| Датчики не дают полезного значения | Аналоговый массив на микросхеме без ADC | Массив с цифровым выходом либо внешний ADC |
Куда двигаться дальше
Добавьте второй таймер и измерьте собственный контур. Когда таймер 0 создаёт PWM, таймер 1 может измерять период контура регулирования и превращать ощущение отзывчивости в число. На микросхеме, где можно подсчитывать машинные циклы, это число точно предсказуемо — проверьте свой прогноз.
Подключите жидкокристаллический дисплей (LCD) через порт 0, и вы полностью столкнётесь с проблемой открытого стока, а также с требованиями по времени устройства, которое действительно медленнее процессора.
Затем соберите версию на Arduino — и обратите
внимание, сколько теперь вы понимаете в каждой её строке. Вызов analogWrite,
занимающий одну строку, здесь потребовал вечера на ISR; analogRead — это ADC,
который пришлось добавить снаружи. Именно это сравнение и составляет реальный
результат проекта.
Дорожная карта проекта
Путь сборки
Следуйте по дереву технологий от деталей к работающему роботу. Каждый узел открывается, когда выполнены его предварительные условия, а ваш прогресс сохраняется на этом устройстве.
0 / 17 выполнено
Компоненты
- КонтроллерМикроконтроллер 8051Микросхема из учебной программы, без каких-либо слоёв между вами и оборудованием.
- ДатчикМассив ИК-датчиков отражения (IR)Ряд инфракрасных «глаз», который сообщает роботу, где находится линия.
- ДрайверДрайвер двигателей L298NДвойной H-мост, превращающий слабые логические выводы в мощность для двигателей.
- Исполнительный механизмРедукторный двигатель TT (DC)Жёлтый редукторный двигатель, превращающий голую платформу в движущийся робот.
- ШассиШасси робота 2WDПлатформа, к которой крепятся два двигателя, свободный опорный ролик и вся электроника.
- ПитаниеБатарейный блок питания роботаРазница между работающим роботом и роботом, который постоянно перезагружается.
Руководства на этом пути
- Начальный · 30 minАрхитектура 8051: выводы, карта памяти и регистрыГарвардское ядро, четыре порта, 256 байт ОЗУ и расчёт времени в машинных циклах.
- Начальный · 28 min8051 GPIO и подключение к портам: сток, а не источникПочему светодиоды 8051 подключаются наоборот, почему перед чтением нужно записать 1 и какую нагрузку выдерживает порт.
- Средний · 35 minТаймеры 8051 и программный PWM для управления двигателемСоздайте PWM по прерыванию таймера 0, выберите компромисс между частотой и разрешением и управляйте H-мостом.
- Начальный · 20 минМассив инфракрасных датчиков для робота, следующего по линииПреобразование ряда инфракрасных датчиков в единую плавную позицию линии, по которой можно управлять роботом.
- Начальный · 18 min readУправление двигателями постоянного тока с помощью PWM и H-мостаБезопасно подключите коллекторный двигатель постоянного тока и управляйте им с помощью PWM, H-моста и реалистичных пределов тока.
- Начальный · 20 min readРобот, следующий по линии: от датчиков к ПИД-управлениюИК-датчики, взвешенная ошибка и ПИД-регулятор: как робот следует за линией без рывков.
Попрактикуйтесь до сборки схемы
Настройте его в интерактивном симуляторе
Путь сборки проходит через лабораторию в браузере. Добейтесь правильного поведения здесь, а затем перенесите настройки на реального робота.
Часто задаваемые вопросы
Почему собрать робота, следующего по линии, на 8051, а не на Arduino?
Потому что 8051 заставляет реализовать то, что Arduino скрывает. Нет analogWrite, поэтому вы пишете генератор PWM; нет pinMode, поэтому изучаете действие квазидвунаправленных портов. Если цель — работающий робот, используйте Arduino. Если цель — понять робота, 8051 даёт больше знаний за час, чем любая плата с библиотекой для всего.
Какие компоненты нужны для робота, следующего по линии, на 8051?
AT89S52 с кварцевым резонатором и схемой сброса, массив ИК-датчиков отражения, драйвер на H-мосте, например L298N или L293D, два редукторных двигателя TT, шасси 2WD и аккумулятор, обеспечивающий раздельное питание логики и двигателей. Также нужен ISP-программатор: USBasp стоит недорого и прошивает AT89S52 по четырём выводам.
Как управлять скоростью двигателя на 8051 без аппаратного PWM?
PWM создаётся программно. Таймер 0 работает в 8-битном режиме автоматической перезагрузки и генерирует прерывание каждые 100 машинных циклов; обработчик подсчитывает такты и удерживает выход на верхнем уровне в течение первых N отсчётов каждого периода. При 11.0592 MHz это даёт 460.8 Hz с шагом скважности 5% и занимает около четверти CPU — это плата за отсутствие периферийного модуля PWM.
Можно ли писать код на C или обязательно использовать ассемблер?
C подходит, и именно его использует большинство современных курсов. Keil C51 — отраслевой стандарт, а SDCC — бесплатная альтернатива с открытым исходным кодом. Ассемблер на этой микросхеме стоит изучить: система команд небольшая, а время можно подсчитать, — но писать на нём весь код робота не требуется.
Почему после прошивки мой робот на 8051 вообще ничего не делает?
Прежде всего проверьте, что EA (вывод 31) подключён к +5 V. Если он не подключён или заземлён, микросхема пытается получить программу из внешней памяти, которой нет, и без какой-либо ошибки ничего не выполняет. Затем проверьте схему сброса: на 8051 сигнал сброса активен на верхнем уровне, а также проверьте два нагрузочных конденсатора кварцевого резонатора.
Нужно ли покупать компоненты до начала этого проекта?
Нет. Логика движения по линии и настройка коэффициентов работают в браузерном симуляторе, а для трёх руководств по 8051 достаточно только микросхемы на макетной плате. Купите шасси и двигатели, когда будете готовы подключить физического робота.