Отладочная плата на AT89S52 или изучаем МК с нуля

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

    Стабилитрон3.6 В2

    Кварц4 МГц1

    Кварц12 МГц1

    Светодиодылюбые14

    Конденсатор33 пФ2

    Резистор10 кОм7

    Резистор68 Ом2

    Резистор1.5 кОм1

    Резистор330 Ом12

    Кнопка без фиксациилюбые5

    РазьемUSB B1
    Добавить все

    Скачать список элементов (PDF)

    Прикрепленные файлы:

    Добавить комментарий

    Ваш адрес email не будет опубликован.