Реферат по предмету "Информатика"


Устройство ультразвукового измерения дальности

--PAGE_BREAK--
Описание программы
Для удобства программа, приведенная в приложении, разбита на отдельные подпрограммы, которые взаимодействуют друг с другом согласно приведенной ниже обобщенной блок схеме программы.
Обобщенная блок-схема
 SHAPE  \* MERGEFORMAT
Рис. 8. Обобщенная блок-схема.
Более подробно рассмотрим каждый блок приведенной на рис. 8. обобщенной блок схемы.
Список директив, файл, слово CPU
Данный блок соответствует приведенной ниже части программы.
;==============================================================
;                           программа для ультразвукового дальномера
;==============================================================
                                                       ; список директив
list              P=16C84                      ; директива определяющая тип процессора
#include                  ; файл, описывающий специфические переменные, соответствующие процессору
_config       b'00000000000001'     ; слово конфигурации CPU
;==============================================================
С помощью директивы list указываем ассемблеру тип процессора. Подключаем соответствующий файл описания. Затем следует слово конфигурации CPU, которое при программировании микроконтроллера будет размещено по адресу расположенному за пределами пользовательской памяти программ. Слово конфигурации CPU содержит 14 бит. Биты 13-8 CP – защита программного кода (1=защита отключена, 0=защита установлена). Выбираем 0. Бит 7 DP – защита памяти данных EEPROM (1=защита отключена, 0=защита установлена). Выбираем 0. Биты 6-4 CP – защита программного кода (1=защита отключена, 0=защита установлена). Выбираем 0. Бит 3 PWRTE – разрешение задержки при включении питания (1=задержка отключена, 0=задержка установлена). Выбираем 0. Бит 2 WDTE – разрешение включения сторожевого таймера (1=сторожевой таймер включен, 0=сторожевой таймер отключен). Выбираем 0. Биты 1-0 FOSC1-FOSC0 – выбор режима тактового генератора (11=RC-генератор, 10=HS-резонатор, 01=XT-резонатор, 00=LP-резонатор). Выбираем 01 т.к. используем стандартный керамический резонатор 4МГц.
Описание переменных
Данный блок соответствует приведенной ниже части программы.
;==============================================================
; описание используемых переменных ;(назначение адресов ячеек для хранения переменных)
NUMIMP   equ    0x0C; рабочая переменная для подсчета числа импульсов
TIMER1     equ    0x0D; рабочая переменная для подсчета времени 1
TIMER2     equ    0x0E; рабочая переменная для подсчета времени 2
LAPSE       equ    0x0F; рабочая переменная для подсчета погрешности перевода времени
DIGIT1      equ    0x10; рабочая переменная индикатора дециметров
DIGIT2      equ    0x11; рабочая переменная индикатора метров
DIGIT3      equ    0x12; рабочая переменная индикатора декаметров
;==============================================================
В этом блоке описывается в каких ячейках ОЗУ (регистрах общего применения) будут хранится значения наших переменных. Назначение переменных понятно из комментариев приведенной выше части листинга программы.

Исполняемая программа
Данный блок соответствует приведенной ниже части программы.
;==============================================================
                                     ; исполняемая программа
         org    0х000                 ; вектор сброса процессора, начальный адрес
         clrf    PORTA     ; очистили выходные защелки порта А
         clrf    PORTB     ; и порта В
         clrf    TMR0       ; очистка таймера TMR0
         bsf     STATUS, RP0    ; включили банк 1
         movlw        b’00011110’      ; настроили на вывод линию RA0,
         movwf        PORTA     ; остальные линии порта A на ввод
         movlw        b’00000000’      ; настроили на вывод все линии порта B
         movwf        PORTB      ;RB0…RB7
         bcf     OPTION_REG, 7         ; включили подтягивающие резисторы
         bcf     OPTION_REG, 5         ; включили режим таймера для TMR0
         bcf     STATUS, RP0    ; включили банк 0
;==============================================================
Указываем адрес начала программ, вектор сброса процессора. Обнуляем значения в выходных защелках обеих портов. Обнуляем значение таймера. Затем установив в 1 бит RP0 регистра STATUS, мы получаем доступ к регистровому банку 1. Теперь обращаясь к регистрам PORTA и PORTB, мы обращаемся не к выходным защелкам, а к регистрам состояния этих портов, и настраиваем часть линий на ввод, а часть линий на вывод, что соответствует схеме приведенной в приложении. Используя бит 7 RBPU регистра OPTION_REG включаем встроенную нагрузку порта B, для чего устанавливаем бит в 0. С помощью бита 5 T0CS выбираем источник тактирования для таймера TMR0. Для использования внутренней тактовой частоты CLKOUT, устанавливаем в 0 этот бит. В конце установив в 0 бит RP0 регистра STATUS, мы получаем доступ к регистровому банку 0.
Основная программа main
Данный блок соответствует приведенной ниже части программы.
;==============================================================
main ; основная программа
call    initialization                 ; вызываем подпрограмму инициализации
main1                  call    indication  ; вызываем подпрограмму индикации
goto  divssing     ; вызываем подпрограмму обработки нажатия кнопки     
main2                  call    transfer      ; вызываем подпрограмму передачи импульсов
main3                  goto  waiting      ; вызываем подпрограмму ожидания отраженного сигнала
main4                  goto  reception   ; вызываем подпрограмму приема отраженного сигнала
main5                  call    calculation ; вызываем подпрограмму вычисления расстояния
;==============================================================
В данной части используются всего два оператора перехода: оператор вызова подпрограммы call и оператор безусловного перехода goto. Для наглядности приведем блок-схему основной программы main, в которую добавлены условия и порядок взаимодействия рассматриваемых далее подпрограмм.
Блок-схема приведена на рис. 9.
 SHAPE  \* MERGEFORMAT
Рис. 9. Блок-схема основной программы main.
Подпрограмма инициализации initialization
Данный блок соответствует приведенной ниже части программы.
;==============================================================
initialization        ; подпрограмма инициализации и начальных условий
обнуляем значения используемых переменных
clrf    PORTA     ; очистили выходные защелки порта A
clrf    NUMIMP  ; обнуляем значение NUMIMP
clrf    TIMER1    ; обнуляем значение TIMER1
clrf    NUMCH   ; обнуляем значение NUMCH
clrf    TIMER2    ; обнуляем значение TIMER2
clrf    LAPSE      ; обнуляем значение LAPSE
clrf    DIGIT1     ; обнуляем значение DIGIT1
clrf    DIGIT2     ; обнуляем значение DIGIT2
clrf    DIGIT3     ; обнуляем значение DIGIT3
; устанавливаем значения используемых переменных
movlw        d'5'   ; помещаем значение «5» для NUMIMP в аккумулятор
movwf        NUMIMP  ; помещаем значение из аккумулятора в NUMIMP
movlw        d'100'                  ; помещаем значение «100» для TIMER1 в аккумулятор
movwf        TIMER1    ; помещаем значение из аккумулятора в TIMER1
movlw        d'100'        ; помещаем значение «100» для TIMER2 в аккумулятор
movwf        TIMER2             ; помещаем значение из аккумулятора в TIMER2
movlw        d'57' ; помещаем значение «57» для LAPSE в аккумулятор
movwf        LAPSE      ; помещаем значение из аккумулятора в LAPSE
return                 ; возврат из подпрограммы
;==============================================================
Здесь мы обнуляем используемые переменные, и устанавливаем для них необходимые значения. Количество передаваемых импульсов NUMIMP в сигнале принимаем равным 5 (согласовано с преподавателем). И т.д.
Подпрограмма индикации indication
Данный блок соответствует приведенной ниже части программы.
;==============================================================
indication  ; подпрограмма индикации измеренного расстояния
;-----------------------------------------------------устанавливаем биты подключения индикаторов
bsf     DIGIT1, 6 ; устанавливаем бит 6 переменной DIGIT1 в 1
bsf     DIGIT2, 7 ; устанавливаем бит 7 (точка) переменной DIGIT2 в 1
bsf     DIGIT2, 5 ; устанавливаем бит 5 переменной DIGIT2 в 1
bsf     DIGIT3, 4 ; устанавливаем бит 4 переменной DIGIT3 в 1
;-----------------------------------------------------выводим значение DIGIT1 на индикатор
movf DIGIT1, 0 ; помещаем значение переменной DIGIT1 в аккумулятор
movwf        PORTB     ; выводим значение в порт В

устанавливаем задержку отображения
clrf    TMR0       ; обнуляем таймер и
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по его переполнению
indc1 btfss  INTCON, TOIF  ; проверяем флаг прерывания по переполнению таймера
goto  indc1; если флаг равен 0 (счетчик не переполнен)-выполняем проверку
; если флаг равен 1 (счетчик переполнен) — переходим к следующему
; индикатору
;-----------------------------------------------------выводим значение DIGIT2 на индикатор
movf DIGIT2, 0 ; помещаем значение переменной DIGIT1 в аккумулятор
movwf        PORTB     ; выводим значение в порт В
устанавливаем задержку отображения
clrf    TMR0       ; обнуляем таймер и
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по его переполнению
indc2 btfss  INTCON, TOIF  ; проверяем флаг прерывания по переполнению таймера
goto  indc2; если флаг равен 0 (счетчик не переполнен)-выполняем проверку
если флаг равен 1 (счетчик переполнен) — переходим к следующему индикатору
;-----------------------------------------------------выводим значение DIGIT3 на индикатор
movf DIGIT3, 0 ; помещаем значение переменной DIGIT3 в аккумулятор
movwf        PORTB     ; выводим значение в порт В
; устанавливаем задержку отображения
clrf    TMR0       ; обнуляем таймер и
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по его переполнению
indc3 btfss  INTCON, TOIF  ; проверяем флаг прерывания по переполнению таймера
goto  indc3; если флаг равен 0 (счетчик не переполнен)-выполняем проверку
; если флаг равен 1 (счетчик переполнен)-
;---------------------------------------------------------------------------------------------------------
return                  ; возврат из подпрограммы
;==============================================================
В первой части подпрограммы indication мы устанавливаем «биты точки и питания» индикаторов согласно схеме. В переменной DIGIT1 будет храниться значение дециметров от 0 до 9 т.к. используемые в схеме индикаторы являются семи сегментными с дополнительным выводом для десятичного разделителя – точки, в переменной DIGIT2 – значение метров, в переменной DIGIT3 – значение декаметров соответственно. Таким образом согласно схеме для отображения цифр на индикаторах через дешифратор используется всего четыре линии порта B: RB0, RB1, RB2, RB3 для передачи битов 0, 1, 2 и 3 соответственно. Вычисленные отображаемые значения будут храниться в переменных DIGIT1…3 поразрядно, для этого используется первые четыре бита каждой переменной. Линии RB4, RB5 и RB6 порта В мы используем для поочередной подачи питания на индикаторы. Линия RB4 на индикатор декаметров (отображение значения DIGIT3), RB5 на индикатор метров (отображение значения DIGIT2), RB6 на индикатор дециметров (отображение значения DIGIT1). Для этого мы используем следующие биты переменных: бит 6 — DIGIT1, бит 5 — DIGIT2 и бит 4 — DIGIT3 согласно схеме. Линия RB7 порта В используется для подачи сигнала на десятичную точку индикатора метров (переменная DIGIT2). Таким образом используется весь порт В и мы можем, заранее установив биты в переменных посылать их на порт В поочередно, соответственно поочередно подключая индикаторы. Для наглядности ниже приведен рисунок 10.
 SHAPE  \* MERGEFORMAT     продолжение
--PAGE_BREAK--
Рис. 10. Схема индикации.
Далее выводим значение DIGIT1 на порт В. Организуем задержку отображения на индикаторе при помощи таймера TMR0 на 256 мкс. Затем эту же процедуру производим для DIGIT2 и DIGIT3 отображая их значения на индикаторах.
Подпрограмма нажатия кнопки divssing
Данный блок соответствует приведенной ниже части программы.
;==============================================================
divssing     ; подпрограмма обработки нажатия кнопки
btfss  PORTA, 2 ; проверяем линию RA2 порта А (кнопку s2),
goto  main1                 ; если не нажата возвращаемся в программу (на indication)
goto  main2                 ; если нажата-возврат из подпрограммы
;==============================================================
При выполнении этой подпрограммы происходит тестирование присутствия сигнала (+5В) на линии RA2 порта A. Если на линию поступает напряжение (кнопка нажата) – выполняется команда перехода в основную программу на соответствующую метку (main2). В противном случае (кнопка не нажата) переход осуществляется на другую метку основной программы (main2).
Подпрограмма передачи transfer
Данный блок соответствует приведенной ниже части программы.
;==============================================================
transfer      ; подпрограмма передачи импульсов
;---------------------------------------------------------------------------------------------------------
movlw        d'5'   ; помещаем значение «5» для NUMIMP в аккумулятор
movwf        NUMIMP  ; помещаем значение из аккумулятора в NUMIMP
;-----------------------------------------------------передача сигнала
tran1 bsf     PORTA, 0 ; устанавливаем в 1 линию RA0 порта А
movlw        d'249'                  ; помещаем значение «249» для таймера в аккумулятор
movwf        TMR0       ; помещаем значение из аккумулятора в таймер
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по переполнению таймера
tran2 btfss  INTCON, TOIF  ; проверяем флаг прерывания по переполнению таймера
goto  tran2; если флаг равен 0 (счетчик не переполнен)-выполняем проверку
; если флаг равен 1 (счетчик переполнен)-
;-----------------------------------------------------задержка сигнала
bcf     PORTA, 0 ; устанавливаем в 0 линию RA0 порта А
movlw        d'251'                  ; помещаем значение «251» для таймера в аккумулятор
movwf        TMR0       ; помещаем значение из аккумулятора в таймер
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по переполнению таймера
tran3 btfss  INTCON, TOIF  ; проверяем флаг прерывания по переполнению таймера
goto  tran3; если флаг равен 0 (счетчик не переполнен)-выполняем проверку
; если флаг равен 1 (счетчик переполнен)-
;-----------------------------------------------------считаем импульсы
decfsz         NUMIMP, 1       ; уменьшаем зачение NUMIMP на «1» если NUMIMP не равен «0»
;(передано
goto  tran1; переходим в начало подпрограммы на tran1 если NUMIMP равен «0»
;-----------------------------------------------------(передано 5 импульсов)-
movlw        d'3'   ; помещаем значение «3» для NUMIMP в аккумулятор
movwf        NUMIMP  ; помещаем значение из аккумулятора в NUMIMP
;---------------------------------------------------------------------------------------------------------
return                  ; возврат из подпрограммы
;==============================================================
Данная подпрограмма выводит на линию RA0 порта А микроконтроллера 5 импульсов частотой 40 кГц. Учитывая, что мы не подключаем предделитель для таймера-счетчика TMR0 и в схеме используется керамический резонатор частотой 4 МГц имеем тактовую частоту микроконтроллера равную 1 МГц, т.е. одна команда выполняется за 1 мкс. Следовательно один импульс частотой 40 кГц имеет продолжительность 1/40000=25 мкс. Т.е. мы должны сформировать один импульс за 25 мкс. Блок-схема данной подпрограммы представлена на рис. 11. Значения для таймера подобраны таким образом, чтобы сформировать импульс на линии продолжительностью около 25 мкс. В конце подпрограммы устанавливается новое значение для переменной NUMIMP, т.к. оно потребуется для работы другой подпрограммы.
 SHAPE  \* MERGEFORMAT
Рис. 11. Блок-схема подпрограммы transfer.
Подпрограмма ожидания waiting
Данный блок соответствует приведенной ниже части программы.
;==============================================================
waiting                                  ; подпрограмма ожидания отраженного сигнала
;-----------------------------------------------------задержка начала приема сигнала
movlw        d'151'                  ; помещаем значение «151» для таймера в аккумулятор
movwf        TMR0       ; помещаем значение из аккумулятора в таймер
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по переполнению таймера
wait1 btfss  INTCON, TOIF  ; проверяем флаг прерывания по переполнению таймера
goto  wait1; если флаг равен 0 (счетчик не переполнен)-выполняем проверку
; если флаг равен 1 (счетчик переполнен)-
;-----------------------------------------------------начинаем счет времени
ожидание приема (по 100 мкс)
wait3 movlw        d'161'        ; помещаем значение «161» для таймера в аккумулятор
movwf        TMR0       ; помещаем значение из аккумулятора в таймер
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по переполнению таймера
wait2 btfsc  PORTA, 1 ; проверяем наличие сигнала на линии RA1 порта А
goto  wait4; если сигнал есть-переходим на метку wait4
если сигнала нет-продолжаем счет времени
btfss  INTCON, TOIF  ; проверяем флаг прерывания по переполнению таймера
goto  wait2; если флаг равен 0 (счетчик не
;-----------------------------------------------------переполнен)-выполняем проверку
decfsz         TIMER1, 1; если флаг равен 1 (счетчик переполнен)-уменьшаем TIMER1 на 1
goto  wait3; если TIMER1 не равен «0»
;-----------------------------------------------------продолжаем ожидание если TIMER1 равен «0»-
movlw        d'100'        ; помещаем значение «100» для TIMER1 в аккумулятор
movwf        TIMER1    ; помещаем значение из аккумулятора в TIMER1
decfsz         TIMER2, 1; уменьшаем значение TIMER2 на 1
goto  wait3; если TIMER2 не равен «0»
;-----------------------------------------------------продолжаем ожидание
; если TIMER2 равен «0» (сигнал уже не вернется)-заполняем
; значения DIGIT1..3
movlw        d'9'   ; помещаем значение «9» для переменной DIGIT1 в аккумулятор
movwf        DIGIT1     ; помещаем значение из аккумулятора в DIGIT1
movlw        d'9'   ; помещаем значение «9» для переменной ;DIGIT2 в аккумулятор
movwf        DIGIT2     ; помещаем значение из аккумулятора в DIGIT2
movlw        d'9'   ; помещаем значение «9» для переменной ;DIGIT3 в аккумулятор
movwf        DIGIT3     ; помещаем значение из аккумулятора в DIGIT3
;---------------------------------------------------------------------------------------------------------
goto  main1        ; возврат из подпрограммы (сигнала нет)
wait4 goto  main4                 ; возврат из подпрограммы (сигнал есть)
;==============================================================
 SHAPE  \* MERGEFORMAT
Рис. 12. Блок-схема подпрограммы waiting.
В начальной части подпрограммы производится небольшая задержка начала счета времени ожидания для того, чтобы произошло затухание помех вызванных излучением сигнала в предыдущей подпрограмме. Затем запускается таймер на 100 мкс. Т.к. мы будем считать промежутки времени по 100 мкс. Блок-схема подпрограммы представлена на рис. 12. Таким образом максимальный период ожидания составит 100*100*100=1000000 мкс, что составляет 1с. Принимая скорость распространения звука равной 331,4 м/с – это более чем достаточно, т.к. по условию задания максимальная измеряемая дальность устройства составит 99,9 метра.
Подпрограмма приема reception
Данный блок соответствует приведенной ниже части программы.
;==============================================================
reception   ; подпрограмма приема отраженного сигнала
;---------------------------------------------------------------------------------------------------------
ожидание окончания сигнала
recp1 btfsс  PORTA, 1 ; проверяем наличие сигнала на линии RA1 порта А
goto  recp1; если сигнала есть-продолжаем ожидание
;-----------------------------------------------------если сигнала нет-начинаем проверку
recp6 movlw        d'251'                  ; помещаем значение «251» для таймера в аккумулятор
movwf        TMR0       ; помещаем значение из аккумулятора в таймер
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по переполнению таймера
recp1 btfss  INTCON, TOIF  ; проверяем флаг переполнения таймера если таймер не переполнен-
btfsc  PORTA, 1 ; проверяем отсутствие сигнала на линии RA1 порта А
; если таймер переполнен или есть
goto  recp2; сигнал-идем на метку recp2 если таймер не переполнен и нет
goto  recp1; сигнала-идем на метку recp1
;-----------------------------------------------------проверяем флаг переполнения таймера
recp2 btfss  INTCON, TOIF  ; если таймер не переполнен-
goto  recp3         ; сигнал не наш-идем на метку recp3
;---------------------------------------------------------------------------------------------------------    
movlw        d'252'        ; помещаем значение «252» для таймера в аккумулятор
movwf        TMR0       ; помещаем значение из аккумулятора в таймер
bcf     INTCON, TOIF  ; устанавливаем в 0 флаг прерывания по переполнению таймера
recp4 btfss  INTCON, TOIF  ; проверяем флаг переполнения таймера если таймер не переполнен-
btfss  PORTA, 1 ; проверяем наличие сигнала на линии RA1 порта А если таймер переполнен или нет
goto  recp5; сигнала-идем на метку recp5 если таймер не переполнен и есть
    продолжение
--PAGE_BREAK--goto  recp4; сигнал-идем на метку recp4
;-----------------------------------------------------проверяем флаг переполнения таймера
recp5 btfss  INTCON, TOIF  ; если таймер не переполнен-
goto  recp3; сигнал не наш-идем на метку recp3
;---------------------------------------------------------------------------------------------------------    
decfsz         NUMIMP, 1       ; уменьшаем значение NUMIMP на «1»
goto  recp6; если NUMIMP не равен «0»-продолжаем проверку
goto  main5        ; если NUMIMP равен «0»-возврат из подпрограммы
recp3 goto  main3                 ; продолжение ожидания сигнала
;==============================================================
Блок-схема данной подпрограммы представлена на рис. 13. Т.к. переход в подпрограмму осуществляется при наличии сигнала на линии RA1 порта А микроконтроллера, то сначала дожидаемся окончания сигнала. Затем производим тестирование отсутствия сигнала на протяжении определенного времени, если до истечения данного промежутка времени сигнал появился, то делаем вывод, что принят не наш сигнал и выходим из подпрограммы и продолжаем ожидание правильного сигнала в подпрограмме waiting. После этого производим тестирование наличия сигнала на протяжении определенного времени, если до истечения данного промежутка времени сигнал пропал, то делаем вывод, что принят не наш сигнал и выходим из подпрограммы и продолжаем ожидание правильного сигнала в подпрограмме waiting. Если же в течение определенного времени сигнала не было, а затем в течении определенного времени сигнал был, то делаем вывод, что был успешно произведен прием одного импульса нашего сигнала, уменьшаем счетчик принятых импульсов на 1 и возвращаемся на метку recp6 рассматриваемой подпрограммы и производим все действия по приему импульса сигнала еще раз. Прием импульсов проводится до тех пор пока счетчик импульсов NUMIMP не станет равен нулю, и мы можем считать, что приняли три импульса нашего сигнала. После этого переходим в подпрограмму calculation. Работа подпрограммы более понятна из приведенной блок-схемы.
 SHAPE  \* MERGEFORMAT
Рис. 13. Блок-схема подпрограммы reception.
Подпрограмма вычисления calculation
Данный блок соответствует приведенной ниже части программы.
;==============================================================
calculation                             ; подпрограмма вычисления расстояния инвертируем значения TIMER1 и
;-----------------------------------------------------TIMER2
movf TIMER1,0 ; записываем значение переменной TIMER1 в аккумулятор
clrf    TIMER1    ; обнуляем значение TIMER1
sublw         d'100'                  ; из числа 100 вычитаем значение аккумулятора
movwf        TIMER1    ; записываем полученное значение в переменную TIMER1
movf TIMER2,0 ; записываем значение переменной TIMER2 в аккумулятор
clrf    TIMER2    ; обнуляем значение TIMER2
sublw         d'100'        ; из числа 100 вычитаем значение аккумулятора
movwf        TIMER2    ; записываем полученное значение в переменную TIMER2
;-----------------------------------------------------устанавливаем значения для LAPSE и DIGIT1..3
clrf    LAPSE      ; обнуляем значение LAPSE
movlw        d'57'  записываем в аккумулятор значение «57»
movwf        LAPSE      ; записываем значение аккумулятора в переменную LAPSE
clrf    DIGIT1     ; обнуляем значение DIGIT1
clrf    DIGIT2     ; обнуляем значение DIGIT2
clrf    DIGIT3     ; обнуляем значение DIGIT3
;-----------------------------------------------------записываем в аккумулятор вычитаемое
calc3           movlw        d'6'                       ;«6»
subwf                   TIMER1, 1; вычитаем из переменной TIMER1 значение аккумулятора
проверяем флаги регистра STATUS
btfss  STATUS, C        ; флаг Z-нулевого результата
btfsc  STATUS, Z        ; и флаг C-переноса
goto  calc4; если флаги Z и C не равны 0
goto  calc1; если Z=0 и C=0 значит результат отрицательный
;-----------------------------------------------------меняем значения DIGIT1…3 и LAPSE
calc4 incf    DIGIT1, 1 ; увеличиваем переменную DIGIT1 на «1»
movlw        d'10' ; записываем в аккумулятор значение «10»
subwf                   DIGIT1, 0 ; вычитаем значение аккумулятора из переменной DIGIT1
btfss  STATUS, Z                  ; проверяем результат на «0»
goto  calc2 если результат не «0» идем на метку
;-----------------------------------------------------calc2
decf   DIGIT1, 1 ; если результат равен «0» уменьшаем переменную DIGIT1 на «1»
incf    DIGIT2, 1 ; увеличиваем переменную DIGIT2 на «1» (переносим разряд)
movlw        d'10' ; записываем в аккумулятор значение «10»
subwf                   DIGIT2, 0 ; вычитаем значение аккумулятора из переменной DIGIT2
btfss  STATUS, Z        ; проверяем результат на «0»
goto  calc2; если результат не «0» идем на метку
;-----------------------------------------------------calc2
decf   DIGIT2, 1 ; если результат равен «0» уменьшаем переменную DIGIT2 на «1»
incf    DIGIT3, 1 ; увеличиваем переменную DIGIT3 на «1» (переносим разряд) 
movlw        d'10' ; записываем в аккумулятор значение «10»
subwf                   DIGIT3, 0 ; вычитаем значение аккумулятора из переменной DIGIT3
btfss  STATUS, Z                  ; проверяем результат на «0»
goto  calc2; если результат не «0» идем на метку calc2
decf   DIGIT3, 1 ; если результат равен «0» уменьшаем переменную DIGIT3 на «1»
goto  calc5; выходим из подпрограммы т.к. достигнуто значение 99,9
;-----------------------------------------------------корректируем погрешность перевода
calc2 decfz LAPSE, 1  ; уменьшаем значение LAPSE на 1
goto  calc3; если переменная LAPSE не равна «0» — идем на метку calc3
movlw        d'57' ; записываем в аккумулятор значение «57»
movwf        LAPSE      ; записываем значение аккумулятора в переменную LAPSE
movlw        d'2'   ; записываем в аккумулятор значение «2»
addwf                  TIMER1, 1; прибавляем к переменной TIMER1 значение аккумулятора
goto  calc3; идем на метку calc3
;-----------------------------------------------------корректируем переменные TIMER1 и TIMER2
calc1 addwf         TIMER1, 1; прибавляем к переменной TIMER1 значение аккумулятора
movlw        d'100'        ; записываем в аккумулятор значение «100»
addwf                  TIMER1, 1; прибавляем к переменной TIMER1 значение аккумулятора
decf   TIMER2    ; уменьшаем значение переменной TIMER2 на «1»
проверяем флаги регистра STATUS
btfss  STATUS, C        ; флаг C-переноса
btfsc  STATUS, Z                  ; и флаг       Z-нулевого результата
goto  calc4; если результат не отрицательный-продолжаем
если Z=0 и C=0 значит результат отрицательный-
;---------------------------------------------------------------------------------------------------------calc5         return                  ; возврат из подпрограммы
;==============================================================
Блок-схема данной подпрограммы представлена на рис. 14. Поясним некоторые моменты. Принимая скорость звука равной 331,4 м/с, имеем 331,4*1000/1000000 мм/мкс или 0,3314 мм/мкс. Т.к. по условию задания точность измерений составляет 0,1 м, а измеренное нами время составляет двойную величину, то логично вести подсчет промежутками времени за которое ультразвук проходит 0,2 м. Т.е. 200/0,3314=603,5=(600+3,5) мкс. Каждые 600 мкс у нас накапливается погрешность в 3,5 мкс. 57*3,5=199,5≈200. Т.е. каждый промежуток времени 57*600 мкс у нас возникает погрешность в 200 мкс. Хотя она и составляет 1/3 от заданной точности мы, все равно будем ее учитывать. Принцип работы подпрограммы ясен из блок-схемы.
 SHAPE  \* MERGEFORMAT
Рис. 14. Блок-схема подпрограммы calculation.
Заключение
В процессе выполнения курсового проекта, было спроектировано устройство ультразвукового измерения дальности. В пояснительной записке представлено подробное описание схемы устройства, описание программного обеспечения.
В приложении представлена принципиальная схема разработанного устройства и приведен листинг программы.
В ходе выполнения курсового проекта были решены следующие задачи:
·                   синтез и разработка принципиальной схемы устройства;
·                   разработка программного обеспечения;
·                   разработка конструкторской документации проекта (пояснительная записка).

Библиографический список
1.                В. С. Яценков «Микроконтроллеры Microchip. Практическое руководство».
2.                Документация к контроллерам фирмы Microchip.

Приложения
;==============================================================
программа для ультразвукового дальномера
;==============================================================
список директив
list     P=16C84   ; директива определяющая тип процессора
#include        ; файл, описывающий специфические переменные, соответствующие процессору
_config       b'00000000000001'     ; слово конфигурации CPU
;==============================================================
описание используемых переменных (назначение адресов ячеекдля хранения переменных)
NUMIMP   equ    0x0C; рабочая переменная для подсчета числа импульсов
TIMER1     equ    0x0D; рабочая переменная для подсчета времени 1
TIMER2     equ    0x0E; рабочая переменная для подсчета времени 2
LAPSE       equ    0x0F; рабочая переменная для подсчетапогрешности перевода времени
DIGIT1      equ    0x10; рабочая переменная индикатора дециметров
DIGIT2      equ             0x11                   ; рабочая переменная индикатора метров
DIGIT3      equ    0x12; рабочая переменная индикатора декаметров
;==============================================================
исполняемая программа
org    0х000                 ; вектор сброса процессора, начальный адрес
clrf    PORTA     ; очистили выходные защелки порта А
clrf    PORTB     ; и порта В
clrf    TMR0       ; очистка таймера TMR0
bsf     STATUS, RP0    ; включили банк 1
movlw        b’00011110’      ; настроили на вывод линию RA0,
movwf        PORTA     ; остальные линии порта A на ввод
movlw        b’00000000’      ; настроили на вывод все линии порта B
movwf        PORTB      ;RB0…RB7
bcf     OPTION_REG, 7         ; включили подтягивающие резисторы
bcf     OPTION_REG, 5         ; включили режим таймера для TMR0
bcf     STATUS, RP0    ; включили банк 0
;==============================================================
main ; основная программа
call    initialization                 ; вызываем подпрограмму инициализации
main1                  call    indication  ; вызываем подпрограмму индикации
goto  divssing     ; вызываем подпрограмму обработки нажатия кнопки     
main2                  call    transfer      ; вызываем подпрограмму передачи импульсов
main3                  goto  waiting      ; вызываем подпрограмму ожидания отраженного сигнала
main4                  goto  reception   ; вызываем подпрограмму приема отраженного сигнала
main5                  call    calculation ; вызываем подпрограмму вычисления расстояния
;==============================================================
initialization        ; подпрограмма инициализации и начальных условий
обнуляем значения используемых переменных
clrf    PORTA     ; очистили выходные защелки порта A
clrf    NUMIMP  ; обнуляем значение NUMIMP
    продолжение
--PAGE_BREAK--


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.