| На главную |
|
|
|
|
||
|---|---|---|
Примеры программирования |
||
Пример 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МГц и ниже, и помех от дребезга не было. Возможно это компенсировалось другими подпрограммами. Но об этом потом. ВЫВОДЫ:
- метка должна быть уникальна и понятна;
|
||
|
|
||