.CHIP 8052 ;21.10.2011. BEEP приналичии ошибок.
.RAMCHK OFF;
CkCON0 .reg 8fh ;регистр выбора режима х2 для процессора и периферии (стр18)
CkCON1 .reg 0afh ;регистр выбора режима х2 для SPI интерфейса (стр19)
Auxr .reg 8eh ;выключение ALE, разрешение XRAM, изменение объема
;XRAM, выключение PUL UP резисторов (стр24)
CKRL .reg 97h ;8 битовый предделитель частоты процессора (стр15)
EeCON .reg 0d2h ;регистр управления флэш памятю. (стр91)
T2mod .reg 0c9h ;регистр управления таймера 2.(стр34)
BRL .reg 9ah ;регистр задания скорости com порта (стр55)
bdrcon .reg 9bh ;регистор режимов COM порта (стр58)
KBF .reg 9eh ;регистр флагов клавиатурного прерывания (стр60)
KBE .reg 9dh ;регистр переназначения выводов порта P1 на клавиатуру (стр61)
IEN1 .reg 0b1h ;регистр разрешения прерывания (SPI, клавиатура) (стр77)
KBLS .reg 9ch ;регистр уровней
CH .reg 0f9h ;регистр временной базы PCA. Старший байт (стр42)
CL .reg 0e9h ;регистр временной базы PCA. Младший байт (стр42)
Ccon .reg 0d8h ;регистр управления PCA (стр38)
cmod .reg 0d9h ;регистр режимов PCA (стр37)
Ccapm0 .reg 0dah ;регистр режима модуля 0 PCA (стр40)
Ccapm1 .reg 0dbh ;регистр режима модуля 1 PCA (стр40)
Ccapm2 .reg 0dch ;регистр режима модуля 2 PCA (стр40)
Ccapm3 .reg 0ddh ;регистр режима модуля 3 PCA (стр40)
Ccapm4 .reg 0deh ;регистр режима модуля 4 PCA (стр40)
CcaP0h .reg 0fah ;регистр значений модуля 0. Старший байт (стр41)
CcaP1h .reg 0fbh ;регистр значений модуля 1. Старший байт (стр41)
CcaP2h .reg 0fch ;регистр значений модуля 2. Старший байт (стр41)
CcaP3h .reg 0fdh ;регистр значений модуля 3. Старший байт (стр41)
CcaP4h .reg 0feh ;регистр значений модуля 4. Старший байт (стр41)
CcaP0l .reg 0EAh ;регистр значений модуля 0. Младший байт (стр42)
CcaP1l .reg 0ebh ;регистр значений модуля 1. Младший байт (стр42)
CcaP2l .reg 0ech ;регистр значений модуля 2. Младший байт (стр42)
CcaP3l .reg 0edh ;регистр значений модуля 3. Младший байт (стр42)
CcaP4l .reg 0eeh ;регистр значений модуля 4. Младший байт (стр42)
CS .reg P2.3 ;линия выбоpа микpосхемы = CS, 10
MOSI .reg P2.2 ;линии = Din, 11 ;P2.4 макет ;P2.2
MISO .reg P2.1 ;поpта = Dout, 12 ;P2.5 макет ;P2.1
SCK .reg P2.0 ;SPI = CLK, 13 ;P2.2 макет ;P2.0
;Сохраняемые ячейки
Serv .reg 20h.1 ;бит режима настроек
Left .reg 20h.2 ;бит признака вращения энкодера влево
Right .reg 20h.3 ;бит признака вращения энкодера вправо
Dzdec .reg 20h.4 ;бит запрета анализа сигнала от энкодера
Strob .reg 20h.5 ;строб вывода информации на ЖКИ
Strob1s .reg 20h.6 ;секундный строб
Knobf .reg 20h.7 ;бит признака нажатия кнопки
Knobl .reg 21h.0 ;бит признака долгого нажатия кнопки
Moving .reg 21h.1 ;бит признака движения
PIC .reg 21h.2 ;отслеживание в канале поворотника изменения уровня
ErrCon .reg 21h.3 ;бит признака ошибка связи с ЭБУ
ErrBeep .reg 21h.4 ;бит подачи звукового сигнала при наличии ошибок
Status .equ 22h ;ячейка статуса программы
ComState .equ 23h ;статус обработчика COM порта
Beep .equ 24h ;таймер звукового сигнала
ddd .equ 25h ;таймер 150мс
t1s .equ 26h ;таймер 1с
KnobCnt .equ 27h ;счетчик времени нажатия кнопки
Lite .equ 28h ;память яркости подсветки
;Время в пути. Обрабатывается с секундным интервалом от таймера 2. Общее время
;считается в ячейках Chas: Minut: Secund. Время в движении считается в ячейках
;ChasM:MinutM:SecundM если бит Moving установлен. Время в стоянке считается в
;ячейках ChasS: MinutS: SecundS если бит Moving сброшен.
Chas .equ 29h ;счетчик
Minut .equ 2ah ;времени
Secund .equ 2bh ;поездки
Chass .equ 2ch ;счетчик
Minuts .equ 2dh ;времени
Secunds .equ 2eh ;простоя
Chasm .equ 2fh ;счетчик
Minutm .equ 30h ;времени
Secundm .equ 31h ;в пути
;Подсчет расхода. Расход в секунду. Счетчик MLSECC увеличивается в прерывании
;по расходу. Раз в секунду (прерывание от таймера 2) значение MLSECC переписы
;вается в MLSECM и MLSECC обнуляется. Значение в мл. Расход по расстоянию.
;Счетчик MLDISTC увеличивается в прерывании по расходу. В прерывании от датчика
;скорости обрабатывается счетчик дистанции RASHDST. По обнулению счетчика
;дистанции значение MLdistC переписывается в MLDISTM. MLdistC обнуляется и
;счетчик RASHDST инициализируется вновь.
R16D .equ 32h ;счетчик делитель импульсов расхода
MLsecC .equ 33h ;расход в секунду. Счетчик
MLsecM .equ 34h ;расход в секунду. Память
MLdistC .equ 35h ;расход по дистанции. Счетчик
MLdistM .equ 36h ;расход по дистанции. Память
Rashdst .equ 37h ;дистанция для подсчета расхода
Rash1L .equ 38h ;общий расход1 в мл. Младший байт
Rash1H .equ 39h ;общий расход1 в мл. Старший байт
Rash2L .equ 3ah ;общий расход1 в мл. Младший байт
Rash2H .equ 3bh ;общий расход1 в мл. Старший байт
;Напряжение бортсети. Измеряется вначале основного процесса. К измеренному
;значению прибавляется корректирующее значение UCORR Запоминаются текущее
;значение и вычесленный максимум и минимум.
Utek .equ 3ch ;текущее значение напряжения бортсети
Umin .equ 3dh ;минимальное значение напряжения бортсети
Umax .equ 3eh ;максимальное значение напряжения бортсети
Ucorr .equ 3fh ;коррекция измеренного напряжения БС
;Рассояние и скорость. Пройденное рассояние считается в метрах трехбайтовым
;счетчиком DIST3
1. Для подсчета скорости число импульсов в секунду
;накапливается в SPSECH: SPSECL. Раз в секунду (прерывание от таймера 2) результат
;переписывается SPSECH: SPSECL > SpeedH: SpeedL. Ячейки SPSECH: SPSECL обнуляются.
;Раз в секунду (прерывание от таймера 2) значение SpeedH: SpeedL проверяется на
;максимум и максимальное значение запоминается в SPMAXL: SpmaxH. Все значени
;скорости в импульсах для повышения точности расчета.
V6S .equ 40h ;счетчик делитель импульсов расстояния
Dist1 .equ 41h ;пройденное рассотяние. Младший байт
Dist2 .equ 42h ;пройденное рассотяние. Средний байт
Dist3 .equ 43h ;пройденное рассотяние. Старший байт
SpsecL .equ 44h ;счкетчик пройденых импульсов младший байт
SpsecH .equ 45h ;счкетчик пройденых импульсов старший байт
SpeedL .equ 46h ;ячейка подсчета скорости старший байт
SpeedH .equ 47h ;ячейка подсчета скорости старший байт
SpmaxL .equ 48h ;ячейка подсчета максимальной скорости младший байт
SpmaxH .equ 49h ;ячейка подсчета максимальной скорости старший байт
;Передача и прием по COM порту.
CntRx .equ 50h ;адрес буфера приема XRAM
WaitCom .equ 51h ;таймер ожадания
W_Start .equ 52h ;таймер неактивности COM порта
Tcorr .equ 53h ;коррекция температуры двигателя
TDmax .equ 54h ;максимальная температура двигателя
Bufish .equ 55h ;буфеp шестнадцатиpичных отобpажаемых данных
MEM .equ Bufish+4 ;+4 пpи четыpех шестнадцатиpичных pазpядов
Bufout .equ MEM+1 ;выходной буфер преобразвания
jmp M0 ;обход адpесов прерываний
.org 3 ;внешнее прерывание 0 (int0 3H, P3.2)
jmp Ex_int0 ;Расстояние.
.org 0bh ;адpес пpеpывания по таймеpу 0
jmp TR0_int ;точка входа в прерывание по таймеру 0(0bh)
.org 13h ;внешнее прерывание 1 (int1,13H, P3.3)
jmp Ex_int1 ;Расход.
.org 23h ;прерывание по приему и передаче
jbc RI, ComRx ;прерывание по приему переход
jmp ComRx1 ;прерывание по передаче переход
ComRx: push 0 ;прием: сохранить
push acc ;изменяемые регистры
mov R0, CntRx ;загрузить счетчик адреса для косвенной адресации
mov A, sbuf ;принятый байт
movx @R0,A ;записать в XRAM принятый байт
inc CntRx ;следующий адрес буфера приема в XRAM
pop acc ;восстановить
pop 0 ;изменяемые регистры
ComRx1: reti;
.org 3bh ;адpес пpеpывания от энкодера
jmp KBF1 ;обработчик энкодера
M0: mov SP,#80h ;верхушка стека
mov tmod,#11h ;режим работы таймеров
mov T2mod,#2 ;таймер 2 в режим генератора частоты на порт P1.0
orl pcon,#80h ;удвоенная скорость COM порта (sdmod1=1)
mov BRL,#196 ;скорость COM порта: 10 000 000/(16×10400)=196
mov scon,#40h ;SM0=0, SM1=1, SM2=0 режим 3, прием запрещен
mov bdrcon,#1eh ;COM порт от внутр. ген ра (BRR=1) на удв. ч nе (spd=1)
orl CkCON0,#57h ;режим х2 для PCA, TR2 и CPU (X2=0,T2X2=PCAX2=1)
mov cmod,#2 ;регистр режимов PCA (стр37). Режим повышенной частоты
mov Ccon,#40h ;регистр управления PCA (стр38). Запустить PCA
mov KBE,#00001100b;P1.2,P1.3 назначить на энкодер
orl IEN1,#1 ;разрешить прерывание от клавиатуры
mov P0,#10001111b ;поpт ЖКИ.
mov P1,#11111110b ;P1.0 динамик
setb ex0 ;разрешить внешнее прерывание int0
setb ex1 ;разрешить внешнее прерывание int1
setb it0 ;пpеpыванию int0 pеагиpовать на задний фpонт
setb it1 ;пpеpыванию int1 pеагиpовать на задний фpонт
setb et0 ;pазpешить пpеpывание от таймеpа 0
setb tr0 ;запуск таймера 0 (временная база)
mov W_Start,#10 ;обнуление памяти XRAM:
call StartCom ;при W_Start <>0 обнуляется только XRAM
call Initlcd ;инициализация ЖКИ
call Rdprof ;чтение профиля из ПЗУ. Бит EA устанавливается там
mov V6S,#6 ;счетчик делитель импульсов расстояния
mov R16D,#16 ;счетчик делитель импульсов расхода
mov t1s,#20 ;инициализация счетчика вpемени 50мс * 20 = 1с
mov Umax,#50 ;инициировать Umax напряжением 5 В
mov Umin,#160 ;инициировать Umin напряжением 16 В
mov SpmaxL,#0 ;обнуление
mov SpmaxH,#0 ;максимальной скорости
mov MLdistM,#0 ;обнулить счетчик расхода по расстоянию
mov Rashdst,#100 ;подсчет расхода за 100 м
mov ComState,#0 ;статус обработчика COM порта
mov CcaP1h, Lite ;установить яркость подсветки
mov Ccapm1,#42h ;установить бит ECOM модуля 1 PCA. Режим ШИМ
mov W_Start,#0 ;обнулить, иначе возможен пропуск старта при включении
clr Knobf;
; Основной: цикл
Start: mov A,#66h ;номер канала АЦП
call Readv ;измерить напряжение в канале
mov Utek, A ;сохранить значение
clr C ;подсчет максимума и минимума
mov A, Umin ;поиск минимального значения:
subb A, Utek ;из текущего значения вычесть Umin
jc ST1 ;если Umin < текущего, С = 0, переход
mov Umin, Utek ;иначе запомнить новое минимальное значение
ST1: clr C;
mov A, Umax ;поиск максимального значения:
subb A, Utek ;из текущего значения вычесть Umax
jnc ST2 ;если Umax > текущего, С = 1, переход
mov Umax, Utek ;иначе запомнить новое максимальное значение
;Выключение с записью профиля при выключении зажигания
ST2: jnb P2.6,ST6 ;+12 В на зажигании есть переход
mov WaitCom,#20 ;первая задержка 1с
ST3: mov rcap2h,#0F3h ;Входная частота (в режиме X2) 10МГЦ / 2 = 5МГЦ
mov rcap2l,#01h ;Выходная частота = 2.5МГц / (10000h F57F) = 930Гц
mov Beep,#3 ;таймер звукового сигнала. Время 3×50мс = 150мс
ST4: mov A,#67h ;номер канала АЦП
call Readv ;измерить напряжение в канале подсветки
subb A,#30 ;порог 3 В
jc ST5 ;ниже порога переход
jnb P2.6,ST13 ;+12 В на зажигании есть переход
mov A, WaitCom ;задержка
jnz ST4 ;не кончилась цикл
mov WaitCom,#0ffh ;иначе перезагрузить таймер
mov dptr,#STM41 ;сообщение
call Outstr ;080h, 0ffh, 1,"Выключи габариты", 0ffh, 0c0h,"дубина!", 0
jmp ST3 ;цикл ожидания выключения подсветки
ST5: mov dptr,#STM11 ;сообщение
call Outstr ;080h, 0ffh, 1,"Запись профиля…", 0ffh, 0c0h, 0
call Wrprof ;записать профиль в ПЗУ
clr P1.1 ;обесточить удерживающее реле
mov pcon,#2 ;выключить процессор
jmp $;
;Реакция на длительное нажатие кнопки смена режима
ST6: jnb Knobl, ST7 ;длительного нажатия нет переход
clr Knobl ;сбросить бит признака долгого нажатия кнопки
mov Status,#0 ;при нажатии кнопки перебор меню начать с нуля
cpl Serv ;бит режима настроек
jmp ST13 ;изменен статус очистить дисплей ЖКИ
;Реакция на поворот валкодера
ST7: mov R1,#22 ;максимальное значение регистра Status (ставить на единицу меньше)(на е !!!!!
jnb Serv, ST9;
mov R1,#3 ;максимальное значение регистра Status (ставить на единицу меньше) в режиме настроек
ST9: jnb Right, ST10 ;бит признака вращения энкодера вправо. Не установлен переход
clr Right ;иначе сбросить бит
inc Status ;увеличить значение
call CLS ;очистить дисплей ЖКИ
jmp ST12 ;изменен статус очистить дисплей ЖКИ
ST10: jnb Left, ST12 ;бит признака вращения энкодера влево. Не установлен переход
clr Left ;иначе сбросить бит
mov A, Status ;уменьшить значение
jz ST11 ;при нулевом значении переход
dec Status ;уменьшить значение регистра Status
jmp ST13 ;изменен статус очистить дисплей ЖКИ
ST11: mov Status, R1 ;иначе загрузить в регистр Status максимальное значение (R1)
jmp ST13 ;изменен статус очистить дисплей ЖКИ
ST12: mov A, Status ;проверка максимального значения:
setb C ;максимальное значение
subb A, R1 ;содержится в регистра R1
jc ST14 ;если Status R1 < 0, С = 1 значение не максимально переход
mov Status,#0 ;иначе загрузить в регистр Status минимальное значение (R0)
ST13: call CLS ;Очистить дисплей ЖКИ
ST14: mov A, Status;
cjne A,#7,ST15 ;Status < 8 работаем без K Line
ST15: jc ST25;
;Драйвер K Line. Общая часть.
mov A, WaitCom ;счетчик ожидания приема
jnz ST16 ;время не вышло выход
mov A, ComState ;байт состояния процесса
jnz ST17;
call StartCom ;ComState = 0 готов к началу передачи
mov ComState,#1 ;ComState = 1 подготовка завершена
ST16: jmp Start ;и пеpеход на начало
ST17: mov A, Status;
cjne A,#7,ST19 ;Status <> 7 переход
;Драйвер K Line. Status = 7
mov A, ComState ;байт состояния процесса
cjne A,#1,ST18 ;шаг не равен 1 переход
mov dptr,#RDERROR ;прередача строки RDERROR 84h, 10h, 0f1h, 18h, 00h, 00h, 00h, 9dh, 0ffh
mov CntRx,#50h ;ответ ЭБУ на STRC записать в XRAM по адресу 10h
jmp ST20 ;и переход
ST18: cjne A,#2,ST23 ;шаг не равен 2 (прием завершен) переход
mov B,#58h ;идентификатоp запpоса с установленым шестым битом
mov R0,#50h ;начальный адрес буфера приема XRAM
call V_Frame ;проверка правильности приема
mov A, ComState ;после вызова V_Frame:
jnz ST22 ;ComState <> 0 прием не правильный
jmp ST26 ;ComState = 0 прием правильный
;Драйвер K Line. Status >7. Диагностика двигателя RDIAG.
ST19: mov A, ComState ;байт состояния процесса
cjne A,#1,ST21 ;шаг не равен 1 переход
mov dptr,#RDIAG ;прередача строки RDIAG 82h, 10h, 0f1h, 21h, 01h, 0a5h, 0ffh
mov CntRx,#10h ;ответ ЭБУ на STRC записать в XRAM по адресу 10h
ST20: mov ComState,#2 ;ComState = 2 данные готовы
call COMTR ;подпрограмма передачи строки в COM порт
jmp Start ;и переход на начало
ST21: cjne A,#2,ST23 ;шаг не равен 2 переход
mov B,#61h ;идентификатоp запpоса с установленым шестым битом
mov R0,#10h ;начальный адрес XRAM ответа ЭБУ на RDIAG
call V_Frame ;проверка правильности приема
mov A, ComState ;после вызова V_Frame:
jz ST24 ;ComState = 0 прием правильный
ST22: call EnumER ;декодирование и отображение ошибки от ЭБУ
setb ErrCon ;бит признака ошибка связи с ЭБУ
ST23: mov ComState,#0 ;ComState = 0 инициализировать обмен
jmp Start ;и пеpеход на начало
;Вычисление максимальной температуры двигателя
ST24: mov R0,#12h+6 ;читать
movx A,@R0 ;температуру двигателя
clr C ;подготовтся к вычитанию
subb A, TDmax ;проверка максимального значения
jc ST26 ;не максмально переход
movx A,@R0 ;читать температуру двигателя
mov TDmax, A ;значение больше TDmax запомнить в TDmax
jmp ST26 ;и пеpеход на начало
;Конец цикла с максимальным быстродействием
ST25: jnb Strob, ST29 ;строб выхода в подменю
ST26: mov ComState,#0 ;ComState = 0 инициализировать обмен
clr Strob ;установлен сбросить строб
jnb ErrCon, ST27 ;если в предидущем цикле
clr ErrCon ;была ошибка сбросить бит ошибки и
call CLS ;очитстить дисплей ЖКИ
ST27: mov A, Status ;регистр статуса содержит индекс таблицы
mov B,#3 ;длина команды перехода в байтах
mul AB ;Status x 3 (jmp занимает 3 байта в таблице)
jnb Serv, ST28 ;бит режима настроек не установлен переход
mov dptr,#STable ;загрузка адреса начала таблицы
jmp SETUP;
ST28: mov dptr,#WTable ;загрузка адреса начала таблицы
jmp WORK;
EXcls: call CLS ;Очистить дисплей ЖКИ
EXitf: clr Knobf ;сбросить бит нажатия кнопки
ST29: jmp Start ;и пеpеход на начало
DisCom: mov WaitCom,#40 ;запрет работы драйвера COM
jmp EXitf ;выход с очисткой Knobf
STM11: db 080h, 0ffh, 1,"Запись профиля…", 0ffh, 0c0h, 0 ;1я стpока
STM41: db 080h, 0ffh, 1,"Выключи габариты", 0ffh, 0c0h,"дубина!", 0 ;1я стpока
; Коммутатор переходов в рабочем режиме
WORK: jmp @a+dptr ;1.переход на обработчик окна
WTable: jmp Main ;2.Основной экран
jmp Skorost ;3.Скорость (нажатие обнулить):
jmp Vremya ;4.Время
jmp Probeg ;5.Пробег
jmp Volt ;6.Напряжение бортсети
jmp Rashod1 ;7.Расход топлива
jmp Rashod2 ;8.Расход топлива
jmp KodERR ;9.Просмотр кодов ошибок
jmp Termo ;10.Температура охлаждающей жидкости
jmp VoltBS ;11.Напряжение бортсети от ЭБУ
jmp Obor ;12.Скорость вращения двигателя
jmp Ptrain ;13.База ошибок Ptrain
jmp W_Work ;14.Слово режима работы
jmp Flags ;15.Флаги текущих неисправностей
jmp VT ;16.Соотношение воздух/топливо
jmp Drossel ;17.Положение дроссельной заслонки
jmp RegTHH ;18.Текущее положение регулятора холостого хода
jmp KorInj ;19.Коэффициент коррекции времени впрыска
jmp UOZ ;20.Угол опережения зажигания
jmp O2 ;21.Напряжение на датчике кислорода
jmp SostO2 ;22.Флаги состояния датчика кислорода
jmp RLI ;23.Чтение и отображение индентификатора
jmp Dump ;24.Вывод дампа памяти
; Коммутатор переходов в режиме настроек
SETUP: jmp @a+dptr ;1.переход на обработчик окна
STable: jmp SetU ;2.Корректировка напряжения бортсети
jmp ErCLR ;3.Стирание ошибок в ЭБУ
jmp SetT ;4.Корректировка порога температуры двигателя
jmp SetLite ;6.Регулировка яркости подсветки
;
; Программы индивидуальных экранов
;
Main: mov R7,#2 ;R7 число знаков после запятой
jb Moving, Main1 ;бит признака движения сброшен переход
;В стоянке: отображение почасового расхода
mov dptr,#Rash41 ;сообщение
call Outstr ;094h,"л/час = «, 0
mov A, MLsecM ;читать значение расхода в секунду
mov B,#9 ;18 / (10 * 8) = 9/40
mul AB ;MLsecM умножаем на 9.
mov R0, A ;R0 делимое младший байт
mov R1, B ;R1 делимое старший байт
mov R2,#40 ;R2 делитель младший байт
mov R3,#0 ;R3 делитель старший байт
call Float ;деление и отображения числа с плавающей точкой
call CLRstr ;вывод четырех пробелов без адресации курсора
mov MLdistM,#0 ;обнулить счетчик расхода по дистанции
;Отображение максимальной скорости
mov dptr,#Main32 ;сообщение
call Outstr ;094h,"Vmax = „, 0
mov R0, SpmaxL ;отобразить максимальную скорость:
mov R1, SpmaxH ;R1:R0 = SpmaxH: SpmaxL x 6 / 10
call Shsp ;подпрограмма отображения скорости
jmp Main2 ;переход
;В движении: отображение расхода по дистанции
Main1: mov dptr,#Rash42 ;сообщение
call Outstr ;0d4h,"л/100км = „, 0
mov R0, MLdistM ;R1:R0 расход в мл на 100 м
mov R1,#0;
mov R2,#16 ;R3:R2 = 0016(мл/импульс)
mov R3,#0;
call Float ;деление и отображения числа с плавающей точкой
;Отображение скорости
mov dptr,#Main31 ;сообщение
call Outstr ;094h,"V = „, 0
mov R0, SpeedL ;[м/с]/6 = [км/ч]/6×3600/1000 = [км/ч]х 6 / 10
mov R1, SpeedH ;R1:R0 = SpeedH: SpeedL x 6 / 10
call Shsp ;подпрограмма пересчета и отображения скорости
call CLRstr ;вывод четырех пробелов без адресации курсора
;Отображение пробега
Main2: mov dptr,#Main21 ;сообщение
call Outstr ;0c0h,"S = „, 0
call Sshow ;подпрограмма отображения пробега
;Отображение времени
mov A,#80h ;адрес
call WrCOM ;курсор в левый верхний угол ЖКИ
mov R0,#Chas ;R0 адресовать на счетчик часов
call Time ;отобразить общее время
jmp DisCom ;и пеpеход на начало {29мс}
Main21: db 0c0h,"S = „, 0 ;2я стpока
Main31: db 094h,"V = „, 0 ;3я стpока
Main32: db 094h,"Vmax = „, 0;3я стpока
; Скорость
Skorost: mov dptr,#SkoR11 ;сообщение: 080h,"1.Скорость:“,
call Outstr ;0ffh, 094h,"Текущая = „, 0
mov R0, SpeedL ;отобразить скорость:
mov R1, SpeedH ;SpeedH:SpeedL x 6 / 10
call Shsp ;подпрограмма отображения скорости
mov dptr,#SkoR41 ;сообщение
call Outstr ;0d4h,"Максим я= „, 0
mov R0, SpmaxL ;отобразить максимальную скорость:
mov R1, SpmaxH ;SpeedH:SpeedL x 6 / 10
call Shsp ;подпрограмма отображения скорости
Sk1: jnb Knobf, Skex ;кнопка не нажата переход
mov SpmaxL,#0 ;обнулить
mov SpmaxH,#0 ;максимальную скорость
Skex: jmp DisCom ;и пеpеход на начало {20мс}
SkoR11: db 080h,"1.Скорость:“, 0ffh, 094h,"Текущая = „, 0
SkoR41: db 0d4h,"Максим я= „, 0 ;4я стpока
; Время
Vremya: mov dptr,#Vrem11 ;сообщение: 080h,"2.Время:“,
call Outstr ;0ffh, 0c0h,"Общее „, 0
mov R0,#Chas ;R0 адресовать на счетчик часов
call Time ;отобразить общее время поездки
mov dptr,#Vrem31;
call Outstr;
mov R0,#Chass ;R0 адресовать на счетчик часов
call Time ;в простое. Отобразить время
mov dptr,#Vrem41;
call Outstr;
mov R0,#Chasm ;R0 адресовать на счетчик часов
call Time ;в поездке. Отобразить время
VR1: jnb Knobf, Vrex ;кнопка не нажата переход
mov R0,#Chas ;адресовать R0 на ячейки времени
VR2: mov @R0,#0 ;обнулить ячейку
inc R0 ;следующая ячейка
cjne R0,#Secundm+1,VR2;цикл обнуления времени
Vrex: jmp DisCom ;и пеpеход на начало {3мс}
Vrem11: db 080h,"2.Время:“, 0ffh, 0c0h,"Общее „, 0
Vrem31: db 094h,"Простоя „, 0 ;3я стpока
Vrem41: db 0d4h,"В движении „, 0 ;4я стpока
; Текущий пробег
Probeg: mov dptr,#Probeg1 ;сообщение: 080h,"3.Текущий пробег:“,
call Outstr ;0ffh, 0c0h,"S = „, 0
call Sshow ;подпрограмма отображения пробега
mov A, Bufout+0 ;читать младший байт пробега (метры)
call Wrsymb ;отобpазить байт
mov dptr,#Probeg3 ;сообщение
call OutX ;“ км“, 0
Prob1: jnb Knobf, Probex ;кнопка не нажата переход
mov Dist1,#0 ;обнуление
mov Dist2,#0 ;пробега
mov Dist3,#0;
Probex: jmp DisCom ;и пеpеход на начало
Probeg1: db 080h,"3.Текущий пробег:“, 0ffh, 0c0h,"S = „, 0
Probeg3: db „км“, 0 ;2я стpока
; Напряжение бортсети:
Volt: mov dptr,#Volt11 ;сообщение: 080h,"4.Напряжение АКБ:“,
call Outstr ;0ffh, 0c0h,"U = „, 0
mov A, Utek ;читать значение напряжения бортсети
call Shvolt ;отобразить напряжение
mov dptr,#Volt31 ;сообщение
call Outstr ;094h,"Uмин=“, 0
mov A, Umin ;минимальное напряжение бортсети
call Shvolt ;отобразить напряжение
mov dptr,#Volt32 ;сообщение
call Outstr ;094h,"Uмин=“, 0
mov A, Umax ;максимальное напряжение бортсети
call Shvolt ;отобразить напряжение
Volt1: jnb Knobf, Voltex ;кнопка не нажата переход
mov Umin,#150 ;инициировать Umin напряжением 15 В
mov Umax,#60 ;инициировать Umax напряжением 6 В
Voltex: jmp DisCom ;и пеpеход на начало {3мс}
Volt11: db 080h,"4.Напряжение АКБ:“, 0ffh, 0c0h,"U = „, 0
Volt31: db 094h,"Uмин=“, 0;3я стpока
Volt32: db 0d4h,"Uмaх=“, 0;4я стpока
; Расход топлива1
Rashod1: mov dptr,#Rash111 ;сообщение: 080h,"5.Расход топлива1″,
call Outstr ;0ffh, 0c0h,"Общий R = „, 0
mov Bufish+0,Rash1L;младший байт расхода
mov Bufish+1,Rash1H;старший байт расхода
call Shrash ;отобразить общий расход
mov R7,#2 ;R7 число знаков после запятой
jb Moving, Rash1 ;движение есть переход
mov dptr,#Rash41 ;сообщение
call Outstr ;094h,"л/час = „, 0
mov A, MLsecM ;читать значение расхода в секунду
mov B,#9 ;B/16 значение в [мл/с]
mul AB ;B/16×3600/1000 = B х 9 / 40 значение в [л/ч]
mov R0, A;
mov R1, B ;R1:R0 = B х 9 делимое
mov R2,#40 ;R3:R2 делитель
mov R3,#0;
call Float ;деление и отображения числа с плавающей точкой
mov MLdistM,#0 ;обнулить счетчик расхода по дистанции
jmp Rash2;
Rash1: mov dptr,#Rash42 ;сообщение
call Outstr ;0d4h,"л/100км = „, 0
mov R0, MLdistM ;R0 делимое младший байт
mov R1,#0 ;R1 делимое старший байт
mov R2,#16 ;R2 делитель младший байт
mov R3,#0 ;R3 делитель старший байт
call Float ;деление и отображения числа с плавающей точкой
Rash2: call CLRstr ;вывод четырех пробелов без адресации курсора
jnb Knobf, Rashex1 ;кнопка не нажата переход
mov Rash1L,#0 ;обнуление
mov Rash1H,#0 ;расхода
Rashex1: jmp DisCom ;и пеpеход на начало {22мс}
Rash111: db 080h,"5.Расход топлива1″, 0ffh, 0c0h,"Общий R = „, 0
Rash41: db 0d4h,"л/час = „, 0 ;4я стpока
Rash42: db 0d4h,"л/100км = „, 0 ;4я стpока
; Расход топлива2
Rashod2: mov dptr,#Rash112 ;сообщение: 080h,"6.Расход топлива2″,
call Outstr ;0ffh, 0c0h,"Общий R = „, 0
mov Bufish+0,Rash2L;младший байт расхода
mov Bufish+1,Rash2H;старший байт расхода
call Shrash ;отобразить общий расход
jnb Knobf, Rashex2 ;кнопка не нажата переход
mov Rash2L,#0 ;обнуление
mov Rash2H,#0 ;расхода
Rashex2: jmp DisCom ;и пеpеход на начало {22мс}
Rash112: db 080h,"6.Расход топлива2″, 0ffh, 0c0h,"Общий R = „, 0
KodERex: jmp EXitf ;выход с очисткой Knobf
; Коды ошибок
KodERR: mov dptr,#Kodm11 ;сообщение: 080h,"8.Коды ошибок“,
call Outstr ;0ffh, 080h+18,0
mov R0,#50h+4 ;[50h+4] байт количества ошибок в XRAM
movx A,@R0 ;читать байт XRAM
call Decout ;отобразить значение
jz KodER0 ;ошибок нет переход
jb ErrBeep, KodER0;бит установлен звуковой сигнал не выдавать (1108)
mov rcap2h,#0F0h ;Входная частота (в режиме X2) 10МГЦ / 2 = 5МГЦ
mov rcap2l,#01h ;Выходная частота = 2.5МГц / (10000h F57F) = 930Гц
mov Beep,#2 ;таймер звукового сигнала. Время 3×50мс = 150мс
KodER0: jnb Knobf, KodERex ;кнопка не нажата переход
setb ErrBeep ;блокировать подачу звукового сигнала
clr Knobf ;иначе сбросить бит нажатия кнопки
jz KodERex ;ошибок нет выход
mov R4, A ;запомнить число ошибок
KodER1: mov R1,#0 ;счетчик номера ошибки
mov R0,#50h+5 ;[50h+5] начало массива ошибок в XRAM
KodER2: mov dptr,#Kodm42 ;сообщение
call Outstr ;0d4h+10,0ffh, 1,"P“, 0
movx A,@R0 ;читать байт XRAM
mov R3, A;
call Hexout ;старший байт
inc R0 ;код ошибки
movx A,@R0 ;читать байт XRAM
mov R2, A ;R3:R2 код ошибки без начальной P (P0100)
call Hexout ;старший байт
inc R0 ;код статуса пропустить
inc R0 ;следующий адрес XRAM
inc R1 ;увеличить порядковый номер ошибки
mov dptr,#Kodm41 ;сообщение
call Outstr ;0d4h,"Номер:“, 0
mov A, R1 ;отобразить
call Decout ;номер ошибки
mov R6,#0 ;счетчик номера строки R7: R6 в базе Ptrain
mov R7,#0 ;для поиска по номеру ошибки
;Поиск расшифровки ошибки
SEAch1: call L_DPTR ;загрузка в DPTR адреса сообщения с номером в R7: R6
mov A,#0 ;первый байт
movc A,@a+dptr ;старший номер ошибки
mov B, R3 ;сравнить с номером от ЭБУ (в R3)
cjne A, B, SEAch2 ;не совпадает переход
inc dptr ;иначе следующий байт в строке сообщения
mov A,#0 ;второй байт
movc A,@a+dptr ;старший номер ошибки
mov B, R2 ;сравнить с номером от ЭБУ (в R2)
cjne A, B, SEAch2 ;не совпадает переход
inc dptr ;иначе здесь DPTR указывает на сообщение
call Outs ;вывести сообщение на дисплей без адресации курсора
jmp KodER3 ;выход из цикла поиска
SEAch2: mov A, R6 ;16 ричный инкремент:
add A,#1 ;R4 величина приращения
mov R6, A ;R7:R6 = R7: R6 + 1
mov A, R7;
addc A,#0;
mov R7, A ;проверка на переполнение:
jz SEAch1 ;старший байт = 0 переполнения нет
mov A, R6 ;проверка младшего байта
clr C ;на значение D8h
subb A,#0d8h ;R7:R6 =
D8 = 472
jc SEAch1 ;значение не достигнуто переход
mov dptr,#Kodm12 ;иначе сообщение
call Outstr ;080h,"Код не найден“, 0
KodER3: jnb Right, KodER4 ;поворота энкодера вправо нет переход
clr Right ;иначе сбросить флаг поворота вправо
mov A, R1 ;читать счетчик номера отображаемой ошибки
mov B, R4;
cjne A, B, KodER2 ;не равен переход
jmp KodER1 ;переход на отображение ошибок
KodER4: jnb Left, KodER5 ;поворота энкодера влево нет переход
clr Left ;иначе сбросить флаг поворота влево
mov A, R1 ;проверка счетчика
dec A ;на начальный 1
jz KodER5 ;значение достигнуто переход
dec R0; 1 перейти к предидущей ошибке
dec R0; 2
dec R0; 3
dec R1; 1
dec R0; 4 перейти к предидущей ошибке
dec R0; 5
dec R0; 6 перейти к предидущей ошибке
dec R1; 2
jmp KodER2;
KodER5: jb P2.6,KodER6 ;зажигание выключено выход
jnb Knobf, KodER3 ;кнопка не нажата переход
KodER6: jmp EXcls ;и пеpеход на начало
Kodm11: db 080h,"7.Коды ошибок“, 0ffh, 080h+18,0 ;1я стpока
Kodm12: db 080h,"Код не найден“, 0 ;1я стpока
Kodm41: db 0d4h,"Номер:“, 0 ;4я стpока
Kodm42: db 1,0ffh, 0d4h+10,"P“, 0 ;4я стpока
; Температура охлаждающей жидкости
Termo: mov dptr,#Termo1 ;сообщение: 080h,"9.Температура ОЖ“,
call Outstr ;0ffh, 0d4h,"T= „, 0
mov R0,#12h+6 ;10h адрес ответа ЭБУ в XRAM
movx A,@R0 ;читать байт XRAM
clr C ;пересчет по формуле
subb A,#88 ;N=E 40(88) [C]
jc term1
add A, Tcorr ;добавить значение коррекции
push acc ;сохранить параметр
subb A,#20 ;вычесть значение 20 градусов
pop acc ;восстановить параметр
jnc Term2 ;температуру ниже 20 не показывать
term1: mov dptr,#Termo3 ;сообщение:
call Outstr ;094h,"ниже 20 градусов“, 0
jmp DisCom ;и пеpеход на начало
Term2: call Decout ;отобразить значение
mov A,#"C“ ;отобразить
call WrDAT ;размерность
call Prob ;вместо нуля отобразить пробел
mov dptr,#Termo2 ;сообщение
call Outstr ;094h,"Максимальная = „, 0
mov A, TDmax ;читать максимальную температуру
clr C ;пересчет по формуле
subb A,#88 ;N=E 40 [C]
add A, Tcorr ;добавить значение коррекции
call Decout ;отобразить значение
mov A,#"C“ ;отобразить
call WrDAT ;размерность
call Prob ;вместо нуля отобразить пробел
jnb Knobf, TermoEX ;кнопка не нажата переход
mov TDmax,#0 ;обнуление
TermoEX: jmp DisCom ;и пеpеход на начало
Termo1: db 080h,"8.Температура ОЖ“, 0ffh, 094h,"T = „, 0
Termo2: db 0d4h,"Макс ная = „, 0 ;4я стpока
Termo3: db 094h,"T < 20C „, 0 ;3я стpока
; Напряжение бортсети
VoltBS: mov dptr,#VoltBS1 ;сообщение: 080h,"10.Напряжение“, 0ffh, 0c0h,
call Outstr ;"бортсети от ЭБУ:“, 0ffh, 0d4h,"U = „, 0
mov R0,#12h+8 ;формула N=5.2+E/20[В] или 52+E/2
movx A,@R0 ;читать значение напряжения
clr C;
rrc A ;делим на 2
add A,#52 ;+ 52
call Shvolt1 ;отображение напряжения
ljmp EXitf ;выход с очисткой Knobf
VoltBS1: db 080h,"9.Напряжение“, 0ffh, 0c0h,"бортсети от ЭБУ:“, 0ffh, 0d4h,"U = „, 0
; Скорость вращения двигателя
Obor: mov dptr,#Obor1 ;сообщение: 080h,"11.Скорость“, 0ffh, 0c0h,
call Outstr ;"вращения двигателя“, 0ffh, 0d4h,"V = „, 0
mov R0,#12h+11 ;10h адрес ответа ЭБУ в XRAM
movx A,@R0 ;читать байт XRAM
mov B,#40 ;формула N=E*40 [об/мин]
mul AB;
mov Bufish+0,A ;сохранить младший байт обработанных данных
mov Bufish+1,B ;сохранить старший байт обработанных данных
call Decimal ;пpеобpазовать в десятичное число
mov A, Bufout+3 ;читать пеpвый (стаpший) байт частоты
jnz GelHH3 ;нуль не отобpажать
call Prob ;вместо нуля отобразить пробел
jmp GelHH4;
GelHH3: lcall Wrsymb ;отобpазить байт
GelHH4: mov A, Bufout+2 ;читать втоpой байт частоты
lcall Wrsymb ;отобpазить байт
mov A, Bufout+1 ;читать тpетий байт частоты
lcall Wrsymb ;отобpазить байт
mov A, Bufout+0 ;читать четвеpтый (младший) байт частоты
lcall Wrsymb ;отобpазить байт
mov dptr,#Obor2 ;сообщение
call Outstr ;0d4h+8,"об/мин „, 0
jmp EXitf ;и пеpеход на начало
Obor1: db 080h,"10.Скорость“, 0ffh, 0c0h,"вращения двигателя“, 0ffh, 0d4h,"V = „, 0
Obor2: db 0d4h+8,"об/мин“, 0
PtrnEx jmp DisCom ;иначе пеpеход на начало
; Просмотр базы сообщений ошибок Ptrain
Ptrain: mov dptr,#Ptr1 ;сообщение:
call Outstr ;080h,"12.База Ptrain“, 0
jnb Knobf, PtrnEx ;кнопка не нажата переход
clr Knobf ;иначе сбросить бит
Ptrn1: mov R7,#0 ;R7:R6 Счетчик номера
mov R6,#0 ;выводимого сообщения
Ptrn2: call CLS ;очистить дисплей ЖКИ
mov A,#0d4h ;адресовать курсор
call WrCOM ;в начало четвертой строки
mov Bufish+0,R6 ;младший байт Отобразить
mov Bufish+1,R7 ;средний байт номер
mov Bufish+2,#0 ;старший байт выводимого
mov Bufish+3,#0 ;старший байт сообщения
call Decimal ;пpеобpазовать в 10 pазpядное десятичное число
mov A, Bufout+3 ;читать старший разряд
call Wrsymb ;отобpазить байт
mov A, Bufout+2 ;читать средний разряд
call Wrsymb ;отобpазить байт
mov A, Bufout+1 ;читать средний разряд
call Wrsymb ;отобpазить байт
mov A, Bufout+0 ;читать младший разряд
call Wrsymb ;отобpазить байт
call L_DPTR ;вычисление адреса выводимого сообщения
mov A,#0d4h+15 ;адресовать курсор
call WrCOM ;в конец четвертой строки
mov A,#"P» ;вывод кода ошибки:
call WrDAT ;вывести символ PowerTrain
mov A,#0 ;первый байт
movc A,@a+dptr ;старший номер ошибки
call Hexout ;отобразить байт
inc dptr ;следующий адрес строки
mov A,#0 ;второй байт
movc A,@a+dptr ;младший номер ошибки
call Hexout ;отобразить байт
inc dptr ;следующий адрес строки начало сообщения
call Outs ;вывести сообщение с адресацией курсора на начало
Ptrn3: jnb Right, Ptrn5 ;поворота энкодера вправо нет переход
clr Right ;иначе сбросить флаг поворота вправо
mov R4,#1 ;величина приращения номера
Ptrn4: mov A, R6 ;16 ричный инкремент:
add A, R4 ;R4 величина приращения
mov R6, A ;R7:R6 = R7: R6 + R4
mov A, R7;
addc A,#0;
mov R7, A ;проверка на переполнение:
jz Ptrn2 ;старший байт = 0 переполнения нет
dec A ;иначе проверка старшего байта
jnz Ptrn1 ;на значение больше 1. Больше переход
mov A, R6 ;проверка младшего байта
clr C ;на значение D8h
subb A,#0d8h;
jc Ptrn2;
jmp Ptrn1 ;R7:R6 < 1D8h (472).Переход на обнуление
Ptrn5: jnb Left, Ptrn7 ;поворота энкодера влево нет переход
clr Left ;иначе сбросить флаг поворота влево
clr C ;16 ричный декремент:
mov A, R6 ;поверка R7: R6 на
orl A, R7 ;нулевое значение
jnz Ptrn6 ;не ноль переход
mov R7,#1 ;иначе записать максимальное значение +1
mov R6,#0d9h ;R7:R6 = 1D9h = 473
Ptrn6: mov A, R6 ;16 ричный декремент
subb A,#1;
mov R6, A ;R7:R6 = R7: R6 1
mov A, R7;
subb A,#0;
mov R7, A;
jmp Ptrn2 ;переход на отображение
Ptrn7: jnb Knobl, Ptrn8 ;долгого нажатия кнопки нет переход
clr Knobl ;иначе сбросить бит долгого нажатия кнопки
mov R4,#50 ;установить инкремент = 50
jmp Ptrn4 ;переход на инкремент
Ptrn8: jb P2.6,Ptrn9 ;зажигание выключено выход
jnb Knobf, Ptrn3 ;кнопка не нажата переход
Ptrn9: call CLS ;очистить дисплей ЖКИ
jmp DisCom ;иначе пеpеход на начало
L_DPTR: push psw ;загрузка в DPTR адреса
push acc ;сообщения с номером в R7: R6
push 7 ;сохранить изменяемые регистры
push 6 ;размерность таблицы адресов 2 байта
clr C ;поэтому номер R6: R7 умножается на 2
mov A, R6;
rlc A ;16 ричное умножение на 2
mov R6, A ;R7:R6 = 2 х R7: R6
mov A, R7 ;R7:R6 смещение на
rlc A ;отображаемое сообщение
mov R7, A;
mov dptr,#PtrainB ;начальный адрес таблицы адресов сообщений
mov A, dpl ;добавить смещение:
add A, R6 ;16 ричное сложение
mov dpl, A ;DPTR = DPTR + R7: R6
mov A, dph ;адреса располагаются в порядке:
addc A, R7 ;сначала ст. б, потом мл.б.
mov dph, A ;здесь DPTR указывает на адрес сообщения
mov A,#0 ;загрузить старший байт
movc A,@a+dptr ;адреса выводимого сообщения
push acc ;сохранить значение
inc dptr ;следующий адрес таблицы
mov A,#0 ;загpузить младший байт
movc A,@a+dptr ;адреса выводимого сообщения
mov dpl, A ;здесь DPTR указывает на сообщение,
pop dph ;определяемое номером в R7: R6
pop 6 ;восстановить
pop 7 ;изменяемые
pop acc ;регистры
pop psw;
ret;
Ptr1: db 080h,"11.База Ptrain", 0 ;1я стpока
; Слово режима работы
W_Work: mov dptr,#W_Wm11 ;сообщение: 080h,"13.Слово режима", 0ffh, 0c0h,
call Outstr ;"работы", 0ffh, 0d4h, 0
mov R0,#12h+5 ;10h адрес ответа ЭБУ в XRAM
movx A,@R0 ;читать байт XRAM
call Hexout ;отобразить байт
call Prob ;отобразить межбайтовый пробел
inc R0 ;следующий адрес XRAM
movx A,@R0 ;читать байт XRAM
call Hexout ;отобразить байт
jmp EXitf ;выход с очисткой Knobf
W_Wm11: db 080h,"12.Слово режима", 0ffh, 0c0h,"работы", 0ffh, 0d4h, 0
; Флаги текущих неисправностей
Flags: mov dptr,#Flgm11 ;сообщение: 080h,"14.Флаги текущих",
call Outstr ;0ffh, 0c0h,"неисправностей", 0
mov A,#0d4h+4 ;установить
call WrCOM ;курсор
mov R0,#12h+7 ;10h адрес ответа ЭБУ в XRAM
LoadR1: movx A,@R0 ;читать байт XRAM
call Hexout ;отобразить байт
call Prob ;отобразить межбайтовый пробел
inc R0 ;следующий адрес XRAM
cjne R0,#12h+7+4,LoadR1;цикл отображения четырех байт
jmp EXitf ;выход с очисткой Knobf
Flgm11: db 080h,"13.Флаги текущих", 0ffh, 0c0h,"неисправностей", 0
; Соотношение воздух/топливо
VT: mov dptr,#VT1 ;сообщение: 080h,"15.Соотношение", 0ffh, 0c0h,
call Outstr ;"воздух / топливо", 0ffh, 0d4h,"N= «, 0
mov R0,#12h+12 ;формула N=14.7*(E+128)/256
movx A,@R0 ;= 147*(E+128)/2560
add A,#128 ;добавить 128 (E+128)
mov r0, A ;множимое младший байт
mov A,#0 ;добавить перенос в старший байт
addc A,#0 ;R1:R0 = (ACC + 128)
mov r1, A ;множимое старший байт
mov r2,#147 ;множитель младший байт
mov r3,#0 ;множитель старший байт
call UMUL16 ;R3:R2:R1:R0 = R1: R0 x R3: R2
mov r2,#00h ;делитель младший байт
mov r3,#0ah ;делитель старший байт = 2560
mov r7,#4 ;число знаков после запятой
call Float ;деление с отображением
call CLRstr ;вывод четырех пробелов без адресации курсора
jmp EXitf ;выход с очисткой Knobf
VT1: db 080h,"14.Соотношение», 0ffh, 0c0h,"воздух/топливо", 0ffh, 0d4h,"N = «, 0
;Подпрограмма проверки ответа от ЭБУ. Входные данные: B
;индентификатор запроса с установленым 6 м битом, R0 начальный адрес
;буфера приема XRAM, Выходные данные: ComState не меняется прием правильный
;ComState = 1XXXXXXXB, где XX код ошибки
V_Frame: push psw ;проверка ответа от ЭБУ:
push acc ;сохранить
push 0 ;изменяемые
push 1 ;pегистpы
push B;
mov ComState,#0 ;ComState = 0 прием правильный
movx A,@R0 ;[R0+0] = 10XXXXXXB первый байт ответа от ЭБУ
jnb acc.7,V_F2 ;бит 7 должен быть равен 1
jb acc.6,V_F2 ;бит 6 должен быть равен 0
mov R1,#1 ;смещение для трехбайтового заголовка = 1
anl A,#00001111b ;интересует младший ниббл
jnz V_F0 ;младший ниббл <> 0 заголовок трехбайтовый
inc R1 ;иначе смещение для четырехбайтового заголовка = 2
V_F0: inc R0 ;адресовать второй байт ответа ЭБУ в XRAM
movx A,@R0 ;[R0+1] = F1h второй байт ответа от ЭБУ
cjne A,#0f1h, V_F2 ;не совпадает ошибка приема фрейма
inc R0 ;адресовать третий байт ответа ЭБУ в XRAM
movx A,@R0 ;[R0+2] = 10h адрес ЭБУ на шине K Line
cjne A,#10h, V_F2 ;не совпадает ошибка приема фрейма
mov A, R0 ;адресовать R0 на первый байт данных:
add A, R1 ;добавить смещение 1 для трехбайтового заголовка
mov R0, A ;и 2 для четырехбайтового заголовка
movx A,@R0 ;[R0+0] идентификатоp запpоса
cjne A, B, V_F1 ;в B индентификатор запроса с установленым 6 м битом
jmp V_F3 ;АСС = B прием правильный
V_F1: cjne A,#7fh, V_F2 ;7Fh признак отpицательного ответа
inc R0 ;[R0+1] индентификатор запроса
movx A,@R0;
anl B,#10111111b ;сбросить шестой бит
cjne A, B, V_F2 ;АСС <> B ошибка приема фрейма
inc R0 ;[R0+2] код ошибки
movx A,@R0;
mov ComState, A ;вернуть код ошибки
jmp V_F21 ;выход с ComState = 1XXXXXXXB XX код ошибки
V_F2: mov ComState,#55h ;55h неопределенная ошибка
V_F21: mov W_Start,#0 ;инициировать старт
V_F3: pop B ;восстановить
pop 1 ;изменяемые
pop 0 ;регистры
pop acc;
pop psw;
ret;
EnumER: push acc ;подпрограмма декодирования кодов ответа:
push psw ;сохранить
push dph ;изменяемые
push dpl ;pегистpы
mov dptr,#Errm39 ;1,0ffh, 0c0h,"Ошибка: «, 0
call Outstr ;отобразить сообщение
call Hexout ;ComState = 0XXXXXXXB, где XX код ошибки
mov dptr,#Errm30 ;по умолчанию: 094h,"Неизвестная ошибка», 0
cjne A,#10h, Enum1;
mov dptr,#Errm31 ;094h,"Запрос отклонен", 0
Enum1: cjne A,#11h, Enum2;
mov dptr,#Errm32 ;094h,"Неправильный запрос", 0
Enum2: cjne A,#12h, Enum3;
mov dptr,#Errm33 ;094h,"Неправильный", 0FFh, 0d4h,"аргумент", 0
Enum3: cjne A,#21h, Enum4;
mov dptr,#Errm34 ;094h,"Приемник занят", 0
Enum4: cjne A,#31h, Enum5;
mov dptr,#Errm35 ;094h,"Неправильное", 0FFh, 0d4h,"значение", 0
Enum5: cjne A,#72h, Enum6;
mov dptr,#Errm36 ;094h,"Связь прервана", 0
Enum6: cjne A,#77h, Enum7;
mov dptr,#Errm37 ;094h,"Несоответствие к/с", 0
Enum7: cjne A,#55h, Enum8;
mov dptr,#Errm38 ;094h,"Нет ответа от ЭБУ", 0
Enum8: call Outstr ;отобразить сообщение
pop dpl ;восстановить
pop dph ;изменяемые
pop psw ;pегистpы
pop acc;
ret;