Отладочная плата на 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

Начнем со схемы

Отладочная плата для AT89S52

Прежде всего, хочу сказать, для чего я делал такую плату:

  1. Отладка простых программ с использованием светодиодов (помигать, разработка световых эффектов и тп.).
  2. Работа с кнопками (лепить матричную клавиатуру было не охота, так что если нужна такая клавиатура, то можно использовать один порт для периферии).
  3. Отладка программ с использованием последовательного порта (UART).
  4. Изучение основ семейства 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