kursovik (722200), страница 3
Текст из файла (страница 3)
Начало
Порт А –
вход
Порт В –
выход
Запуск
АЦП
Вычисление
разностного
уравнения
Выдача
Результата
На порт В
Рисунок 4.1 – блок-схема работы цифрового фильтра
Опираясь на данную блок схему, начнем более тщательное
р
ассмотрение вопроса. Конфигурация портов и АЦП задается исходя из документации предлагаемой производителем. Данная документация содержит примеры программ для настройки портов и АЦП. Оговорим некоторые аспекты этих программ применительно к нашему курсовому проекту. Контакты порта А зададим входами установкой битов в регистре TRISA. Данное условие необходимо для осуществления аналого-цифровой обработки сигнала. Контакты порта В зададим как выходные сбросом битов в регистре TRISB. Для АЦП выберем канал 0, то есть вывод микропроцессора RA0. В PIC16C711 на одно преобразование АЦП необходим минимальный интервал времени 10Тad, где Тad =1,6 мкс выбирается программно. Также одной из важных частей программы запуска АЦП является организация разрешения прерываний.
После конфигурации портов и запуска АЦП необходимо приступить к выполнению программы вычисления разностного уравнения, описывающего фильтр.
Просчитаем количество переменных, входящих в уравнения. Это количество будет определять необходимое число байт памяти. В нашем случае оно составляет 17. Нетрудно заметить, что коэффициенты разностных уравнений подобраны таким образом, что умножение переменной на них будет делением на 2,4,8…, а эта операция выполняется путем сдвига регистра вправо. Для хранения промежуточных данных сдвиговых операций и операций сложения нам понадобятся дополнительные ячейки памяти в количестве 17. При начальном запуске программы или при сбросе микропроцессорной системы все ячейки памяти необходимо сбросить в нуль.
На обработку данных АЦП требуется, как указывалось ранее, время. Чтобы повысить эффективность и качество системы, необходимо во время просчета АЦП, вместо простоя и ожидания системой результата просчета, произвести вычисления без участия текущего значения отсчета. Вычисления с участием текущего значения отсчета должны производиться через время, равное 10Tad.
Результат вычисления АЦП будет обрабатывать программа прерывания.
Исходя из всех вышеприведенных соображений, составим окончательный алгоритм программы:
Начало 1
Установка
порта А на COUNT-1
ввод
Установка да
порта В на Z=0
вывод
нет
6
0x17W Сброс ADCON1
WCOUNT 0xC1W
WADCON0
0x0CW
Разрешить
прерывание
WFSR АЦП
Разрешить
глобальное
Сброс INDF прерывание
FSR + 1 Пуск АЦП
1 2
2 3
Вычисление
А11UM1с сох- Вычисление
ранением зна- A32YN2YK2=
чения =A32(YN2+YK2)
с сохранением
значения
Вычисление
B11YN1 с сох-
ранением зна- Вычисление
чения B31YL1
Вычисление
В12YN2
ВычислениеYLL
= A31YN1YK1+
Вычисление + A32YN2YK2-
YNN=А11UM1- - B31YL1 с сох-
- B11YN1- ранением зна-
- В12YN2 с сох- чения
ранением зна-
ч
ения
Вычисление YK1 W
A21UM1 с сох-
ранением зна-
ч
ения
Вычисление W YK2
B21YK1
Вычисление YK W
YK=А21UM1-
- B21YK1 с сох-
ранением зна-
чения
W YK1
Вычисление
A31YN1YK1 =
=A31(YN1+YK1) Вычисление
с сохранением A10UM
значения
3 4
4 6 5
Вычисление
YN =A10UM+ UM W
+YNN
с сохранением
значения
W UM1
Вычисление
Y
L=A30(YN+
+
YK)+YLL
с сохранением
значения
ОСТАНОВ
Передача знач-
чения YL на
порт B
YN1 W
W YN2
YN W
W YN1
YL W
5
Рисунок 4.2 - Алгоритм программы проектируемого устройства
5 РАЗРАБОТКА ПРОГРАММЫ НА ЯЗЫКЕ АССЕМБЛЕР
Прежде чем приступить к написанию программы необходимо учесть спецификацию ПЗУ микроконтроллера. Организация ПЗУ изображена на рисунке 5.1
Рисунок 5.1 – Организация ПЗУ PIC16C71
Из рисунка видно, что начало программы пользователя может быть расположено ниже адреса 0004h. Адрес 0000h – вектор сброса, 0004h – вектор прерывания. По этим адресам перед началом программирования, как правило, прописывают безусловный переход на программу пользователя и безусловный переход на программу обработки прерывания соответственно. Так как в случае нашей системы устройство, осуществляющее запрос прерывания, одно, то по адресу 0004h можно прописывать начало программы обработки прерывания.
Также при программировании обязательно нужно учесть спецификацию банков ОЗУ. Структура ОЗУ изображена на
рисунке 5. При обращении к регистрам ОЗУ каждый раз необходимо программно переключаться между банками ОЗУ, в зависимости от того в каком банке находится регистр. Ассемблер, поставляемый производителем, позволяет вначале всем регистрам присвоить вместо адреса определенное имя. Это удобно для составления программы.
Рисунок 5.2 – Организация ОЗУ PIC16C711
Сначала напишем программу обработки прерывания. Занесем программу в таблицу - 1 с адресами ПЗУ и комментариями.
Таблица 5.1
| Адрес | Метка | Мнемонический код | Комментарии | Циклы |
| ORG 0x004 | Директива | |||
| 0004h | MOVWF W_TEMP | Сохранение содержимого W в W_TEMP | 1 | |
| 0005h | MOVF STATUS, 0 | Пересылка содержимого STATUS в W | 1 | |
| 0006h | MOVWF STATUS_TEMP | Сохранение W в STATUS _TEMP | 1 | |
| Продолжение таблицы 5.1 | ||||
| 0007h | BCF STATUS, RP0 | Выбор банка 0 | 1 | |
| 0008h | MOVF ADRES, 0 | Пересылка результата АЦП в W | 1 | |
| 0009h | MOVWF UM | Пересылка W в UM | ||
| 000Ah | MOVF STATUS_TEMP, 0 | Пересылка STATUS_TEMP в W | 1 | |
| 000Bh | MOVWF STATUS | Пересылка W в STATUS | 1 | |
| 000Ch | MOVF W_TEMP, 0 | Пересылка W_TEMP в W | 1 | |
| 000Dh | RETFIE | Возврат прерывания | 2 | |
Программу, реализующую математическую модель фильтра начнем с адреса 000Eh и разместим в таблицу 5, 2.
Таблица 5.2
| Адрес | Метка | Мнемонический код | Комментарии | Циклы |
| ORG 0x00E | Директива | |||
| 000Eh | MOVLW 0xFF | Пересылка 0xFF в аккумулятор | 1 | |
| 000Fh | BSF STATUS, RP0 | Выбор банка 1 | 1 | |
| 0010h | MOVWF TRISA | Порт А – Вход | 1 | |
| 0011h | CLRF TRISB | Порт В – Выход | 1 | |
| 0012h | MOVLW 0x18 | Организация счетчика СOUNT | 1 | |
| 0013h | BCF STATUS, RP0 | Выбор банка 0 | 1 | |
| 0014h | MOVWF COUNT | Организация счетчика | 1 | |
| 0015h | MOVLW 0x0C | Адрес начальной ячейки в ОЗУ | 1 | |
| 0016h | MOVWF FSR | Пересылка адреса начальной ячейки в FSR | 1 | |
| 0017h | M1: | CLRF INDF | Обнуление текущей ячейки памяти | 1 |
| 0018h | INCF FSR, 1 | Адрес + 1 | 1 | |
| 0019h | DECF COUNT | Счетчик – 1 | 1 | |
| 001Ah | BTFSS STATUS, Z | Условный переход по 1 значению флага нулевого результата | 1(2) | |
| 001Bh | GOTO M1 | 2 | ||
| 001Ch | M2: | BSF STATUS,RP0 | Выбор банка 1 | 1 |
| 001Dh | CLRF ADCON1 | RA0-RA3 Входы АЦП | 1 | |
| 001Eh | MOVLW 0xC1 | 1 | ||
| 001Fh | BCF STATUS,RP0 | Выбор банка 0 | 1 | |
| 0020h | MOVWF ADCON0 | АЦП включен, работает канал0 (RA0), частота 32Tosc. | 1 | |
| 0021h | BSF INTCON ADIE | Разрешить прерывание АЦП | 1 | |
| 0022h | BSF INTCON GIE | Разрешить глобальное прерывание | 1 | |
| 0023h | BSF ADCON0, GO | Запустить АЦП | 1 | |
| 0024h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0025h | RRF UM1, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0026h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0027h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0028h | MOVWF A11UM1 | W A11UM1 | 1 | |
| 0029h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 002Ah | RRF YN1, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 002Bh | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 002Ch | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 002Dh | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 002Eh | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| Продолжение таблицы 5.2 | ||||
| 002Fh | BCF STATUS, C | 1 | ||
| 0030h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0031h | MOVWF B11YN1 | W B11YN1 | 1 | |
| 0032h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0033h | RRF YN1, 0 | Циклический сдвиг вправо через триггер переноса | ||
| 0034h | ADDWF W, 0 | W=W+W | 1 | |
| 0035h | ADDWF W, 0 | W=W+W | 1 | |
| 0036h | ADDWF B11YN1 | W=W+ B11YN1 | 1 | |
| 0037h | SUBWF A11UM1, 0 | W= A11UM1- W | 1 | |
| 0038h | MOVWF YNN | W YNN | 1 | |
| 0039h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 003Ah | RRF UM1, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 003Bh | MOVWF A21UM1 | W A21UM1 | 1 | |
| 003Ch | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 003Dh | RRF YK1, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 003Eh | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 003Fh | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0040h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0041h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0042h | SUBWF A21UM1, 0 | W= A21UM1- W | 1 | |
| 0043h | MOVWF YK | W YK | 1 | |
| 0044h | MOVF YN1, 0 | YN1W | 1 | |
| 0045h | ADDWF YK1 | W=W+ YK1 | 1 | |
| 0046h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0047h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0048h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0049h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 004Ah | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 004Bh | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 004Ch | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 004Dh | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 004Eh | MOVWF A31YN1YK1 | W A31YN1YK1 | 1 | |
| 004Fh | MOVF YN2, 0 | YN2W | 1 | |
| 0050h | ADDWF YK2 | W=W+ YK2 | 1 | |
| 0051h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0052h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0053h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0054h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0055h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0056h | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0057h | MOVWF A32YN2YK2 | W A32YN2YK2 | 1 | |
| 0058h | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0059h | RRF YL1, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| Продолжение таблицы 5.2 | ||||
| 005Ah | ADDWF W, 0 | W=W+W | 1 | |
| 005Bh | ADDWF W, 0 | W=W+W | 1 | |
| 005Ch | SUBWF A32YN2YK2, 0 | W= A32YN2YK2- W | 1 | |
| 005Dh | ADDWF A31YN1YK1 | W=W+ A31YN1YK1 | 1 | |
| 005Eh | MOVWF YLL | W YLL | 1 | |
| 005Fh | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 0060h | NOP | Ничего не выполнять | 1 | |
| 0061h | NOP | 1 | ||
| 0062h | NOP | 1 | ||
| 0063h | NOP | 1 | ||
| 0064h | NOP | 1 | ||
| 0065h | NOP | 1 | ||
| 0066h | NOP | 1 | ||
| 0067h | NOP | 1 | ||
| 0068h | NOP | 1 | ||
| 0069h | NOP | 1 | ||
| 006Ah | NOP | 1 | ||
| 006Bh | NOP | 1 | ||
| 006Ch | NOP | 1 | ||
| 006Dh | NOP | 1 | ||
| 006Eh | NOP | 1 | ||
| 006Fh | NOP | 1 | ||
| 0070h | NOP | 1 | ||
| 0071h | NOP | 1 | ||
| 0072h | NOP | 1 | ||
| 0073h | NOP | 1 | ||
| 0074h | MOVF YK1, 0 | YK1W | 1 | |
| 0075h | MOVWF YK2 | W YK2 | 1 | |
| 0076h | MOVF YK, 0 | YK W | 1 | |
| 0077h | MOVWF YK1 | W YK1 | 1 | |
| 0078h | RRF UM, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 0079h | ADDWF YNN | W=W+ YNN | 1 | |
| 007Ah | MOVWF YN | W YN | 1 | |
| 007Bh | ADDWF YK | W=W+ YK | 1 | |
| 007Ch | BCF STATUS, C | Очистка триггера переноса | 1 | |
| 007Dh | RRF W, 0 | Циклический сдвиг вправо через триггер переноса | 1 | |
| 007Eh | ADDWF W, 0 | W=W+W | 1 | |
| 007Fh | ADDWF YLL | W=W+ YLL | 1 | |
| 0080h | MOVWF YL | W YL | 1 | |
| 0081h | MOVWF PORTB | W PORTB | 1 | |
| 0082h | MOVF YN1, 0 | YN1W | 1 | |
| 0083h | MOVWF YN2 | W YN2 | 1 | |
| 0084h | MOVF YN, 0 | YN W | 1 | |
| 0085h | MOVWF YN1 | W YN1 | 1 | |
| 0086h | MOVF YL, 0 | YL W | 1 | |
| 0087h | MOVWF YL1 | W YL1 | 1 | |
| 0088h | MOVF UM, 0 | UM W | 1 | |
| 0089h | MOVWF UM1 | W UM1 | 1 | |
| 008Ah | GOTO M2 | Безусловный переход на метку | 1 | |
| END | ||||
| Всего вместе с программой обработки прерывания | 283 | |||
Время выполнения программы 56 мкс.















