В один прекрасный момент случилось то, что должно было случиться еще очень давно, это изучение микроконтроллеров серии MCS-51 на ассемблере. В начале этого пути упоминались AT89C4051, но они мне показались не функциональными сточки зрения прошивки, так как все программаторы, которые я встречал в сети, были либо под COM-порт, либо LPT. Тогда я полез в каталог данного семейства и начал смотреть подобные микроконтроллеры. В итоге нашёл AT89S51, AT89S52, AT89S53 – это тот же самый AT89C4051, но у серии S есть ISP и они имеют большее количество памяти и портов ввода вывода. Поиски программатора тоже были не из легких, но в скорее я нашёл то, что искал – это был USBasp с модифицированной прошивкой и новым софтом. Вот такое вот вступление, теперь же рассмотрим сам программатор и отладочную плату с некоторыми простыми примерами.
Программатор для AT89S52
Программатор поддерживает AT89S51, AT89S52, AT89S53, AT89S8252, AT89S8253, AT89S2051, AT89S4051 + еще много разных камней от AVR . Схему собирать как есть без выкидывания деталей, хотя я не ставил конденсаторы на обвязку кварца, но это уже другой разговор.
Обвязка МК перед программированием
Здесь вывод 31 должен быть подтянут к + питания (лог. единица). Этот вывод дает знать, из какой памяти выполнять программу МК, если на выводе 31 присутствует логический ноль, то контроллер работает с внешней памятью, а если иначе, то с внутренней. Так как у меня нету внешней памяти я работаю с внутренней. Выводы Р1.5-Р1.7,RST это ISP для программирования МК, все также как и у AVR. Если вдруг не заработает, то есть не будет определяться МК программатором то за место R1 нужно поставить конденсатор на 0.1мкф как у автора. Почему я поставил резистор? Да потому что у меня не было под рукой мелкого конденсатора, + я еще дополнил данный вывод сброса кнопкой.
По программатору, думаю все понятно.
Отладочная плата для AT89S52
Начнем со схемы
Прежде всего, хочу сказать, для чего я делал такую плату:
- Отладка простых программ с использованием светодиодов (помигать, разработка световых эффектов и тп.).
- Работа с кнопками (лепить матричную клавиатуру было не охота, так что если нужна такая клавиатура, то можно использовать один порт для периферии).
- Отладка программ с использованием последовательного порта (UART).
- Изучение основ семейства AT89X51
Схему я собрал на макетной плате с использованием деталей тех, что были под рукой, единственное, что покупал так это микроконтроллер и панельку под него.
Рассмотрим теперь несколько примеров программ на ассемблере.
Стандартный Hello World на ассемблере
cseg at 0 // абсолютный сегмент в области памяти программ jmp Start //переход к Start Start: //метка начала программы setb p2.0 //устанавливаем в бит p2.0 лог. ед. LoopMain: //главный цикл lcall DriveLed //вызов функции мигания светодиода lcall Delay //вызов функции задержки sjmp LoopMain //конец главного цикла ;******************************************************** Delay: //функция задержки mov r3,#0 //пишем в регистр r3 ноль LoopDelay2: // цикл задержки 2 mov r2,#0 //пишем в регистр r2 ноль LoopDelay1: //цикл задержки 1 Nop //нет команд nop nop nop nop nop nop nop nop nop inc r2 //инкрементируем r2 cjne r2,#255,LoopDelay1 // если r2 не равно 255 переходим к метке цикл задержки 1, если равно то идем дальше nop inc r3 // инкремент r3 cjne r3,#20,LoopDelay2 //если r3 не равно 20 то переходим к метке цикл задержки 2, если равно то идем дальше nop ret // возврат из подпрограммы ;******************************************************** DriveLed: //функция мигания светодиодом cpl p2.0 //инвертируем бит р2.0 ret //возврат из подпрограммы ;******************************************************** end //конец главной программы
В этой программе все просто, если непонятно о чем идет речь, то тогда лучше сначала просто открыть справочник и почитать про команды. Я пользуюсь этим
Теперь сделаем бегущий огонь.
Данная программа реализуется посредством записи в выбранный регистр (у меня это аккумулятор А ) числа FЕ это 1111 1110 и при выполнении команды rr A (сдвига содержимого аккумулятора в право ) получаем 0111 1111, и так далее. Аналогично можно сделать сдвиг влево.
Изменения в программе были внесены здесь
Изменения в программе были внесены здесь Start: mov A, #0feh //записать в аккумулятор #0feh, 1111 1110 и в функции DriveLed DriveLed: rr A //сдвиг в право mov P2, A //записать в порт Р2 содержимое аккумулятора А ret
Все остальные куски программы такие же. Здесь тоже нет ни чего сложного.
Ну и еще одна программа с использованием кнопки. Сделаем так чтобы по нажатию кнопки светодиод бежал в право, а при следующем нажатии бежал в лево.
Здесь поступим следующим образом
Start: mov A, #0feh mov r4, #00000000b LoopMain: m1: setb p0.0 //установили бит(на нем висит кнопка) mov c, p0.0 //записали в регистр признаков С jc m2 //переход к м2 если С=1 inc r4 // инкремент r4 m2: cjne r4, #1, w // если r4 не равен 1 то идем к метке w, если равен то дальше call DriveLed lcall Delay jmp m1 w: cjne r4, #2, m1 // если r4 не равен 2 то идем к метке м1, если равен то дальше call DriveLed1 lcall Delay sjmp LoopMain
Данный код не идеален, потому что его работа напрямую зависти от величины задержки, но для начала пойдет.
Список радиоэлементов
Обозначение | Тип | Номинал | Количество | Примечание | Магазин | Мой блокнот |
---|---|---|---|---|---|---|
Микроконтроллер | at89s51,52,53 | 1 | ||||
Стабилитрон | 3.6 В | 2 | ||||
Кварц | 4 МГц | 1 | ||||
Кварц | 12 МГц | 1 | ||||
Светодиоды | любые | 14 | ||||
Конденсатор | 33 пФ | 2 | ||||
Резистор | 10 кОм | 7 | ||||
Резистор | 68 Ом | 2 | ||||
Резистор | 1.5 кОм | 1 | ||||
Резистор | 330 Ом | 12 | ||||
Кнопка без фиксации | любые | 5 | ||||
Разьем | USB B | 1 | ||||