Занимательная микроэлектроника — страница 112 из 117

  ;десятки градусов

brne Р1  ;если нет — на другие разряды

ldi r28,TdH  ;установка YL — старш. темп.

  ld temp,Y  ;в temp — значение десятков градусов

   ldi ZH,HIGH(OUT_N*2)  ;адрес констант в памяти — в Z

  ldi ZL,LOW(OUT_N*2)

                 add ZL,temp  ;адрес маски цифры, равной temp

lpm  ;в r0 — маска

   out PortC,r0  ;установили сегменты

  ldi temp,1<  ;устанавливаем разряд

     out PORTB,temp  ;установили разряды

  rjmp rADC

P1:

          cpi cRazr,1  ;единицы град

brne P2

          ldi r2 8,TdM  ;установка адреса — ср. темп.

ld temp,Y

          ldi ZH,HIGH()UT_N*2)

                 ldi ZL,LOW(OUT_N* 2)

                 add ZL,temp

                 lpm

out PortC,r0  ;установили сегменты

ldi temp,1<  ;устанавливаем разряд

out PORTB,temp  ;установили разряды rjmp rADC


P2:

          cpi cRazr,2  ;дробные град

brne P3

          ldi r2 8,TdL  ;установка Y — мл. темп.

ld temp,Y

          ldi ZH,HIGH(OUT_N* 2)

                ldi ZL,LOW(OUT_N*2)

                add ZL,temp

                lpm

          out PortC,r0  ;установили сегменты

ldi temp,1<  ;устанавливаем разряд

out PORTB,temp  ;установили разряды

rjmp rADC

Р3:

          cpi cRazr,3  ;сотни давления

brne Р4

          ldi r28,PdH  ;установка Y — сотн. prs

  ld temp,Y

          ldi ZH,HIGH(OUT_N*2)

                ldi ZL,LOW(OUT_N*2)

                add ZL,temp

                lpm

          out PortC, r0  ;установили сегменты

ldi temp,1<  ;устанавливаем разряд

out PORTB,temp  ;установили разряды

rjmp rADC

P4:

          cpi    cRazr,4  ;десятки давления

brne P5

          ldi r2 8,PdM  ;установка Y — дес. prs

ld temp,Y

          ldi ZH,HIGH(OUT_N*2)

          ldi ZL,LOW(OUT_N*2)

          add ZL,temp

          lpm

          out PortC,r0  ;установили сегменты

ldi temp,1<  ;устанавливаем разряд

out PORTB,temp  ;установили разряды

rjmp rADC

P5:

           cpi    cRazr,5  ;единицы давления

brne rADC

           ldi r28,PdL  ;установка Y — ед. prs

ld temp,Y

           ldi ZH,HIGH(OUT_N*2)

           ldi ZL,LOW(OUT_N*2)

           add ZL,temp

           lpm

           out PortC,r0  ;установили сегменты

 ldi temp,1<  ;устанавливаем разряд

out PORTB,temp  ;установили разряды


rADC:   inc countCyk  ;обработка АЦП

sbrs countCyk,5  ;если бит 5 в countCyk равен 1, то прошло 32 такта таймера 0, будем запускать АЦП (см. readADC)

reti

            clr countCyk

            inc count

            cpi count,65  ;если прошло 64 чтения, то сразу на обработку

breq endADC

            sbrc Flag,0  ;если бит 0 флага — читаем температуру

ldi temp,0

            sbrc Flag,1  ;если бит 1 флага — читаем давление

ldi temp,1

            out ADMUX, temp  ;установили АЦП канал

sbi ADCSRA, ADSC  ;запуск новое преобразование

reti


endADC:

;расчет по 64 значениям

clr count

            sbrc Flag,0

            ldi r28,Tram  ;установка адреса — T

sbrc Flag,1

            ldi r28,Pram  ;установка адреса — P

ld AregH,Y+  ;загрузка суммы из памяти

ld AregL,Y

div64L:  ;деление на 64

lsr AregH  ;сдвинули старший

 ror AregL  ;сдвинули младший

inc count

            cpi count,6

            brne div64L  ;сдвинули-поделили на 64


subi r28,1  ;в Y опять адрес Tram или Pram

clr temp

             st Y+,temp

             st Y,temp  ;очистили память для следующего цикла


sbrs Flag,0  ;расчет температуры

rjmp prs  ;иначе давления

 ldi r28,tZH  ;установка адреса коэфф. Z

ld temp,Y+

                  mov KoeffH,temp

                  ld temp,Y

                  mov KoeffL,temp  ;получили коэфф. Z температуры


;вычисление знака:

ср AregL,KoeffL

                          срс AregH,KoeffH

                          brsh b0

                          sub KoeffL,AregL

                          sbc KoeffH,AregH

                          mov AregL,KoeffL

                          mov AregH,KoeffH

                          sbi PortD,7  ;знак —

rjmp m0


Ь0:  ;если больше

sub AregL,KoeffL

                          sbc AregH,KoeffH

                          cbi PortD,7  ;знак +


m0:  ;умножение на коэфф. К

ldi r28,tKH  ;установка адреса коэфф. К

ld temp,Y+

                          mov KoeffH,temp

                          ld temp,Y

                          mov KoeffL,temp  ;получили К температуры

rcall Mp16  ;умножили

             ;деление на 1024

mov AregL,temp1

                   mov AregH,temp2  ;на 2 56

lsr AregH  ;сдвинули старший

ror AregL  ;сдвинули младший

lsr AregH  ;сдвинули старший

ror AregL  ;сдвинули младший; еще на 4

rjmp contPT

prs:

            sbrs Flag,1  ;расчет давления

rjmp contPT

                   ldi r28,pZH  ;установка адреса коэфф. Z

ld temp,Y+

                   mov KoeffH,temp

                   ld temp,Y

                   mov KoeffL,temp  ;получили коэфф. Z давления


adc AregL,KoeffL

                        add AregH,KoeffH  ;прибавили к величине


ldi r28,pKH  ;установка адреса коэфф. К

ld temp,Y+ mov

                        KoeffH,temp

                        ld temp,Y

                        mov KoeffL,temp  ;получили коэфф. К давления

rcall Мр16  ;умножили

               ;деление на 1024

  mov AregL,temp1

                        mov AregH,temp2  ;на 256

lsr AregH  ;сдвинули старший

ror AregL  ;сдвинули младший

lsr AregH  ;сдвинули старший

ror AregL  ;сдвинули младший; еще на 4


contPT:


             sbrc Flag,0

             ldi r28,TdH  ;установка адреса — T

sbrc Flag,1

             ldi r28,PdH  ;установка адреса — P

rcall bin2BCD16  ;преобраз в дв. дес.

st Y+,ResH  ;запоминаем в памяти старший BCD

mov temp,ResL  ;младший распаковываем

swap temp

                    andi temp,0b00001111

             st Y+,temp

             mov temp,ResL

             andi temp,0b00001111

             st Y,temp  ;и тоже сохраняем в памяти

;установка флагов и переменных для следующего цикла

clr count

             sbrc Flag,0

             rjmp _F0

             clr Flag

             sbr Flag,0x1  ;был бит 1, устанавливаем бит 0

reti

_F0:

             clr Flag  ;был бит 0, устанавливаем бит 1

sbr Flag,0x2

reti  ;TIME0


readADC:  ;чтение АЦП по прерыванию

sbrc Flag,0

              ldi r28,Tram  ;установка адреса — T

sbrc Flag,1

              ldi r28,Pram  ;установка адреса — P

ld AregH,Y+

              ld AregL,Y

              in temp1,ADCL  ;получаем младший

in temp,ADCH  ;старший

add AregL,tempi  ;суммируем

adc AregH,temp

              dec r28

              st Y+,AregH  ;запоминаем сумму

st Y,AregL  ;в памяти

reti  ;ADC


Мр16:  ;умножение двух 16-разрядных величин

;AregL multiplicand low byte

;AregH multiplicand high byte

;KoeffL multiplier low byte

;KoeffH multiplier high byte

;temp result byte 0 (LSB)

;tempi result byte 1

;temp2 result byte 2

  clr temp2  ;очистить ставший

mul AregL,KoeffL  ;умножаем младшие

mov temp,r0  ;в r0 младший результата операции mul

mov temp1,r1  ;в r01 старший результата операции mul

mul AregH,KoeffL  ;умножаем старший на младший

add tempi,r0  ;в r младший результата операции mul

 adc temp2,r1  ;в r01 старший результата операции mul

  mul AregL,KoeffH  ;умножаем младший на старший

add temp1,r0  ;в r0 младший результата операции mul

adc temp2,r1  ;в r01 старший результата операции mul

mul AregH,KoeffH