Примеры программирования

Пример 1

Пример обработки нажатия кнопки
Пример 2 Перевод двоичного числа в десятичное (по разрядам)
Пример 3 Вывод данных на индикацию
Пример 4 Мой вариант бегущей строки

Я недавно занимаюсь программированием микроконтроллеров, и, может быть, кому-нибудь Мои программки покажутся наивными. Но заверяю со всей ответственностью, что как бы слабы они ни были , они нормально работают т.е. дают желаемый результат. А это, по-моему, самое важное в составлении программ.
Если на 3 бит Порта В (выбрано чисто условно) подключить кнопку, которая при нажатии будет замыкаться на "0", то :
Давайте разберём буквально по буквам этот пример.
sbros - метка. Метка это такое место в программе, которое, на подобие, дорожного указателя показывает, где мы находимся или куда должны перейти после выполнения определенной процедуры. sbr1 и sbr2 тоже метки. Единственное условие, которое должно обязательно соблюдаться при определении(установке меток) это то, что она должна быть уникальна и понятна (хотя бы самому программисту).
btfsc - команда ассемблера, которая проверяет состояние отдельного бита регистра (переменной) и, в зависимости от этого, разрешает выполнение следующей команды, или пропускает её. Т.е., если кнопка отпущена, то бит 3 = 1 (это мы получили, подключив соответственно кнопку к выводу контроллера) и мы переходим к следующей команде call.
Если кнопка нажата, то бит 3 = 0 и мы игнорируем команду call и переходим к команде btfss. Она работает так же как команда btfsc, но наоборот. Т.е. если бит 3 = 0, выполняется следующая команда,а если равен 1, то следующая команда пропускается.
Итак при отпущенной кнопке мы переходим на метку sbr2, а при нажатой - sbr1 потому, что команда call означает вызов подпрограммы (процедуры) расположенной там, где стоит соответствующая метка.
Команда return означает, что подпрограмма, обозначенная меткой sbros, закончилась и пора вернуться туда, откуда она была вызвана командой call.
Так, значит, кнопку нажали и пришли сюда:

incf - означает, что содержимое регистра (в данном случае наша переменная kcyk) увеличивается на единицу, а цифра 1 после kcyk означает, что результат этого сложения это kcyk+1. Не понятно? Если поставить 0, то kcyk остакнется kcyk, а результат kcyk+1 запишется в аккумулятор. Но нам надо отметить, что было нажатие кнопки. Это будет увеличение kcyk на единицу.

Дальше давайте рассмотрим вот этот кусочек программы:


movlw - запись какого-либо конкретного числа в аккумулятор. Соответственно: d h o или b это представление числа в десятичном (децимальном), шестнадцатиричном (гексадецимальном), восьмеричном (октагональном) или двоичном (бинарном) виде.
Subwf - вычитаем содержимое аккумулятора из регистра (kcyk) и, соответственно помещаем результат в аккумулятор. Почему в аккумулятор? А что бы проверить как прошло вычитание и чему равен результат. По сотоянию флагов регистра STATUS можно это определить. Флаг (бит) Z показывает : если результат вычитания равен нулю - флаг устанавливается в единицу; Если же не равен нулю - флаг устанавливается в ноль.
Данной процедурой мы проверяем; - а равно ли содержимое регистра kcyk единице? И, если равно, то пропускаем команду return и уходим выполнять другую подпрограмму. При всех остальных значениях мы будем всё время возвращаться туда, откуда пришли. Почему я решил сначала рассмотреть именно этот кусочек? Потому, что он определяет весь смысл данной процедуры - среагировать только на один импульс при нажатии на кнопку. Нельзя забывать, что выполнение программы происходит со скоростью работы внутреннего генератора процессора. Как правило это 4, 10, 20 мегагерц. Частота зависит в первую очередь от выбранного микроконтроллера и, естественно от поставленной задачи. Я об этом напоминаю потому, что за время, пока мы держали нажатой кнопку, обращение к программе было многократным и наша переменная kcyk все время увеличивалась на единицу. Поскольку этот счет ограничен и достигает значения FFh (если я ошибаюсь, то поправьте)
То ,что бы достичь этой величины, надо очень немного времени. И ещё: при переполнении регситр может себя повести не совсем и не всегда как нам надо, поэтому я ограничил эту величину и не даю ему переполниться.

Теперь должен быть понятен кусочек:



Но при циклическом счете у нас все время будет появляться единица и что бы исключить повторное срабатывание, по достижении граничной величины, я приравниваю kcyk двойке. Т.е. как только kcyk равна 255, так тут же она становится равна 2.



Но стоит нам отпустить кнопку, как мы приходим на ещё одну подпрограмму:

clrf - команда обнуления (очистки ) соответствующего регистра.

Итак , вроде бы разобрали все. Конечно это один из путей решения задачи. Конечно можно её упростить, и вообще придумать другой алгоритм. Скорее всего так и будет при составлении своей конкретной задачи.

В этом примере не учтено одно обстоятельство: - дребезг контактов.
Эта программка работала на частотах 4МГц и ниже, и помех от дребезга не было. Возможно это компенсировалось другими подпрограммами. Но об этом потом.

ВЫВОДЫ:

- метка должна быть уникальна и понятна;
- при сложении и вычитании обязательно указать, где должен быть результат:
0 - в аккумуляторе
1 - в регистре
(хотя MPASM - компилятор ассемблера, при отсутствии этого указания ставит по умолчанию единицу)
- подпрограмма, которую вызываем командой call, должна заканчиваться оператором return


Хостинг от uCoz