Разработка программы на языке ассемблер

Прежде чем приступить к написанию программы необходимо учесть спецификацию ПЗУ микроконтроллера. Организация ПЗУ изображена на рисунке 5.1

разработка программы на языке ассемблер - student2.ru

Рисунок 5.1 – Организация ПЗУ PIC16C71

Из рисунка видно, что начало программы пользователя может быть расположено ниже адреса 0004h. Адрес 0000h – вектор сброса, 0004h – вектор прерывания. По этим адресам перед началом программирования, как правило, прописывают безусловный переход на программу пользователя и безусловный переход на программу обработки прерывания соответственно. Так как в случае нашей системы устройство, осуществляющее запрос прерывания, одно, то по адресу 0004h можно прописывать начало программы обработки прерывания.

Также при программировании обязательно нужно учесть спецификацию банков ОЗУ. Структура ОЗУ изображена на

рисунке 5. При обращении к регистрам ОЗУ каждый раз необходимо программно переключаться между банками ОЗУ, в зависимости от того в каком банке находится регистр. Ассемблер, поставляемый производителем, позволяет вначале всем регистрам присвоить вместо адреса определенное имя. Это удобно для составления программы.

разработка программы на языке ассемблер - student2.ru

Рисунок 5.2 – Организация ОЗУ PIC16C711

Сначала напишем программу обработки прерывания. Занесем программу в таблицу - 1 с адресами ПЗУ и комментариями.

Таблица 5.1

Адрес Метка Мнемонический код Комментарии Циклы
    ORG 0x004 Директива  
0004h   MOVWF W_TEMP Сохранение содержимого W в W_TEMP
0005h   MOVF STATUS, 0 Пересылка содержимого STATUS в W
0006h   MOVWF STATUS_TEMP Сохранение W в STATUS _TEMP
Продолжение таблицы 5.1
0007h   BCF STATUS, RP0 Выбор банка 0
0008h   MOVF ADRES, 0 Пересылка результата АЦП в W
0009h   MOVWF UM Пересылка W в UM  
000Ah   MOVF STATUS_TEMP, 0 Пересылка STATUS_TEMP в W
000Bh   MOVWF STATUS Пересылка W в STATUS
000Ch   MOVF W_TEMP, 0 Пересылка W_TEMP в W
000Dh   RETFIE Возврат прерывания

Программу, реализующую математическую модель фильтра начнем с адреса 000Eh и разместим в таблицу 5, 2.

Таблица 5.2

Адрес Метка Мнемонический код Комментарии Циклы
    ORG 0x00E Директива  
000Eh   MOVLW 0xFF Пересылка 0xFF в аккумулятор
000Fh   BSF STATUS, RP0 Выбор банка 1
0010h   MOVWF TRISA Порт А – Вход
0011h   CLRF TRISB Порт В – Выход
0012h   MOVLW 0x18 Организация счетчика СOUNT
0013h   BCF STATUS, RP0 Выбор банка 0
0014h   MOVWF COUNT Организация счетчика
0015h   MOVLW 0x0C Адрес начальной ячейки в ОЗУ
0016h   MOVWF FSR Пересылка адреса начальной ячейки в FSR
0017h M1: CLRF INDF Обнуление текущей ячейки памяти
0018h   INCF FSR, 1 Адрес + 1
0019h   DECF COUNT Счетчик – 1
001Ah   BTFSS STATUS, Z Условный переход по 1 значению флага нулевого результата 1(2)
001Bh   GOTO M1  
001Ch M2: BSF STATUS,RP0 Выбор банка 1
001Dh   CLRF ADCON1 RA0-RA3 Входы АЦП
001Eh   MOVLW 0xC1  
001Fh   BCF STATUS,RP0 Выбор банка 0
0020h   MOVWF ADCON0 АЦП включен, работает канал0 (RA0), частота 32Tosc.
0021h   BSF INTCON ADIE Разрешить прерывание АЦП
0022h   BSF INTCON GIE Разрешить глобальное прерывание
0023h   BSF ADCON0, GO Запустить АЦП
0024h   BCF STATUS, C Очистка триггера переноса
0025h   RRF UM1, 0 Циклический сдвиг вправо через триггер переноса
0026h   BCF STATUS, C Очистка триггера переноса
0027h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0028h   MOVWF A11UM1 W® A11UM1
0029h   BCF STATUS, C Очистка триггера переноса
002Ah   RRF YN1, 0 Циклический сдвиг вправо через триггер переноса
002Bh   BCF STATUS, C Очистка триггера переноса
002Ch   RRF W, 0 Циклический сдвиг вправо через триггер переноса
002Dh   BCF STATUS, C Очистка триггера переноса
002Eh   RRF W, 0 Циклический сдвиг вправо через триггер переноса
Продолжение таблицы 5.2
002Fh   BCF STATUS, C  
0030h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0031h   MOVWF B11YN1 W® B11YN1
0032h   BCF STATUS, C Очистка триггера переноса
0033h   RRF YN1, 0 Циклический сдвиг вправо через триггер переноса  
0034h   ADDWF W, 0 W=W+W
0035h   ADDWF W, 0 W=W+W
0036h   ADDWF B11YN1 W=W+ B11YN1
0037h   SUBWF A11UM1, 0 W= A11UM1- W
0038h   MOVWF YNN W® YNN
0039h   BCF STATUS, C Очистка триггера переноса
003Ah   RRF UM1, 0 Циклический сдвиг вправо через триггер переноса
003Bh   MOVWF A21UM1 W® A21UM1
003Ch   BCF STATUS, C Очистка триггера переноса
003Dh   RRF YK1, 0 Циклический сдвиг вправо через триггер переноса
003Eh   BCF STATUS, C Очистка триггера переноса
003Fh   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0040h   BCF STATUS, C Очистка триггера переноса
0041h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0042h   SUBWF A21UM1, 0 W= A21UM1- W
0043h   MOVWF YK W® YK
0044h   MOVF YN1, 0 YN1®W
0045h   ADDWF YK1 W=W+ YK1
0046h   BCF STATUS, C Очистка триггера переноса
0047h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0048h   BCF STATUS, C Очистка триггера переноса
0049h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
004Ah   BCF STATUS, C Очистка триггера переноса
004Bh   RRF W, 0 Циклический сдвиг вправо через триггер переноса
004Ch   BCF STATUS, C Очистка триггера переноса
004Dh   RRF W, 0 Циклический сдвиг вправо через триггер переноса
004Eh   MOVWF A31YN1YK1 W® A31YN1YK1
004Fh   MOVF YN2, 0 YN2®W
0050h   ADDWF YK2 W=W+ YK2
0051h   BCF STATUS, C Очистка триггера переноса
0052h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0053h   BCF STATUS, C Очистка триггера переноса
0054h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0055h   BCF STATUS, C Очистка триггера переноса
0056h   RRF W, 0 Циклический сдвиг вправо через триггер переноса
0057h   MOVWF A32YN2YK2 W® A32YN2YK2
0058h   BCF STATUS, C Очистка триггера переноса
0059h   RRF YL1, 0 Циклический сдвиг вправо через триггер переноса
Продолжение таблицы 5.2
005Ah   ADDWF W, 0 W=W+W
005Bh   ADDWF W, 0 W=W+W
005Ch   SUBWF A32YN2YK2, 0 W= A32YN2YK2- W
005Dh   ADDWF A31YN1YK1 W=W+ A31YN1YK1
005Eh   MOVWF YLL W® YLL
005Fh   BCF STATUS, C Очистка триггера переноса
0060h   NOP Ничего не выполнять
0061h   NOP  
0062h   NOP  
0063h   NOP  
0064h   NOP  
0065h   NOP  
0066h   NOP  
0067h   NOP  
0068h   NOP  
0069h   NOP  
006Ah   NOP  
006Bh   NOP  
006Ch   NOP  
006Dh   NOP  
006Eh   NOP  
006Fh   NOP  
0070h   NOP  
0071h   NOP  
0072h   NOP  
0073h   NOP  
0074h   MOVF YK1, 0 YK1®W
0075h   MOVWF YK2 W® YK2
0076h   MOVF YK, 0 YK ®W
0077h   MOVWF YK1 W® YK1
0078h   RRF UM, 0 Циклический сдвиг вправо через триггер переноса
0079h   ADDWF YNN W=W+ YNN
007Ah   MOVWF YN W® YN
007Bh   ADDWF YK W=W+ YK
007Ch   BCF STATUS, C Очистка триггера переноса
007Dh   RRF W, 0 Циклический сдвиг вправо через триггер переноса
007Eh   ADDWF W, 0 W=W+W
007Fh   ADDWF YLL W=W+ YLL
0080h   MOVWF YL W® YL
0081h   MOVWF PORTB W® PORTB
0082h   MOVF YN1, 0 YN1®W
0083h   MOVWF YN2 W® YN2
0084h   MOVF YN, 0 YN ®W
0085h   MOVWF YN1 W® YN1
0086h   MOVF YL, 0 YL ®W
0087h   MOVWF YL1 W® YL1
0088h   MOVF UM, 0 UM ®W
0089h   MOVWF UM1 W® UM1
008Ah   GOTO M2 Безусловный переход на метку
  END    
Всего вместе с программой обработки прерывания

Время выполнения программы 56 мкс.

Операции NOP предназначены для синхронизации работы АЦП с программой. Также для этой цели было добавлено 4 команды перед операциями над текущим значением отсчета. В составленном алгоритме данные коррекции небыли предусмотрены. Время выполнения программы, реализующей цифровой фильтр, равно 49 мкс. Интервал дискретизации сигнала равен 24,6 мкс, соответственно частота дискретизации равна 41000Гц. В программе используются два перехода: один для обнуления ОЗУ, другой – для возврата программы на место запуска АЦП. При использовании более современных PIC процессоров возможно исключение операций NOP.

Наши рекомендации