Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсач В7.doc
Скачиваний:
3
Добавлен:
28.08.2019
Размер:
398.85 Кб
Скачать

6. Исходные коды программ

.PROGRAM Kurswork

#include G:\Softune\Mb90V590.h

.EXPORT _main

.SECTION DATA_MAIN, DATA, ALIGN=2

YH .RES.W 1 //целая часть y

YL .RES.W 1 //вещественна часть y

XH .RES.W 1 //целая часть x

XL .RES.W 1 //вещественна часть x

CorrCH .RES.W 1 // 2 старших бита коэффициента усиления

CorrCL .RES.W 1 // 8 младших бита коэффициента усиления

//коэффициенты

C1 .DATA.W H'60

C2 .DATA.W H'01

C3 .DATA.W -96

C4 .DATA.W -1

C5 .DATA.W H'00

C6 .DATA.W H'62

C7 .DATA.W 10

InpS .DATA.W 40

.SECTION CODE_MAIN, CODE, ALIGN=2

/*Процедура сложения 2 вещественных чисел*/

_ADD4:

//Input: RW1 - целая часть 1 RW0 - вещественная часть 1, RW3 - целая часть 2 RW2 - вещественная часть 2;

//Output: RW5 - целая часть 3 RW4 - вещественная часть 3

//Сохранение нужных регистров в стеке, в конце процедуры мы их восттановим

PUSHW A

MOVW A, RW6

PUSHW A

MOVW A, RW1

PUSHW A

MOVW A, RW0

PUSHW A

MOVW A, RW3

PUSHW A

MOVW A, RW2

PUSHW A

// Приводим число от 4-х байтового к 2 байтовому, для этого умножаем целую часть на 100 и складываем с вещественной

MOVW RW6, #100

MOVW A, RW1

MULW A, RW6

ADDW A, RW0

MOVW RW1, A

// Приводим аналогичную процедуру со 2 числом

MOVW RW6, #100

MOVW A, RW3

MULW A, RW6

ADDW A, RW2

// Складываем оба числа

ADDW A, RW1

// Проверяем, является ли сумма отрицательным числом

BN ADDBEFORENULL

// Если положительное, то разделяем сумму на целую и вещественную части, для этого делим сумму на 100,

// результат деления - целая часть, остаток - вещественная. Вещественную часть приводим к числу не большему 99.

//это проводим деля остаток на 100, результат складываем с целой частью, остато записываем в вещественную часть

MOVW RW6, #100

DIVU A, R4

MOVW RW5, A

MOVW RW4, RW6

MOVW A, RW4

MOVW RW6, #100

DIVU A, R4

MOVW RW4, RW6

MOVW RW6, A

MOVW A, RW5

ADDW A, RW6

MOVW RW5, A

JMP EndADD4

ADDBEFORENULL:

// Если отрицательное, то изменяем знак операнда, проводим процедуру, описанную выше, и меняем знак операнда ещё раз

NEGW A

MOVW RW6, #100

DIVU A, R4

MOVW RW5, A

MOVW RW4, RW6

MOVW A, RW4

MOVW RW6, #100

DIVU A, R4

MOVW RW4, RW6

MOVW RW6, A

MOVW A, RW5

ADDW A, RW6

MOVW RW5, A

MOVW A, RW4

NEGW A

MOVW RW4, A

MOVW A, RW5

NEGW A

MOVW RW5, A

EndADD4:

// Восстанавливаем регистры

POPW A

MOVW RW1, A

POPW A

MOVW RW0, A

POPW A

MOVW RW3, A

POPW A

MOVW RW2, A

POPW A

MOVW RW6, A

POPW A

RET

/*Процедура умножения 2 вещественных чисел*/

_MUL4:

//Input: RW1 - целая часть 1 RW0 - вещественная часть 1, RW3 - целая часть 2 RW2 - вещественная часть 2;

//Output: RW5 - целая часть 3 RW4 - вещественная часть 3 PUSHW A

//Сохранение нужных регистров в стеке, в конце процедуры мы их восттановим

PUSHW A

MOVW A, RW6

PUSHW A

MOVW A, RW1

PUSHW A

MOVW A, RW0

PUSHW A

MOVW A, RW3

PUSHW A

MOVW A, RW2

PUSHW A

MOVW A, RW7

PUSHW A

MOVW RW7, #0

MOV R2, #0

// Проверяем, является ли произведение чисел отрицательным, это возможно только в случае, если один из сомножителей отрицателен, а другой положителен

// Одновременно с этим проверяем, является ли каждое число отрицательным, если да, то меняем знак этого числа, чтобы работать только с положительными числами

// Флаг отрицательного числа лежит в RW7

MOVW A, RW0

ADDW A, RW1

BN MULNEXT3

JMP MULNEXT4

MULNEXT3:

MOV A, R2

INC A

MOV R2, A

MOVW A, RW0

NEGW A

MOVW RW0, A

MOVW A, RW1

NEGW A

MOVW RW1, A

MULNEXT4:

MOVW A, RW3

ADDW A, RW2

BN MULNEXT5

JMP MULNEXT6

MULNEXT5:

MOV A, R2

INC A

MOV R2, A

MOVW A, RW2

NEGW A

MOVW RW2, A

MOVW A, RW3

NEGW A

MOVW RW3, A

MULNEXT6:

MOV A, R2

CMP A, #1

BEQ CHANGESIGN0

JMP MULNEXT1

CHANGESIGN0:

MOVW RW7, #1

// Умножаем последовательно целую и целую части, целую и вещественную, вещественную и целую, вещественную и вещественную

MULNEXT1:

// Целая и целая

MOVW RW6, #0

MOVW A, RW1

MULW A, RW3

// После перемножения помещаем в RW5

MOVW RW5, A

// Целая и вещественная

MOVW A, RW1

MULW A, RW2

// После перемножения необходимо разделить целую и вещественную части, для этого делимна 100, результат складываем с RW5, а остаток с RW4

MOV R4, #100

DIVU A, R4

ADDW A, RW5

MOVW RW5, A

MOVW RW4, RW6

MOVW A, RW0

MULW A, RW3

// После перемножения необходимо разделить целую и вещественную части, для этого делимна 100, результат складываем с RW5, а остаток с RW4

MOV R4, #100

DIVU A, R4

ADDW A, RW5

MOVW RW5, A

MOVW A, RW6

ADDW A, RW4

MOVW RW4, A

// вещественная и вещественная, результат округляем путём деления на 100

MOVW A, RW0

MULW A, RW2

MOV R4, #100

DIVU A, R4

ADDW A, RW4

//Вещественную часть приводим к числу не большему 99.

//это проводим деля остаток на 100, результат складываем с целой частью, остато записываем в вещественную часть

MOVW RW4, A

MOV R4, #100

DIVU A, R4

CMP A, #0

BEQ MULNEXT0

ADDW A, RW5

MOVW RW5, A

MOVW RW4, #0

MOV R0, R4

MULNEXT0:

MOVW A, RW7

CMPW A, #0

BNE CHANGESIGN1

JMP MULNEXT2

// В случае если установлен знак отрицательного числа RW7, изменяем знак реззультата

CHANGESIGN1:

MOVW A, RW4

NEGW A

MOVW RW4, A

MOVW A, RW5

NEGW A

MOVW RW5, A

MULNEXT2:

// Восстанавливаем регистры

POPW A

MOVW RW7, A

POPW A

MOVW RW1, A

POPW A

MOVW RW0, A

POPW A

MOVW RW3, A

POPW A

MOVW RW2, A

POPW A

MOVW RW6, A

POPW A

RET

/*Процедура округления числа*/

Trunc:

// Input: RW1 RW0; Output: RW2

//Сохранение нужных регистров в стеке, в конце процедуры мы их восттановим

PUSHW A

MOVW A, RW6

PUSHW A

MOV R1, #0

// Проверяем, являются ли числа отрицательными, в случае этого изменяем знак и устанавливаем флаг R1

MOVW A, RW0

BN TruncCHANGESIGN0

MOVW A, RW1

BN TruncCHANGESIGN0

JMP TruncNext2

TruncCHANGESIGN0:

MOVW A, RW1

NEG A

MOVW RW1, A

MOVW A, RW0

NEG A

MOVW RW0, A

MOV R1, #1

// В случае если вещественная часть больше 50, то прибавляем к целой части 1, то есть округляем к ближайшему целому

TruncNext2:

MOVW A, RW0

CMP A, #51

BLO TruncNext0

MOVW A, RW1

INCW A

MOVW RW1, A

TruncNext0:

MOV R0, #0

MOVW A, RW4

CMPW A, #0

// Если установлен флаг R1, то делаем число обратно отрицательным

BNE TruncCHANGESIGN1

JMP EndTrunc

TruncCHANGESIGN1:

MOVW A, RW1

NEG A

MOVW RW1, A

EndTrunc:

// Масштабируем число в диапазон 0 - FF

MOVW A, RW1

ADDW A, #1020

MOVW RW2, RW1

MOVW RW3, #0

POPW A

MOVW RW6, A

POPW A

RET

/*Процедура сравнения двух чисел. Если одно из них отличается от другого более чем на С1%, то R7 = 1, иначе R7 = 0*/

Compare:

// Input RW1, RW0; Output R7

//Сохранение нужных регистров в стеке, в конце процедуры мы их восттановим

PUSHW A

MOVW A, RW0

PUSHW A

MOVW A, RW1

PUSHW A

MOVW A, RW3

PUSHW A

MOVW A, RW2

PUSHW A

MOVW A, RW0

PUSHW A

// Умножаем первое число на 0.C7, Где С7 - заданная погрешность. Меняем знак результата и отправляем его в стек.

MOV R7, #0

MOVW RW0, #0

MOVW RW3, #0

MOVW RW2, C7

CALL _MUL4

POPW A

MOVW RW3, A

MOVW A, RW5

NEG A

PUSHW A

MOVW A, RW4

NEG A

PUSHW A

// Вычитаем одно число из другого, если результат отрицательный, то меняем знак.

MOVW RW2, #0

MOVW A, RW1

NEG A

MOVW RW1, A

MOVW RW0, #0

CALL _ADD4

MOVW A, RW4

BN CompareChangesign

MOVW A, RW5

BN CompareChangesign

JMP CompareNext0

CompareChangesign:

MOVW A, RW4

NEG A

MOVW RW4, A

MOVW A, RW5

NEG A

MOVW RW5, A

// Вынимаем ранее полученное значение из стека и складываем с предыдущим результатом (разницей 2-х чисел), если результат положительный, то устанавливаем R7 = 1

CompareNext0:

MOVW RW0, RW4

MOVW RW1, RW5

POPW A

MOVW RW2, A

POPW A

MOVW RW3, A

CALL _ADD4

MOVW A, RW4

BP SETFLAG

MOVW A, RW5

BP SETFLAG

JMP CompareNext1

SETFLAG:

MOV R7, #1

CompareNext1:

// Восстановление из стека

POPW A

MOVW RW0, A

POPW A

MOVW RW1, A

POPW A

MOVW RW3, A

POPW A

MOVW RW2, A

POPW A

RET

/*Процедура сравнения трёх чисел, если одно из них отличакется больше чем на 10% то выставляется номер датчика на R7*/

CompareThree:

// Input RW0, RW1, RW2; Output R7

PUSHW A

MOVW A, RW0

PUSHW A

MOVW A, RW1

PUSHW A

MOVW A, RW2

PUSHW A

MOVW A, RW4

PUSHW A

MOVW A, RW5

PUSHW A

MOVW A, RW6

PUSHW A

// Сравнение 1 и 3, 1 и 2, если есть отличия больше 10% то R7 = 1

MOVW RW4, RW0

MOVW RW5, RW1

MOVW RW6, RW2

CALL Compare

MOV R6, R7

MOVW RW1, RW2

CALL Compare

MOV A, R6

ADD A, R7

CMP A, #2

BEQ WITHOUTFIRST

// Сравнение 2 и 1, 2 и 3, если есть отличия больше 10% то R7 = 2

MOVW RW0, RW5

MOVW RW1, RW4

CALL Compare

MOV R6, R7

MOVW RW1, RW6

CALL Compare

MOV A, R6

ADD A, R7

CMP A, #2

BEQ WITHOUTSECOND

// Сравнение 3 и 1, 3 и 2, если есть отличия больше 10% то R7 = 3

MOVW RW0, RW6

MOVW RW1, RW4

CALL Compare

MOV R6, R7

MOVW RW1, RW5

CALL Compare

MOV A, R6

ADD A, R7

CMP A, #2

BEQ WITHOUTTHIRD

MOV R7, #0

JMP EndCompareDouble

WITHOUTFIRST:

MOV R7, #1

JMP EndCompareDouble

WITHOUTSECOND:

MOV R7, #2

JMP EndCompareDouble

WITHOUTTHIRD:

MOV R7, #3

JMP EndCompareDouble

EndCompareDouble:

POPW A

MOVW RW6, A

POPW A

MOVW RW5, A

POPW A

MOVW RW4, A

POPW A

MOVW RW2, A

POPW A

MOVW RW1, A

POPW A

MOVW RW0, A

POPW A

RET

_main:

// Начальное значение Y = 0.00

MOVW YH, #H'00

MOVW YL, #H'00

// Начальное значение X = 0.00

MOVW XH, #H'00

MOVW XL, #H'00

//Настраиваем порты на вывод и инициализируем порты

MOV DDR8, #H'FF

MOVW PDR8, #0

MOV DDR7, #H'FF

MOVW PDR7, #0

MOV DDR4, #H'FF

MOVW PDR4, #H'FF

MOV DDR5, #H'FF

MOVW PDR5, #H'3

MOV DDR3, #H'FF

MOVW PDR3, #0

// Коэффициент усиления

MOVW CorrCH, #H'3

MOVW CorrCL, #H'FF

//Настраиваем АЦП

MOV ADCS0,#H'00

MOV ADCS1,#H'00

MOV ADCR1,#H'E8

MOVW A, #H'00

MOV ADER, #H'01

MLOOP0:

// 1 датчик считываем и масштабируем

MOV ADER, #H'01

SETB ADCS1:1

CLRB ADCS1:1

WBTC ADCS1:7

MOVW A, ADCR0

ADDW A, #255

MOVW RW0, A

// 2 датчик считываем и масштабируем

MOV ADER, #H'02

SETB ADCS1:1

CLRB ADCS1:1

WBTC ADCS1:7

MOVW A, ADCR0

ADDW A, #255

MOVW RW1, A

// 3 датчик считываем и масштабируем

MOV ADER, #H'03

SETB ADCS1:1

CLRB ADCS1:1

WBTC ADCS1:7

MOVW A, ADCR0

ADDW A, #255

MOVW RW2, A

// Выясняем, какой датчик битый и удаляем его из рассмотрения, находим среднее значение

CALL CompareThree

MOV A, R7

CMP A, #1

BEQ DELETEFIRST

CMP A, #2

BEQ DELETESECOND

CMP A, #3

BEQ DELETETHIRD

MOVW A, RW0

ADDW A, RW1

ADDW A, RW2

MOV R0, #3

DIVU A, R0

JMP MNEXT0

DELETEFIRST:

MOVW A, RW1

ADDW A, RW2

MOV R0, #2

DIVU A, R0

JMP MNEXT0

DELETESECOND:

MOVW A, RW0

ADDW A, RW2

MOV R0, #2

DIVU A, R0

JMP MNEXT0

DELETETHIRD:

MOVW A, RW0

ADDW A, RW1

MOV R0, #2

DIVU A, R0

MNEXT0:

// Вычисление разностного уравнения

// 1 произведение

PUSHW A

MOVW A, #0

PUSHW A

MOVW RW0, A

MOVW RW1, #0

MOVW RW3, C2

MOVW RW2, C1

CALL _MUL4

//Сохранение результата

MOVW RW7, RW5

MOVW RW6, RW4

// 2 произведение

MOVW RW0, XL

MOVW RW1, XH

MOVW RW3, C4

MOVW RW2, C3

CALL _MUL4

//1 сложение

MOVW RW0, RW5

MOVW RW1, RW4

MOVW RW3, RW6

MOVW RW4, RW7

CALL _ADD4

MOVW RW7, RW5

MOVW RW6, RW4

// 3 умножение

MOVW RW0, YL

MOVW RW1, YH

MOVW RW3, C6

MOVW RW2, C5

CALL _MUL4

//2 сложение

MOVW RW0, RW5

MOVW RW1, RW4

MOVW RW3, RW6

MOVW RW4, RW7

CALL _ADD4

// Запись в Y и X

MOVW YL, RW4

MOVW YH, RW5

POPW A

MOVW XL, A

POPW A

MOVW XH, A

// Округление и вывод на ЦАП

MOVW RW0, RW4

MOVW RW1, RW5

CALL Trunc

MOVW A, RW2

MOVW PDR8, A

SWAP

MOVW PDR7, A

SWAP

// Сравнение ожидаемого результата с результатом на ЦАПе

MOVW A, RW0

MOV ADER, #H'00

SETB ADCS1:1

CLRB ADCS1:1

WBTC ADCS1:7

MOVW RW1, ADCR0

CALL Compare

MOV A, R7

BP Correct

JMP MNEXT1

// Коррекция коэффициента усиления. Проходим коэффициенты от 1 до 1024, если в результате разницу между сигналами

// не удалось снизить до приемлимого уровня, подаём 1 на PDR3 - включаем акустику.

Correct:

MOVW CorrCH, #H'3

MOVW CorrCL, #H'FF

MOVW RW2, #100

MOVW A, CorrCH

MULW A, RW2

ADDW A, CorrCL

MOVW RW2, A

MOVW RW4 R, #100

MLOOP2:

SETB ADCS1:1

CLRB ADCS1:1

WBTC ADCS1:7

MOVW RW1, ADCR0

CALL Compare

MOV A, R7

CMP A, 0

BEQ MNEXT1

MOVW A, RW2

DIVU A, R0

MOVW CorrCH, A

MOVW PDR5, CorrCH

MOVW CorrCL, RW4

MOVW PDR4, CorrCL

DWBNZ RW2, MLOOP2

MOVW PDR3, #1

MNEXT1:

// Задержка сигнала

MOVW RW0, #1000

MLOOP1:

NOP

DWBNZ RW0, MLOOP1

JMP MLOOP0

NOP

.END

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]