Перемычка JP2Перемычка JP2 предназначена для подключения нагрузочного резистора 120 Ом к CAN интерфейсу. Перемычка установлена - резистор подключен, Перемычка удалена - резистор отключен. Схема соединения ЕМ 167-1 с PC компьютером для связи по RS232 показана на рисунке 11.
J5 Разъем PC компьютера
Рис. 11.
15. Комплект поставки
16. Варианты исполнения контроллера
Контроллер поставляется в следующих модификациях:
Суффикс –ЕХТ - диапазон рабочих температур: от -40'С до +85'С по всем контроллерам. Суффикс –KIT - все ответные части разъемов и кабель RS232.
Разъёмы: Разъёмы J1, J3, J4, J5, J9, J10, J11, J12, J13, JP1 прямые или угловые, или прямые вниз (по требованию заказчика). Замечание: При заказе контроллеров необходимо соблюдать обозначения изделий данные выше. Расположение выходных разъемов оговаривается отдельно.
17. Габаритные и установочные размеры
Габариты и установочные размеры платы показаны на рис. 12. Рис. 12. Размеры приведены в миллиметрах.
Примечание: Входные и выходные разъемы - J1, J3, J4, J5, J9, J10, J11, J12, J1З, JP1 - могут быть угловыми и выходить за габариты платы. 18. Приложения
Примеры программ, приведенные ниже, транслировались acceмблером asm167 версии 1.11 и проверялись отладчиком sfd7 версии 1.1.
Приложение А: преобразование кода Грея в двоичный весовой
Пример программы преобразования кода Грея в двоичный код. Для преобразования используются данные в регистре в регистре r0. Результат возвращается в регистре r0. Дополнительные регистры не используются. Циклов в пpoгpамме нет. grey: bxor 0.14, r0.15; Осуществляется последовательное bxor 0.13, r0.14; преобразование кода с помощью bxor r0.12, r0.13; операции битового «искключающего bxor r0.11, r0.12; ИЛИ (сложение по модулю 2). bxor r0.10, r0.11; Исходный и результирующий коды - bxor r0.9, r0.10; шестнадцатибитовые, однако, bxor r0.8, r0.9; при такой структуре программы bxor r0.7, r0.8; не составляет труда настроить bxor r0.6, r0.7; преобразователь на нужную bxor r0.5, r0.6; разрядность кода пpocтым удалением bxor r0.4, r0.5; или добавлением команд в bxor r0.3, r0.4; последовательность. bxor r0.2, r0.3; При увеличении разрядности bxor r0.1, r0.2; можно задействовать другие bxor r0.0, r0.1; регистры. ret end
Приложение Б: генерация шума (псевдослучайная последовательность)
Пример программы генератора шума. Программа генерирует псевдослучайную 16 битовую последовательность. Частота шумового сигнала определяется частотой вызова программы. StepNoise: rol r1, # 1; Такт сдвига. Первый отвод bxor r1.0, r1.14; Второй отвод bxor r1.0, r1.13; Третий отвод bxor r1.0, r1.11; Четвертый отвод ret; Такт ПСП закончен end
Приложение В: формирование звука
Пример подпрограмм формирования звука. Программа формирования звуков базируется на использование блока таймеров GPT2 (Таймеры Т5, Т6 и регистр CAPREL). Выходной сигнал музыкального фрагмента формируется на выводе порта Р3.1. Основной цикл программы: org 1000h cykle: calla cc_UC, playmusic jmpr cc_UC, cykle
Подпрограмма запуска звучания ноты. В регистре r0 содержится значение частоты звучания ноты. В регистре r1 содержится значение длительности звучания ноты. Инициализация таймера Т6:
Инициализация таймера Т5:
begsound: push r1; Длительность звучания pop Т5; ноты в таймер Т5 push r0; Начальное значение pop CAPREL; коэффициента деления в CAPREL. push r0; Начальное значение pop T6; коэффициента деления в таймер bset DP3.1; Разрешить выход таймера Т6 mov T6CON, # 82C0h; Инициализировать таймер Т6 mov T5CON, # 000C7h; Инициализировать таймер Т5 bset T6OUT; Включить выход таймера Т6 ret
Подпрограмма формирования паузы. В регистре r1 содержится длительность звучания ноты. begpause: push r1; Значение коэффициента pop T5; деления mov T5CON, # 000C7h; Запустить таймер Т5 ret
Подпрограмма ожидания конца звучания ноты или паузы.
WendSound: jnb T5IR, WendSound; Ожидать запроса прерывания от Т5 bclr T6OUT; Выключить выход таймера Т6 mov T5con, # 0; Остановить таймер Т5 bclr 5IR; Очистить бит прерывания таймера Т5 ret
Воспроизведение мелодии из массива. В регистре r2 содержится адрес таблицы нот и длительностей звучания. playmusic: mov r4, # elka; Адрес массива нот beginMusic: mov r0, [r2+]; Частота jmpr cc_Z, endMusic; Если 0 - закончить mov r1, [r2+]; Длительность calla cc_UC, begsound; Включить звучание ноты calla cc_UC, WendSound; Ждать конца ноты mov r1, # 700; Пауза между нотами calla cc_UC, BegPause; Включить звучание ноты calla cc_UC, WendSound; Ждать конца ноты jmpr cc_UC, BeginMusic endMusic: ret; Воспроизведение завершено.
Массив нот и длительностей звучания. ELKA: dw C75h, 10752, 768h, 10752, 768h, 10752, 850h, 10752 dw 768h, 10752, 955h, 10752, C75h, 10752, C75h, 10752 dw C75h, 10752, 768h, 10752, 768h, 10752, 6FEh, 10752 dw B19h, 10752, 63Ah, 32256, 63Ah, 10752, 1632h, 10752 dw 1632h, 10752, 6FEh, 10752, 6FEh, 10752, 768h, 10752 dw 850h. 10752, 955h, 10752, C75h, 10752, 768h, 10752 dw 768h, 10752, 850h, 10752, 768h, 10752, 955, 32256 dw C75h, 10752, 768h, 10752, 768h, 10752, 850h, 10752 dw 768h, 10752, 955h, 10752, C75h, 10752, C75h, 10752 dw C75h, 10752, 768h, 10752, 768h, 10752, 6FEh, 10752 dw B19h, 10752, 63Ah, 32256, 63Ah, 10752, 1632h, 10752 dw 1632h, 10752, 6FEh, 10752, 6FEh, 10752, 768h, 10752 dw 850h, 10752, 955h, 10752, C75h, 10752, 768h, 10752 dw 768h, 10752, 850h, 10752, 768h, 10752, 955h, 32256 dw 0h, 0 - Признак конца массива нот end
Приложение Г: инициализация страницы ввода/вывода
Подпрограмма инициализации страницы ввода/вывода Подпрограмма начальной установки системных регистров для дополнительных устройств (АЦП, ЦАП, часов реального времени). Эта подпрограмма должна быть выполнена один раз перед обращением к любой приведенной ниже подпрограмме, использующей команду ЕХТР. При отсутствии инициализации регистров ADDRSEL4 и BUSCON4 доступ к дополнительным устройствам невозможен. Регистр ADDRSEL4 может задавать любой размер памяти, однако для правильной работы подпрограмм обмена с дополнительными устройствами необходимо перекрытие последней страницы.
InitBus: mov addrsel4, #0FFF0h; Последние 4 килобайта mov buscon4, #4B8h; Настроить системные регистры ret
Приложение Д: работа с часовым таймером
Примеры подпрограмм работы с часовым таймером ; Командные слова для считывания из таймера: SecondRd equ 1000.0001b; команда - считать значение секунд из таймера MinuteRd equ 1000.0011b; команда - считать значение минут из таймера HoursRd equ 1000.0101 b; команда - считать значение часов из таймера
; Командные слова для записи в таймер: SecondWr equ 1000.0000b; команда - записать значение секунд в таймер MinuteWr equ 1000.0010b; команда - записать значение минут в таймер HoursWr equ 1000.0100b; команда - записать значение часов в таймер org0 jmpa cc_Uc, start_timer; Запуск таймера. jmpa cc_Uc, ReadDann; Считывание значений таймера.
Программа управления и работы с таймером DS1302 org 200h; Область расположения программы sCLK dbit P4.4; Бит тактов таймера (Р4.4) setsCLK dbit DP4.4; Управление битом тактов (dP4.4) In/Out dbit P4.7; Бит ввода/вывода таймера (Р4.7) setin/Out dbit DP4.7; Управление битом ввода/вывода (dP4.7) RSTtimer dbit P6.7; Бит сброса таймера (Р6.7) setRSTtimer dbit DP6.7; Управление битом сброса (dP6.7) initPort: bset setsCLK; Инициализация битов bset setRSTtimer; управления таймером, bset setIn/Out ret ; Послать байт в таймер ; Данные для выдачи в таймер должны находиться в регистре RO sendByte: bset setIn/Out; Установить бит на передачу данных mov r2, #8; Загрузить счетчик битов nextbit bmov In/Out, r0.0; Установить бит для записи в таймер bset sClk; Записать бит данных в таймер rоr r0, #1; Подготовить следующий бит для записи bclr sClk sub r2, #1; Проверить все ли биты выданы jmpr cc_nZ, nextbit; в таймер bclr setIn/Out; Подготовить процессор к приему ret; данных из таймера ; Получить байт из таймера ; Данные считанные из таймера помещаются в регистр R0 recieveByte: mov r2, #8; Загрузить счетчик битов mov r0, #0; Очистить регистр приема данных rec1bit: bset sClk; Установить бит синхронизации rоr r0, #1 bmov r0.7, In/Out; Считать бит из таймера bclr sClk; Сбросить бит синхронизации sub r2, #1; Проверить все ли биты считаны jmpr cc_nZ, reclbit ret ; Получить значение (секунд, минут и т.д) из таймера ; Значение считанное из таймера помещается в регистр R0 ReadDann: bset RSTtimer mov r0, #SecondRd; Выдача команды для получения callr SendByte; значения секунд callr recieveByte; Получение значения секунд в R0 bclr RSTtimer ret start_timer: calla cc_UC, initPort; Инициализировать процессор ; для работы с таймером bset RSTtimer; установить сигнал RST mov r0, #SecondWr; Выдача команд для установки calla cc_UC, sendByte; секунд в таймер mov r0, #0; Выдача значений секунд calla cc_Uc, sendByte; в таймер (запуск таймера) bclr RSTtimer; Сброс сигнала RST ret end
Приложение Е: работа с внутренним АЦП микроконтроллера
Примеры подпрограмм работы с внутренним АЦП микроконтроллера SAB 80C167
Maxlnp equ 16; Количество каналов для С167 org 01000h
Подпрограмма работы с внутренним АЦП ; Номер канала АЦП в RI0. ; Результат измерения в R0. ReadADC: cmp r0, # Maxlnp; Максимальный номер входа jmpr cc_NC, error; Номер канала ошибочен push r0; Загрузить номер канала pop ADCON; в регистр конфигурации bset ADST; Запустить преобразование WaitADC: nор; Используется для трассирования ; и может быть удален jb ADBSY, waitADC; Преобразование завершено? push ADDAT; Прочитать данные в pop r0; регистр R0 and r0, # 003FFh; Удалить номер канала из результата ret; Конец подпрограммы error: bset С; Установить флаг ошибочного канала ret
Примечание: В подпрограмме используется передача данных через стек парой команд PUSH/POP. Вместо них можно было бы использовать команду MOV, однако ее применение требует контроля или принудительной установки регистра DPP3, кроме того команда MOV занимает 2 слова кода также, как и PUSH/POP.
Тестовая программа для проверки подпрограммы работы с внутренним АЦП Последовательно запускает преобразование каналов АЦП и при получении флага ошибки С сбрасывает номер канала в 0 и повторяет цикл. Test: mov r1,#0; Установить номер канала 0 tst: mov r0, r1; Номер канала в рабочий регистр calla cc_UC, ReadADC; Считать значение в канале jmpr cc_C, Test; Ошибочный номер канала. Сбросить add r1, #1; Установить следующий канал jmpr cc_UC, tst; Продолжить работу org 0; Обычно программы запускаются jmpa cc_UC, Test; с адреса 0. Это довольно удобно end
Приложение Ж: стартовый загрузчик
Пример программы стартового загрузчика, которая может быть загружена с помощью bootstrap, и позволит загрузить пользовательскую программу произвольной длины в заданную область памяти. org 0FA40h; Адрес загрузки bootstrap
Программа основного цикла загрузчика Примечание: При загрузке программы пользователя в младшую область памяти, где используется короткая адресация операнда, надо добавить в конец программы несколько команд NOP, так, чтобы общая длина программы была равна 32 байтам, или в программе передачи блока добавить необходимые байты. Данный загрузчик не может загрузить программу размером более одной страницы, т. к. не настраивает регистры страниц и не наращивает DPP0. Seg equ 002h; Сегментная часть стартового адреса startPGM equ 01000h; Стартовый адрес программы begPGM equ 00000h; Страничный адрес начала загрузки endPGM equ 01234h; Последний адрес (длина) программы page equ 008h; Страница для загрузки
Примечание: При определении адреса загрузки программы необходимо учитывать номер DPPx и корректировать его или адрес. preloader: mov r0, # begPGM Начальный адрес программы (4/2) mov DPP0, # page Стартовый адрес программы (4) 1$: jnb SORIR, 1$ Байт поступил? (4) movb [R0], SORBUF Принять байт (4) bclr SORIR Занять канал (2) cmpi1 r0, # endPGM Проверка на конец цикла, сравнение с конечным адресом программы (4/2) jmpr cc_NZ, 1$ (2) jmps seg, startPGM Переход в основную программу (4) nop Выравнивание до 32 байтов (2) nop Выравнивание до 32 байтов (2) nop Выравнивание до 32 байтов (2) endblock: Эта метка используется для контроля длины получившегося блока и должна быть равна 0FA60h end
Приложение З: генерация сигналов PWM
Пример подпрограммы генерации сигналов PWM ; Запускает все доступные каналы PWM, реализованные на блоках САРСОМ. ; Индекс модуляции каждого канала отличается 10h. org 0 jmpa cc_UC, start; Пропустить область векторов прерываний ; Векторы прерываний. org 200h Start: mov r0, # 000h; Начинаем с канала 0 mov r1, # 003h; Индекс модуляции первого канала Test: mov r2, # 1000h; Период push r0; Сохранить номер канала и таймер push r1; Сохранить индекс модуляции calla cc_UC, initPWM; Установить индекс модуляции jmpr cc_C, Halt; Последний канал (признак ошибки)? pop r1; Восстановить индекс модуляции pop r0; Восстановить номер канала и таймер add r1, # 10h; Изменить индекс модуляции addb rl0, # 1; Следующий канал xorb rh0, # 0FFh; Другой таймер jmpr cc_UC, Test; Продолжить работу Halt: srvwdt; Обслужить сторожевой таймер jmpr cc_UC, Halt; Зациклиться maxPWM equ 28; Для С167 При аппаратном генерировании PWM в процессорах С167, каналы ССМ24-ССМ27 не имеют внешних выводов. Поэтому в программах инициализации и изменения индекса модуляции они пропущены в нумерации. Следовательно, имеем: Канал 00 - Р2.0, канал 01 - Р2.1,... канал 15 - Р2.15; канал 16 - Р8.0, канал 17 - Р2.0,... канал 23 - Р8.7; канал 24 - Р7.4, канал 25 - Р7.5, канал 26 - Р7.6, канал 27 - Р7.7.; ; Инициализировать канал PWM. rL0 - Номер канала PWM (0 - maxPWM) rH0 - Таймер 0/1 7/8 (0, не ноль) r1 - Индекс модуляции (0 - 0FFFFh) r2 - Период PWM (0 - 0FFFFh) ; Использует (портит) R0, R1, R2, R3, R4. ; Возвращает флаг С, если номер канала неверен.
Initpwm: cmpb rl0, # maxPWM; Проверить номер канала jmpr cc_C, CapcomPWM ; Завершение подпрограммы с установкой флага С. bset с; Установить флаг ошибки ret; Выйти из подпрограммы CapcomPWM: neg r1; Таймер считает вверх neg r2; Таймер считает вверх pop r4; Адрес возврата со стека push r1; Индекс модуляции на стек push r4; Адрес возврата на стек push r2; Период модуляции - на стек cmpb rh0, # 0; Определить ассоциированный таймер. bmovn r0.8, Z movbz r2, rl0; Подготовить для расчета адреса add r2, r2; Умножить на 2 cmpb rl0, # 16; Определить блок capcom jmpr cc_C, setTimer01 jnb r0.8, setTimer7 jmpr cc_UC, setTimer8 setTimer01: jb r0.8, setTimerl setTimer0:; Период модуляции со стека pop t0rel; занести в регистр таймера Т0. bfldl t01con, # 0BFh, # 040h; Запустить таймер в работу jmpr cc_UC, setCCM setTimerl:; Период модуляции со стека pop tlrel; занести в регистр таймера Т1. bfldh t01 con, # 0BFh, #040h; Запустить таймер в работу jmpr cc_UC, setCCM setTimer7: extr 1; Период модуляции со стека pop t7rel; занести в регистр таймера Т7 bfldl t78con, # 0BFh, # 040h; Запустить таймер в работу jmpr cc_UC, setCCM setTimer8: extr 1; Период модуляции со стека pop t8rel; занести в регистр таймера Т8 bfldh t78con, # 0BFh, # 040h; Запустить таймер в работу jmpr cc_UC, setCCM setCCM00: bfldl ccm0, # 00Fn, 007h bset p2.0; Включить выход порта bmov ccm0.3, r0.8; Определить таймер bset dp2.0; Разрешить работу порта retp cc0; Установить индекс модуляции setCCM01: bfldl ccm0, # 0F0h, 070h bset p2.1; Включить выход порта bmov ccm0.7, r0.8; Определить таймер bset dp2.1; Разрешить работу порта retp cc1; Установить индекс модуляции setCCM02: bfldh ccm0, # 00Fh, 007h bset p2.2; Включить выход порта bmov ccm0.11, r0.8; Определить таймер bset dp2.2; Разрешить работу порта retp cc2; Установить индекс модуляции setCCM03: bfldh ccm0, # 0F0h, 070h bset p2.3; Включить выход порта bmov ccm0.15, r0.8; Определить таймер bset dp2.3; Разрешить работу порта retp сс3; Установить индекс модуляции setCCM04: bfldl ccml, #00Fh, 007h bset p2.4; Включить выход порта bmov ccm1.3, r0.8; Определить таймер bset dp2.4; Разрешить работу порта retp cc4; Установить индекс модуляции setCCM05: bfldl ccml, # 0F0h, 070h bset p2.5; Включить выход порта bmov ccm1.7, r0.8; Определить таймер bset dp2.5; Разрешить работу порта retp cc5; Установить индекс модуляции setCCM06: bfldh ccml, # 00Fh, 007h bset p2.6; Включить выход порта bmov ccm1.11, r0.8; Определить таймер bset dp2.6; Разрешить работу порта retp сс6; Установить индекс модуляции setCCM07: bfldh ccml, # 0F0h, 070h bset p2.7; Включить выход порта bmov ccm1.15, r0.8; Определить таймер bset dp2.7; Разрешить работу порта retp cc7; Установить индекс модуляции setCCM08: bfldl ccm2, # 00Fh, 007h bset p2.8; Включить выход порта bmov ccm2.3, r0.8; Определить таймер bset dp2.8; Разрешить работу порта retp cc8; Установить индекс модуляции setCCM09: bfldl ccm2, # 0F0h, 070h bset p2.9; Включить выход порта bmov ccm2.7, r0.8; Определить таймер bset dp2.9; Разрешить работу порта retp cc9; Установить индекс модуляции setCCM10: bfldh ccm2, #00Fh, 007h bset p2.10; Включить выход порта bmov ccm2.11, r0.8; Определить таймер bset dp2.10; Разрешить работу порта retp cc10; Установить индекс модуляции setCCM11: bfldh ccm2, # 0F0h, 070h bset p2.11; Включить выход порта bmov ccm2.15, r0.8; Определить таймер bset dp2.11; Разрешить работу порта retp cc11; Установить индекс модуляции setCCM12: bfldl ссm3, # 00Fh, 007h bset p2.12; Включить выход порта bmov ссm3.3, r0.8; Определить таймер bset dp2.12; Разрешить работу порта retp cc12; Установить индекс модуляции setCCM13: bfldl ccm3, # 0F0h, 070h bset p2.13; Включить выход порта bmov ccm3.7, r0.8; Определить таймер bset dp2.13; Разрешить работу порта retp сc 13; Установить индекс модуляции setCCM14: bfldh сст3, # 00Fh, 007h bset p2.14; Включить выход порта bmov ccm3.11, r0.8; Определить таймер bset dp2.14; Разрешить работу порта retp cc14; Установить индекс модуляции setCCM15: bfldh ссm3, # 0F0h, 070h bset p2.15; Включить выход порта bmov ccm3.15, r0.8; Определить таймер bset dp2.15; Разрешить работу порта retp cc15; Установить индекс модуляции setCCM: callr SelchanPWM; Адрес таблицы переходов - на стек jmpr cc_UC, setCCM00; Таблица переходов для jmpr cc_UC, setCCM01; блока САРСОМ1 jmpr cc_UC, setCCM02 jmpr cc_UC, setCCM03 jmpr cc_UC, setCCM04 jmpr cc_UC, setCCM05 jmpr cc_UC, setCCM06 jmpr cc_UC, setCCM07 jmpr cc_UC, setCCM08 jmpr cc_UC, setCCM09 jmpr cc_UC, setCCM10 jmpr cc_UC, setCCM11 jmpr cc_UC, setCCM12 jmpr cc_UC, setCCM13 jmpr cc_UC, setCCM14 jmpr cc_UC, setCCM15 jmpr cc_UC, setCCM16 jmpr cc_UC, setCCM17 jmpr cc_UC, setCCM18 jmpr cc_UC, setCCM19 jmpr cc_UC, setCCM20 jmpr cc_UC, setCCM21 jmpr cc_UC, setCCM22 jmpr cc_UC, setCCM23 jmpr cc_UC, setCCM28 jmpr cc_UC, setCCM29 jmpr cc_UC, setCCM30 jmpr cc_UC, setCCM31 SelchanPWM: pop r1; Адрес таблицы переходов со стека add r1, r2; Номер регистра ССх * 2. bclr с; Сбросить флаг ошибки jmpi cc_UC, (r1); Перейти по адресу setCCM16: bfldl ccm4, #00Fh, 007h bset p8.0; Включить выход порта bmov ccm4.3, r0.8; Определить таймер bset dp8.0; Разрешить работу порта retp cc16; Установить индекс модуляции setCCM17: bfldl ccm4, # 0F0h, 070h bset p8.1; Включить выход порта bmov ccm4.7, r0.8; Определить таймер bset dp8.1; Разрешить работу порта retp cc17; Установить индекс модуляции setCCM18: bfldh ccm4, #00Fh, 007h bset p8.2; Включить выход порта bmov ccm4.11, r0.8; Определить таймер bset dp8.2; Разрешить работу порта retp cc18; Установить индекс модуляции setCCM19: bfldh ccm4, # 0F0h, 070h bset p8.3; Включить выход порта bmov ccm4.15, r0.8; Определить таймер bset dp8.3; Разрешить работу порта retp cc19; Установить индекс модуляции setCCM20: bfldl ccm5, #00Fh, 007h bset p8.4; Включить выход порта bmov ссm5.3, r0.8; Определить таймер bset dp8.4; Разрешить работу порта retp cc20; Установить индекс модуляции setCCM21: bfldl ccm5, #5F5h, 070h bset p8.5; Включить выход порта bmov ccm5.7, r0.8; Определить таймер bset dp8.5; Разрешить работу порта retp cc21; Установить индекс модуляции setCCM22: bfldh ccm5, #00Fh, 007h bset p8.6; Включить выход порта bmov ccm5.11, r0.8; Определить таймер bset dp8.6; Разрешить работу порта retp cc22; Установить индекс модуляции setCCM23: bfldh ccm5, #0F0h, 070h bset p8.7; Включить выход порта bmov ccm5.15, r0.8; Определить таймер bset dp8.7; Разрешить работу порта retp cc23; Установить индекс модуляции setCCM28: bfldl ccm7, #00Fh, 007h bset p7.4; Включить выход порта bmov ccm7.3, r0.8; Определить таймер bset dp7.4; Разрешить работу порта retp cc28; Установить индекс модуляции setCCM29: bfldl ccm7, #0F0h, 070h bset p7.5; Включить выход порта bmov ccm7.7, r0.8; Определить таймер bset dp7.5; Разрешить работу порта retp cc29; Установить индекс модуляции setCCM30: bfldh ccm7, #00Fh, 007h bset p7.6; Включить выход порта bmov ccm7.11, r0.8; Определить таймер bset dp7.6; Разрешить работу порта retp сс30; Установить индекс модуляции setCCM31: bfldh ccm7, #0F0h, 070h bset p7.7; Включить выход порта bmov ccm7.15, r0.8; Определить таймер bset dp7.7; Разрешить работу порта retp cc31; Установить индекс модуляции ; Установить индекс модуляции канала. ; Номер канала в регистре rL0. ; Индекс модуляции в r1. ; Использует (портит) R0, R1, R2. ; Возвращает флаг С, если номер канала неверен. setPWM: cmpb rI0, # maxPWM; Проверить номер канала jmpr cc_C, setPWMst bset с; Установить флаг ошибки ret; Выйти из подпрограммы setPWMst: pop r2; Адрес возврата push r1; Индекс модуляции на стек push r2; Вернуть на стек для RETP movb rh0, # 0; Подготовить расчет перехода add r0, r0; Команды двухбайтовые callr SelectPWM; Адрес таблицы команд - на стек retp cc0; Установить индекс модуляции retp cc1; Установить индекс модуляции retp cc2; Установить индекс модуляции retp сс3; Установить индекс модуляции retp cc4; Установить индекс модуляции retp сс5; Установить индекс модуляции retp сс6; Установить индекс модуляции retp cc7; Установить индекс модуляции retp cc8; Установить индекс модуляции retp cc9; Установить индекс модуляции retp cc10; Установить индекс модуляции retp cc11; Установить индекс модуляции retp cc12; Установить индекс модуляции retp c13; Установить индекс модуляции retp cc14; Установить индекс модуляции retp cc15; Установить индекс модуляции retp cc16; Установить индекс модуляции retp cc17; Установить индекс модуляции retp сc18; Установить индекс модуляции retp cc19; Установить индекс модуляции retp cc20; Установить индекс модуляции retp cc21; Установить индекс модуляции retp cc22; Установить индекс модуляции retp cc23; Установить индекс модуляции retp cc28; Установить индекс модуляции retp cc29; Установить индекс модуляции retp сс30; Установить индекс модуляции retp cc31; Установить индекс модуляции selectPWM: pop r1; Взять адрес таблицы переходов add r1, r0; Добавить номер канала bclr с; Сбросить флаг ошибки jmpi cc_UC, [r1]; Переход на команду установки org 0; Маленькая хитрость для удобства запуска ; тестовой программы из отладчика SF7 end
Приложение И: генерация сигналов высокоскоростного PWM
Пример подпрограммы генерации сигналов высокосокростного PWM. ; Запускает все доступные каналы быстрого PWM. ; Индекс модуляции каждого канала отличается 800h. org 0 jmpa cc_UC, start; Пропустить область векторов прерываний ; Векторы прерываний. org 200h Start: mov r0, # 000h; Начинаем с канала 0 nор; Зарезервировано для отладки mov r1, # 400h; Индекс модуляции первого канала mov r2, # 2000h; Период mov r3, # 0; Старт с 0 test: calla cc_UC, initFPWM; Установить индекс модуляции jmpr cc_C, StartF; Последний канал (признак ошибки)? add r1, # 800h; Изменить индекс модуляции addb rl0, # 1; Следующий канал jmpr cc_UC, Test; Продолжить работу StartF: mov r0, # 00Fh; Запустить все каналы calla cc_UC, StartFpwm jmpa cc_UC, Halt Newlndex: mov r0, # 0; Номер канала mov r1, # 8000; Индекс модуляции calla cc_UC, setfPWM jmpr cc_UC, Newlndex org 400h Halt: srvwdt; Обслужить сторожевой таймер jmpr cc_UC, Halt; Зациклиться maxFPWM equ 4 ; Всего 4 канала быстрого PWM. ; Инициализировать канал PWM. rL0 - Номер канала PWM. (0 - maxPWM) rh0 - Конфигурирование канала: r0. 8 = 1 - Канал быстрого PWM включен, R0. 8 = 0 выключено r0. 9 = 1 - Предделитель включен (Ft/64), R0. 9 = 0 выключен. r0.10 = 1 - Выходной сигнал симметричен, R0.10 = 0 несимметричен. r0.11 = 1 - Выходной сигнал инвертирован, R0.11 = 0 неинвертирован. ; R0.12... R0.15 не используются. r1 - Индекс модуляции. (0 - 0FFFFh) r2 - Период PWM. (0 - 0FFFFh) r3 - Стартовое значение таймера. (0 - 0FFFFh) ; Использует (портит) R0, R1. ; Возвращает флаг С, если номер канала неверен. Примечание: На время изменения значений в каналах работа таймеров останавливается. Это необходимо для получения сдвинутых во времени импульсов. Если выходные сигналы не имеют привязки друг относительно друга или необходимо менять частоту PWM без остановки таймера, то можно удалить для соответствующего канала команду bclr PTRx. InitFPWM: push r1; Индекс модуляции на стек push r2; Период модуляции на стек push r3; Стартовое значение на стек cmpb rl0, # 0; Канал 0? jmpr cc_Z, Fpwm0 cmpb rl0, # 1; Канал 1? jmpr cc_Z, Fpwm1 cmpb rl0, # 2; Канал 2? jmpr cc_Z, Fpwm2 cmpb rl0, # 3; Канал 3? jmpr cc_Z, Fpwm3 ; Завершение подпрограммы с установкой флага С. add sp, # 6; Восстановить стек bset с; Установить флаг ошибки ret; Выйти из подпрограммы Fpwm0: bclr ptr0; Остановить работу (если работает) extr 2; Регистры таймера и периода в ESFR pop PT0; Стартовое значение таймера pop PP0; Регистр периода pop PW0; Регистр длины bmov р7.0, r0.11; Инверсия bmov pm0, r0.10; Симметрия bmov pti0, r0.9; Предделитель bmov ptr0, r0.8; Запуск в работу bset pen0; Разрешить выход bset dp7.0; очистить флаг ошибки ret Fpwml: bclr ptrl; Остановить работу (если работает) extr 2; Регистры таймера и периода в ESFR pop PT1; Стартовое значение таймера pop PP1; Регистр периода pop PW1; Регистр длины bmov р7.1, r0.11; Инверсия bmov pm1, r0.10; Симметрия bmov pti1, r0.9; Предделитель bmov ptrl, r0.8; Запуск в работу bset pen1; Разрешить выход bset dp7.1; очистить флаг ошибки ret Fpwm2: bclr ptr2; Остановить работу (если работает) extr 2; Регистры таймера и периода в ESFR pop PT2; Стартовое значение таймера pop PP2; Регистр периода pop PW2; Регистр длины bmov p7.2,r0.11; Инверсия bmov pm2, r0.10; Симметрия bmov pti2, r0.9; Предделитель bmov ptr2, r0.8; Запуск в работу bset pen2; Разрешить выход bset dp7.2; Очистить флаг ошибки ret Fpwm3: bclr ptr3; Остановить работу (если работает) extr 2; Регистры таймера и периода в ESFR pop PT3; Стартовое значение таймера pop PP3; Регистр периода pop PW3; Регистр длины bmov р7.3, r0.11; Инверсия bmov pm3, г0.10; Симметрия bmov pti3, r0.9; Предделитель bmov ptr3, r0.8; Запуск в работу bset pen3; Разрешить выход bset dp7.3; Очистить флаг ошибки ret ; Запустить каналы в работу. ; Использует (портит) R0, R1. StartFpwm: and r0,#0000Fh; Оставить только биты старта push PWMCON0; Контрольный регистр PWMCON0 pop r1; Скопировать в R1 or r1, r0; Наложить маску запускаемых каналов push r1; Скопировать регистр г1 в pop PWMCON0; контрольный регистр PWMCON0 ret ; Запустить каналы в работу. ; Использует (портит) R0, R1. StopFpwm: or r0, # 0FFF0h; Оставить только стоповые биты push PWMCON0; Контрольный регистр PWMCON0 pop r1; Скопировать в R1 and r1, r0; Наложить маску каналов push r1; Скопировать регистр г1 в pop PWMCON0; контрольный регистр PWMCON0 ret ; Установить индекс модуляции канала. ; Номер канала в регистре rL0. Индекс модуляции в r1. ; Использует (портит) R0, R1, R2. ; Возвращает флаг С, если номер канала неверен. setfPWM: cmpb rl0, # maxFPWM; Проверить номер канала jmpr cc_C, setPWMst bset с; Установить флаг ошибки ret; Выйти из подпрограммы setPWMst: pop r2; Адрес возврата push r1; Индекс модуляции на стек push r2; Вернуть на стек для RETP movb rh0, # 0; Подготовить расчет перехода add r0, r0; Команды двухбайтовые callr SelectPWM; Адрес таблицы команд - на стек retp pw0; Установить индекс модуляции retp pw1; Установить индекс модуляции retp pw2; Установить индекс модуляции retp pw3; Установить индекс модуляции selectPWM: pop r1; Взять адрес таблицы переходов add r1, r0; Добавить номер канала bclr с; Сбросить флаг ошибки jmpi cc_UC, [r1]; Переход на команду установки org 0; Маленькая хитрость для удобства ; запуска тестовой программы ; из отладчика SFD7 end
Приложение К: работа с CAN
Пример подпрограммы работы с CAN. ControlStatus EQU 0EF00h; Control / ststus register InterruptReg EQU 0EF02h; Interrupt register BitTimingReg EQU 0EF04h GlobalMaskShort EQU 0EF06h GlobalMaskLong EQU 0EF08h Message15Mask EQU 0EF0Ch ArbitrMsgl EQU 0EF12h ArbitrMsg2 EQU 0EF22h ArbitrMsg3 EQU 0EF32h ArbitrMsg4 EQU 0EF42h ArbitrMsg5 EQU 0EF52h ArbitrMsg6 EQU 0EF62h ArbitrMsg7 EQU 0EF72h ArbitrMsg8 EQU 0EF82h ArbitrMsg9 EQU 0EF92h ArbitrMsg10 EQU 0EFA2h ArbitrMsg11 EQU 0EFB2h ArbitrMsg12 EQU 0EFC2h ArbitrMsg13 EQU 0EFD2h ArbitrMsg14 EQU 0EFE2h ArbitrMsg15 EQU 0EFF2h configMsg1 EQU 0EF16h configMsg2 EQU 0EF26h configMsg3 EQU 0EF36h configMsg4 EQU 0EF46h configMsg5 EQU 0EF56h configMsg6 EQU 0EF66h configMsg7 EQU 0EF76h configMsg8 EQU 0EF86h configMsg9 EQU 0EF96h configMsg10 EQU 0EFA6h configMsg11 EQU 0EFB6h configMsg12 EQU 0EFC6h configMsg13 EQU 0EFD6h configMsg14 EQU 0EFE6h configMsg15 EQU 0EFF6h MESSAGE1 EQU 0EF10h MESSAGE2 EQU 0EF20h MESSAGE3 EQU 0EF30h MESSAGE4 EQU 0EF40h MESSAGE5 EQU 0EF50h MESSAGE6 EQU 0EF60h MESSAGE7 EQU 0EF70h MESSAGE8 EQU 0EF80h MESSAGE9 EQU 0EF90h MESSAGE10 EQU 0EFA0h MESSAGE11 EQU 0EFB0h MESSAGE12 EQU 0EFC0h MESSAGE13 EQU 0EFD0h MESSAGE14 EQU 0EFE0h MESSAGE15 EQU 0EFF0h org 1000h ; Пересортировать биты арбитража. ; R0 - младшая часть идентификатора. ; R1 - старшая часть идентификатора. ; R2 - Базовый адрес регистра. setMask: shl r0, # 1; Сдвинуть три старших addc r1, r1; бита идентификатора shl r0, # 1; (или маски) из младшего addc r1, r1; слова в старшее. При shl r0, # 1; этом старшие биты младшего addc r1, r1; слова обнуляются ror r0, # 8; Подготовить младшую часть ror r1, # 8; Подготовить старшую часть exts 0, 2; Установить первый сегмент mov [r2], r1; Занести новое mov 2 [r2+], r0; значение ret ; Восстановить биты арбитража (операция обратная setMask). R0 - младшая часть идентификатора. R1 - старшая часть идентификатора. R2 - Базовый адрес регистра. ReadMask exts 0, 2; Установить первый сегмент mov r1, [r2]; Считать текущее mov r0, 2 [r2+]; значение арбитра bmov r0.10, r1.10; Переместить 3 бита bmov r0.9, r1.9; из регистра r1 bmov r0.8, r1.8; в регистр r0 and r1, # 0F8FFh; Сбросить ненужные биты ror r0, # 0Bh; Подготовить младшую часть ror r1, # 0Bh; Подготовить старшую часть ret ; Начальная иницализация CAN контроллера. InitCAN: scxt dpp3, # 3; Регистры на 3 странице mov r0, # 00041h; Установить init.bie mov ControlStatus, r0; CCE bit mov r0, # 03440h; Fcpu = 20 mHz mov r0, # 02340h; Fcpu = 16 mHz mov BitTimingReg, r0; SJW, BRP, TSEG1, TSEG2, Spl mov r0, # 0FFFFh; Установить глобальные mov r1, # 0FFFFh; маски: mov r2, # GlobalMaskShort; короткую calla cc_UC, setMask mov r0, #0FFFFh mov r0, # 0FFFFh mov r2, # GlobalMaskLong; длинную calla cc_UC, sqtMask mov r0, # 0FFFFh mov r1, # 0FFFFh mov r2, # Message 15Mask; и маску 15 сообщения calla cc_UC, setMask mov r0, # 00000h; Прерывания не используются rnov InterruptReg, r0; (запрещены) mov r0, # 05555h; Деактивировать mov MESSAGE1, r0; все сообщения mov MESSAGE2, r0 mov MESSAGE3, r0 mov MESSAGE4, r0 mov MESSAGE5, r0 mov MESSAGE6, r0 mov MESSAGE7, r0 mov MESSAGE8, r0 mov MESSAGE9, r0 mov MESSAGE10, r0 mov MESSAGE11, r0 mov MESSAGE12, r0 mov MESSAGE13, r0 mov MESSAGE14, r0 mov MESSAGE15, r0 ; Инициализация передающих каналов. ; Первый канал передачи: mov r0, # 08Ch; Режим передачи: movb configMsg1, rl0; 8 байтов, расширенный mov r0, # 00001h; Арбитраж mov r1, # 00000h; (адрес) mov r2, # ArbitrMsgl calla cc_UC, setMask ; Остальные, если нужно до пятнадцатого, исключая предназначенные на прием. ; Инициализация принимающих каналов. ; Первый канал приема: mov r0, # 084h; Режим приема movb configMsg2, rl0; 8 байтов, расширенный mov r0, # 00002h; Арбитраж mov r1, # 00000h; (адрес) mov r2, # ArbitrMsg2 calla cc_UC, setMask mov r0, # 95h movb MESSAGE2, rl0 ; Остальные, если нужно до пятнадцатого, кроме предназначенных на передачу. ; Завершить инициализацию. mov ControlStatus, zeros pop dpp3 ret ; Проверка наличия сообщения, требующего обслуживания. ; R0 - Номер сообщения или ноль, если нет сообщений. ; Использует (портит) R1, R2. TestEmpty: mov r0, # 15; Максимальный номер сообщения - 15 mov r1, # message15; Адрес регистра состояний # 15 nextTstEmpty: exts 0, 1; На нулевом сегменте mov r2, [r1]; прочитать контрольный регистр andb rh2, # 2; Выделить бит NEVVDAT jmpr cc_NZ, EndTstEmpty; Новое сообщение? sub r1, # 10h; Шаг между сообщениями в памяти sub r0, # 1; Все сообщения проверены? jmpr cc_NZ, nextTstEmpty EndTstEmpty: ret ; Прочитать сообщение в память. ; R0 - Номер сообщения 1-15. ; R1, R2 - Адрес буфера в памяти. ; Использует R0, R1, R2. ; Портит R0, R1, R3. ReadMSG: shl r0, # 4; Номер канала - в тетраду адреса add r0, # 0EF06h; Адрес регистра конфигурации exts 0, 1; В нулевом сегменте movb rl3, [r0+]; прочитать контрольный регистр movb rh3, # 0; Выделить счетчик shr r3, # 4; байтов сообщения CykleReadMSG: exts 0, 1; В нулевом сегменте movb rh3, [r0+]; прочитать байт сообщения exts r2, 1; В пользовательском сегменте movb [r1], rh3; сохранить считанный байт сообщения add r1, # 1; Сместить адрес subb rl3, # 1; Уменьшить счетчик jmpr cc_NZ, CykleReadMSG and r0, # 0FFF0h; Указатель на контрольный регистр mov r3, # 055FFh; Сбросить биты сообщения exts 0, 1; и переполнения (сообщение mov [r0], r3; принято) ret ; Передать сообщение в сеть. ; R0 - Номер сообщения 1-15. ; R1, R2 - Адрес буфера в памяти. ; Использует R0, R1, R2. ; Портит R0, R1, R3. WriteMSG: shl r0, # 4; Номер канала - в тетраду адреса add r0, #0EF06h; Адрес регистра конфигурации exts 0, 1; В нулевом сегменте movb rl3, [r0+]; прочитать контрольный регистр movb rh3, # 0; Выделить счетчик shr r3, # 4; байтов сообщения CykleWriteMSG: exts r2, 1; В пользовательском сегменте movb rh3, [r1+]; считать байт сообщения exts 0, 1; В нулевом сегменте movb [r0], rh3; записать байт сообщения add r0, # 1; Сместить адрес subb rl3, # 1; Уменьшить счетчик jmpr cc_NZ, CykleWriteMSG and r0, # 0FFF0h; Указатель на контрольный регистр mov r3, # 06595h; Сбросить биты сообщения exts 0, 1; и переполнения (сообщение mov [r0], r3; принято) ret ; Тестовая программа для проверки функционирования CAN. ; После запуска работает в режиме приема сообщений по каналу 2. ; Принятые сообщения передаются в канал 1, осуществляя, таким образом, режим "зеркала". org 0; Процессор стартует с 0 jmpa cc_UC, Start; Переход на начало программы ; Пропустить область ; векторов прерывания bufferH equ 0; Определение адреса буфера bufferL equ 3000h; для приема и передачи сообщений org 2000h Start: diswdt; Отключить сторожевой таймер einit; Для работы из ПЗУ calla cc_UC, InitCAN; Инициализировать контроллер WaitMSG: calla cc_UC, TestEmpty; Есть сообщения or r0, r0; для приема? jmpr cc_Z, WaitMSG mov r1, # bufferL; Загрузить адрес буфера mov r2, # bufferH; в регистры. calla cc_UC, ReadMSG; Прочитать сообщение. mov r0, # 1; Передать по 1 каналу. mov r1, # bufferL; Загрузить адрес буфера mov r2, # bufferH; в регистры. calla cc_UC, WriteMSG; Передать сообщение. jmpr cc_UC, WaitMSG org 0 end
Приложение Л: Система команд микроконтроллеров 80С16х
Обозначения: Rw - индексные регистры (R0, R1,...R3) Rwi - 2-байтовый регистр GPR (R0, R1,...R15). GPR- Регистры Общего Назначения (РОН). Rb - байтовый регистр GPR (RL0, RH0,..., RL7, RH7) reg - регистры SFR или GPR (в случае байтовых операций с SFR, доступ через "reg" возможен только к младшему байту) mem - прямая адресация в памяти слова или байта [...] - косвенная адресация в памяти слова или байта (любой 2-байтовый GP
|