Читаем Занимательная микроэлектроника полностью

Листинг П5.2

;ATmega853 5 кварц 4000 кГц

.include "m8535def.inc"

;==== Определения и константы ====

;Управление индикацией

.equ segG = 6  ;port С pin 28

.equ segF = 5  ;pin 27

.equ segE = 4  ;pin 26

.equ segD = 3  ;pin 25

.equ segC = 2  ;pin 24

.equ segB = 1  ;pin 23

.equ segA = 0  ;pin 22

.equ RazrTdH = 0  ;PortB,0 pin 1 десятки градуса

.equ RazrTdM = 1  ;PortB,1 pin 2 ед. градусов

.equ RazrTdL = 2  ;PortB,2 pin 3 десятые градусов

.equ RazrPdH = 3  ;PortB,3 pin 4 сотни давления

.equ RazrPdM = 4  ;PortB,4 pin 5 дес. давления

.equ RazrPdL = 5  ;PortB,5 pin 6 ед. давления

;адреса SRAM старший байт адреса SRAM=0x01

.equ Tram =: 0x0  ;0x0,0x1 — старш. и младш. байты температуры АЦП

.equ Pram =: 0x2  ;0x2,0x3 — старш. и младший, байты давления АЦП

.equ TdH = 0x04  ;температура старший дес.

.equ TdM = 0x05  ;темп. средний дес.

.equ TdL = 0x06  ;темп. младший дес.

.equ PdH = 0x07  ;давление старший дес.

.equ PdM = 0x08  ;давление средний дес.

.equ PdL = 0x09  ;давление младший дес.

.equ tZH = 0x20  ;ст. разряд коэффициента Z температуры

.equ tZL = 0x21  ;мл. разряд коэффициента Z температуры

.equ tKH = 0x22  ;ст. разряд коэффициента К температуры

.equ tKL = 0x23  ;мл. разряд коэффициента К температуры

.equ pZH = 0x24  ;ст. разряд коэффициента Z давления

.equ pZL = 0x25  ;мл. разряд коэффициента Z давления

.equ pKH = 0x26  ;ст. разряд коэффициента К давления

.equ pKL = 0x27  ;мл. разряд коэффициента К давления

.equ AtBCDO = 5  ;адрес ResL для процедуры преобразования Bin-Dee

.equ AtBCD2 = 6  ;адрес ResH

;переменные

.def AregH = r2  ;результат измерения hex, старший байт

.def AregL = r3  ;результат измерения hex, младший байт

.def KoeffH = r4  ;коэффициент, старший байт

.def KoeffL = r5  ;коэффициент, младший байт

.def ResL = r6  ;результат упакованный BCD, младший байт

.def ResH = r7  ;результат упакованный BCD, старший байт

.def temp = r16  ;рабочий регистр

.def temp1 = r17  ;вспомогательная переменная

.def temp2 = r18  ;вспомогательная переменная

.def count = r19  ;счетчик преобразований — до 64

.def countCyk = r20  ;счетчик до 32,

.def Flag = r21  ;регистр флагов, биты:

;измерение: 0 — температуры, 1 — давления,

.def cRazr = г22  ;счетчик до 6 мультиплексирования разрядов

;====== прерывания ======

rjmp RESET  ;Reset Handle

        reti  ;IRQ0 Handler

        reti  ;IRQ1 Handler

        reti  ;Timer2 Compare Handler

        reti  ;Timer2 Overflow Handler

        reti  ;Timer1 Capture Handler

        reti  ;Timer1 Compare A Handler

        reti  ;Timer1 Compare В Handler

        reti  ;TIM1_OVF  ;Timer1 Overflow Handler

rjmp TIM0  ;Timer0 Overflow Handler

        reti  ;SPI Transfer Complete Handler

        reti  ;USART RX Complete Handler

        reti  ;UDR Empty Handler

        reti  ;USART TX Complete Handler

rjmp readADC  ;reti;ADC  ;ADC Conversion Complete Handler

        reti  ;EEPROM Ready Handler

          reti  ;Analog Comparator Handler

          reti  ;Two-wire Serial Interface Handler

          reti  ;IRQ2 Handler

          reti  ;Timer0 Compare Handler

reti  ;Store Program Memory Ready Handler

;==================

OUT_N:  ;маски цифр

.db

0b00111111,0b0000110,0b01011011,0b01001111,0b01100110,0b01101101, 0b01111101,0b00000111,0b01111111,0b01101111

;seg ABCDEF(0);seg BC(1);seg ABDEG(2);seg ABCDG(3);seg BCFG(4);seg ACDFG(5)

;seg ACDEFG(6);seg ABC(7);seg ABCDEFG(8);seg ABCDFG(9)

TIM0:

;сначала индикация

          inc cRazr  ;счетчик разрядов

          cpi cRazr,6  ;всего б разрядов

          brne Set_razr

          clr cRazr  ;если равен 6, очищаем

Set_razr:

          cpi cRazr,0  ;десятки градусов

          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  ;умножаем старший на старший

           add temp2,r0  ;4-й разряд нам тут не требуется, но он в r01

ret

bin2BCD16:  ;преобразование 16-разрядного hex в упакованный BCD

;input: hex value low=AregL hex value high = AregH

;output: BCD value digits 1 and 0 ResL

;BCD value digits 2 and 3(=0) ResH

           ldi tempi,16  ;Init loop counter

           clr ResH

           clr ResL

           clr ZH  ;clear ZH (not needed for AT90Sxx0x)

bBCDx_1: lsl AregL  ;shift input value

            rol AregH  ;through all bytes

            rol ResL;

            rol ResH

            dec temp1  ;decrement loop counter

            brne bBCDx_2  ;if counter not zero

            ret  ;return

bBCDx_2:ldi r30,AtBCD2+1  ;Z points to result MSB + 1

bBCDx_3:

            ld temp, — Z  ;get (Z) with pre-decrement

            subi temp, — $03  ;add 0x03

            sbrc temp,3  ;if bit 3 not clear

            st Z, temp  ;store back

            ld temp, Z  ;get (Z)

            subi temp, — $30  ;add 0x30

            sbrc temp, 7  ;if bit 7 not clear

            st Z,temp  ;store back

            cpi ZL,AtBCDO  ;done all three?

            brne bBCDx_3  ;loop again if not

            rjmp bBCDx_1

bin2bcd8:  ;преобразование 8-разрядного hex в неупакованный BCD

;вход hex= temp, выход BCD temp1 — старш.; temp — младш.

;эта процедура работает только для исходного меньше 100

            clr tempi  ;clear result MSD

bBCD8_1: subi temp,10  ;input = input — 10

            brcs bBCD8_2  ;abort if carry set

            inc temp1  ;inc MSD

            rjmp bBCD8_1  ;loop again

bBCD8_2:subi temp, — 10  ;compensate extra subtraction

ret

RESET:  ;точка запуска программы после включения

            ldi temp,low(RAMEND)  ;загрузка указателя стека

            out SPL,temp

            ldi temp,high(RAMEND)  ;загрузка указателя стека

            out SPH,temp

            ldi temp,1<

            out ACSR,temp  ;выкл. аналог, компаратор на всякий

;установка портов вход-выход

            ldi temp,0b00111111  ;разряды

            out DDRB,temp

            ldi temp,0b01111111  ;сегменты

            out DDRC,temp

            ldi temp,0b10000000  ;знак "минус"

            out DDRD,temp

;установка АЦП

            ldi temp, 1<

            ;start ADC 1/32 такт = 128 кГц  ;interrupt enable

            out ADCSRA,temp

;установка таймера

             ldi temp,0b00000010

             out TCCR0,temp

             ;Timer0 on div 1:8 управление разрядами 2000 Гц

;прерывания

             ldi temp,(1<  ;разр. прер. Timer 0

             out TIMSK,temp

             ldi temp,255  ;сбросить все прерывательные флаги

             out TIFR,temp

             out GIFR,temp

;начальная установка переменных

             ldi r29,1  ;YH=1, пишем в RAM, начиная с 01:00

             clr count

             clr countCyk

             clr cRazr

             clr Flag

             sbr Flag,0x01  ; сначала измеряем температуру

;обнуление рабочих ячеек

             clr temp

             ldi r28,Tram  ;Tempr

             st Y+,temp

             st Y,temp

             ldi r2 8,Pram  ;Prs

             st Y+,temp

             st Y,temp

;запись коэффициентов

             ldi r28,tZH  ;начальный адрес

;Z Tempr=471

             ldi temp,High(471)  ;ст.

             st Y+,temp

             ldi temp,Low(471)  ;мл.

             st Y+,temp

;К Tempr=1020

            ldi temp,High(1020)  ;ст.

            st Y+,temp

            ldi temp,Low(1020)  ;мл.

            st Y+,temp

;Z prs=12

            ldi temp,High(12)  ;ст. на самом деле = 0

            st Y+,temp

            ldi temp,Low(12)  ;мл.

            st Y+,temp

;К prs=916

            ldi temp,High(916)  ;ст.

            st Y+,temp

            ldi temp,Low(916)  ;мл.

            st Y,temp

sei  ;разрешаем прерывания

G_cykle:  ;основной цикл

            rjmp G_cykle

Перейти на страницу:

Похожие книги

Электроника для начинающих (2-е издание)
Электроника для начинающих (2-е издание)

В ходе практических экспериментов рассмотрены основы электроники и показано, как проектировать, отлаживать и изготавливать электронные устройства в домашних условиях. Материал излагается последовательно от простого к сложному, начиная с простых опытов с электрическим током и заканчивая созданием сложных устройств с использованием транзисторов и микроконтроллеров. Описаны основные законы электроники, а также принципы функционирования различных электронных компонентов. Показано, как изготовить охранную сигнализацию, елочные огни, электронные украшения, устройство преобразования звука, кодовый замок и др. Приведены пошаговые инструкции и более 500 наглядных рисунков и фотографий. Во втором издании существенно переработан текст книги, в экспериментах используются более доступные электронные компоненты, добавлены новые проекты, в том числе с контроллером Arduino.

Чарльз Платт

Радиоэлектроника / Технические науки
Электроника для начинающих
Электроника для начинающих

В ходе практических экспериментов рассмотрены основы электроники и показано, как проектировать, отлаживать и изготавливать электронные устройства в домашних условиях. Материал излагается последовательно от простого к сложному, начиная с простых опытов с электрическим током и заканчивая созданием сложных устройств с использованием транзисторов и микроконтроллеров. Описаны основные законы электроники, а также принципы функционирования различных электронных компонентов. Показано, как изготовить охранную сигнализацию для защиты от проникновения в дом, елочные огни, электронные украшения для одежды, устройство преобразования звука, кодовый замок, автономную роботизированную тележку и др. Приведены пошаговые инструкции и более 500 наглядных рисунков и фотографий.Для начинающих радиолюбителей

Паоло Аливерти , Чарльз Платт

Радиоэлектроника / Технические науки
Искусство схемотехники. Том 3 (Изд.4-е)
Искусство схемотехники. Том 3 (Изд.4-е)

Широко известная читателю по предыдущим изданиям монография известных американских специалистов посвящена быстро развивающимся областям электроники. В ней приведены наиболее интересные технические решения, а также анализируются ошибки разработчиков аппаратуры: внимание читателя сосредотачивается на тонких аспектах проектирования и применения электронных схем. На русском языке издается в трех томах. Том 3 содержит сведения о микропроцессорах, радиотехнических схемах, методах измерения и обработки сигналов, принципах конструирования аппаратуры и проектирования маломощных устройств, а также обширные приложения. Для специалистов в области электроники, автоматики, вычислительной техники, а также студентов соответствующих специальностей вузов и техникумов.

Пауль Хоровиц , Уинфилд Хилл

Техника / Радиоэлектроника