Главная » Начинающим
Призовой фонд
на август 2019 г.
1. 1000 руб
Паяльник
2. Тестер компонентов MG328
Паяльник
3. 200 руб.
От пользователей

Начинающим программистам микроконтроллеров PIC

Исходя из собственного опыта начала изучения программирования микроконтроллеров постараюсь дать несколько практических советов по составлению программ на ассемблере. Все, приведенные ниже, примеры программирования даны применительно к Pic контроллерам среднего семейства Microchip,как наиболее приемлемых для начала освоения, ввиду относи- тельно простой их архитектуры и несложной системы команд ассемблера.

Предлагаемые программы вполне можно применять в виде готовых макросов (законченных подпрограмм).Они не привязаны к конкретному контроллеру, поэтому при применении следует учитывать данные из datasheet -ов.

1.Применение прерываний от переполнения таймера TMR0 (RTCC)

Примем тактовую частоту - Fтакт. = 4,096 МГц (стандартный кварц). Тогда время цикла составит t c = 1 / Fтакт. * 4 = 0,97656 мкс

INI_TMR ; инициализация режима прерываний от RTCC bsf STATUS,RP0 ; выбираем банк 1 movlw b'00000100' movwf OPTION ; предделитель для RTCC 1 : 32 bcf STATUS,RP0 ; банк 0 movlw b'10100000' movwf INTCON ; разрешено прерывание от RTCC movlw .96 ; загружаем в RTCC предварительное число 96 movwf TMR0

Получим время прерываний:
t i = t c * 32 * (256 - 96 = 160)
t i = 0,97656 * 32 * 160 = 5 000 мкс = 5 мс

Теперь, если в Вашу любую программу ввести бесконечный цикл (так называемый цикл ожи- дания прерывания), и окончание программы переводить на этот цикл, получим временную привязку к 5 мс.И после прерывания программа вернётся по адресу, указанном вектором прерываний (чаще это 04h).Для чего это можно использовать - смотри дальше.

Итак:

; org 0 START ; начало выполнения программы после ; включения питания org 04h ; а это адрес вектора прерывания, по которому main ; будет выполняться основная программа ; START ; здесь обычно происходит обязательная ини- INI_TMR ; циализация портов, режимов, регистров и т.п. INI_PORTS loop goto loop ; а это и есть бесконечный цикл ;-------------------------------------------------- main ; далее идёт тело основной программы, ; в которой обязательно надо создать программу обслуживания прерываний от RTCC, ; вызываемой командой CALL: ServTMR btfsc INTCON,RTIF ; проверяем флаг срабатывания прерываний от RTCC и call SET_TMR ; если "да",то снова инициализируем TMR0 return ; если "нет" - возврат в место вызова ServTMR в ; основной программе main ; SET_TMR movlw .96 movwf TMR0 ; снова загружаем число 96 bcf INTCON,RTIF ; сбрасываем флаг срабатывания retfie ; возврат с разрешением прерываний в ServTMR, а ; затем в основную программу main

Пример использования прерывания от RTCC для получения секундного импульса на одном из выходов , скажем, порта В - RB0 : Используем регистр Rsec, который должен быть ранее объявлен в в адресном поле рабочих регистров.

FORM_1S ; в каждом цикле, а он по прерыванию RTCC длится incf Rsec,w ; 5 Мс, увеличиваем регистр Rsec на 1 до числа 200 xorlw .200 ; (5 мс * 200 = 1 сек) btfsc STATUS,z goto OUT_PORT ; при Rsec = 200 флаг z = '1' и переход на управление ; выводом RB0 порта В return ; возврат в основную программу main ; OUT_PORT btfss PORTB,0 ; проверяем состояние вывода RB0 goto OUT_ON ; если RB0 ='0', то устанавливаем в '1' bcf PORTB,0 ; в противном случае - устанавливаем в '0' goto main ; возврат в основную программу ; OUT_ON bsf PORTB,0 ; устанавливаем RB0 = '1' goto main

Таким образом на выходе RB0 порта В каждую секунду уровень сигнала будет изменяться то '0' то '1'.

В регистрах контроллера информация находится обычно в двоичном виде, ( в бинарном коде). Но часто необходимо получить информацию в двоично - десятичном виде (BCD - код), скажем, для управления поразрядно семисегментным индикатором.

Рассмотрим примеры преобразований двоичного кода b2 в двоично - десятичный BCD и наоборот.

В 8 - bit регистре можно записать в двоичном коде число от 0 до 255 ( от b'00000000' до b'11111111' ). Преобразуем двоичное число в три разряда двоично - десятичного кода - "сотни", "десятки" и "единицы". Для этого будем использовать следующие регистры, которые должны быть заранее объявлены в адресном поле рабочих регистров :

Rbin - регистр хранения числа в двоичном коде b2
Rhan - регистр "сотни" кода BCD
Rdec - регистр "десятки" кода BCD
Rsim - регистр "единицы" кода BCD

Преобразования проводим используя операции вычитания чисел 100, а затем 10 с подсчётом количества положительных вычитаний.

CON_100 movlw .100 ; вычитаем 100 из Rbin c проверкой, что subwf Rbin,w ; результат не отрицательный. Флаг 'c' = 1 при btfss STATUS,c ; результате > или = 0, и 'c' = 0 при < 0 goto CON_10 incf Rhan,f ; подсчёт количества "сотен" movwf Rbin ; результат вычитания сначала храним в регистре goto CON_100 ;аккумуляторе и только потом возвращаем в Rbin ; чтобы не потерять остаток при отрицательном ; результате вычитания. CON_10 movlw .10 ; аналогично определяем "десятки" subwf Rbin,w btfss STATUS,c goto end_con incf Rdec,f movwf Rbin goto CON_10; end_con movf Rbin,w movwf Rsim ; после вычитаний заносим остаток в "единицы" ;продолжение выполнения программы

Обратное преобразование BCD - кода в b2. Используем те же регистры Rhan, Rdec, Rsim где находится число в BCD - коде, регистры RbinH - старший разряд и RbinL - младший разряд для чисел ( > 255) в коде b2 и вспомогательные регистры RM1 - "множимое" , RM2- "множитель".Для преобразования BCD в b2 нужно умножить "сотни" на 100, "десятки" на 10 и сложить всё вместе с "единицами" и с учётом переноса в старший разряд при необ- ходимости.Для умножения используем операцию сложения.

B2X_100 movlw .99 ; преобразование "сотен" movwf RM2 ; множитель = кол - во сложений (100) минус один movf Rhan,w movwf RM1 ; множимое = "сотни" loopX100 addwf RM1,w btfsc STASTUS,c ; проверяем перенос в старший разряд incf RbinH,f ; если есть перенос decfsz RM2,f ; контролируем количество сложений goto loopX100 movwf RbinL ; результат сложения заносим в регистр мл. разряда ; B2X_10 movlw .9 ; преобразование "десятков" movwf RM2 ; множитель = кол - во сложений (10) минус один movf Rdec,w movwf RM1 ; множимое = "десятки" loopX10 addwf RM1,w ; здесь перенос можно не проверять, т.к. результат decfsz RM2,f ; всегда < 255 goto loopX10 addwf RbinL,f ; добавляем результат преобразования "десятков" btfsc STATUS,c ; учитывая возможный перенос в разрядах incf RbinH,f movf Rsim,w addwf Rbin,f ; добавляем "единицы" с учётом возможного переноса btfsc STATUS,c incf RbinH,f

Конец преобразованиям и дальнейшее выполнение программы. В регистрах RbinL и RbinH получили 16 - bit число в коде b2.

Для выполнения арифметической операции деления по аналогии с умножением, рассмот- ренном выше, применяется операция вычитания. Допустим нам нужно произвести деление числа, находящегося в регистрах RHsum (старшие разряды) и RLsum (младшие разряды) - на делитель ( примем делитель не > 255) находящийся в регистре Rdel.

Результат будем заносить в регистры RHrez и RLrez (старшие и младшие разряды соот- ветственно) :

OP_DEL movf Rdel,w subwf Rlsum,w btfss STATUS,c ; проверяем не отрицательный ли результат? goto DEF_carry ; если "да", то проводим заём из ст. разряда incf RLrez,f ; подсчитываем кол-во вычитаний с учётом btfsc STATUS,c ; возможного переноса в старший разряд incf RHrez,f movwf RLsum ; восстанавливаем остаток, что бы не потерять goto OP_DEL ; при отрицательном результате вычитания ; DEF_carry movlw 0h xorwf RHsum,w ; всё ли заняли из старшего разряда в младший? btfsc STATUS,z ; если "да", т.е. RHdel = 0 и в OP_DEL отри- goto OUT_ DEL ; цат. результат - конец делению и выход decf RHsum,f ; если "нет" - заём из старшего разряда и про- incf RLrez,f ; должаем дальше btfsc STATUS,c ; проверка необходимости переноса в ст.разряд incf RHrez,f goto OP_DEL

Автор: Владимир Д.
degvv@mail.ru

Источник: www.radiokot.ru

Владимир Д. Опубликована: 2006 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (2) | Я собрал (0) | Подписаться

0
Андрей #
Полезная страничка, спасибо автору.
Ответить
0
Андрей #
Все классно только зачем ахинею писать какой то RTCC - бред бугага.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Набор начинающего радиолюбителя
Набор начинающего радиолюбителя
ELM327 OBD II — адаптер с поддержкой CAN Солнечная панель 10Вт 12В поликристаллическая
вверх