Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
doc:1201:643.mgul.12013-01_12_01 [2017/02/14 03:01] gotrum |
doc:1201:643.mgul.12013-01_12_01 [2018/04/28 23:47] (текущий) |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | | Александр Викторович,\\ я попробовал добавить текст программы в виде файла,\\ чтобы не загромождать страницу,\\ но dokuwiki ругается на недопустимое расширение файла | | + | |
- | **АННОТАЦИЯ** | + | ====Аннотация==== |
В данном программном документе приведен текст программы «telemetry_rev1-1», предназначенной для опроса телеметрических датчиков, подключенных к микроконтроллеру Atmel Atmega328P, и отправки полученных данных по последовательному порту на бортовую ЭВМ. Текст программы реализован в виде символической записи на языке ассемблера AVR. Компилятором является консольная программа для UNIX-подобных операционных систем - avra. | В данном программном документе приведен текст программы «telemetry_rev1-1», предназначенной для опроса телеметрических датчиков, подключенных к микроконтроллеру Atmel Atmega328P, и отправки полученных данных по последовательному порту на бортовую ЭВМ. Текст программы реализован в виде символической записи на языке ассемблера AVR. Компилятором является консольная программа для UNIX-подобных операционных систем - avra. | ||
Строка 24: | Строка 24: | ||
*m328Pdef.inc - объявление имен регистров и ячеек памяти. | *m328Pdef.inc - объявление имен регистров и ячеек памяти. | ||
- | **1. Текст программы telemetry_rev1-1.asm на языке ассемблера AVR** | + | ====Текст программы telemetry_rev1-1.asm==== |
- | <file asm telemetry_rev1-1.asm> | + | <hidden развернуть> |
- | ;-------------------------------------------------------------------------------------------------------------- | + | <code asm> |
- | ; Program : telemetry_rev1-1 | + | ;---------------------------------------------------- |
- | ; Compiler : AVRA | + | ; Program : telemetry_rev1-1 |
- | ; Chip type : ATmega328P | + | ; Compiler : AVRA |
- | ; System Clock : 16 MHz | + | ; Chip type : ATmega328P |
- | ; Date : 18.01.2017 | + | ; System Clock : 16 MHz |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ; Date : 18.01.2017 |
- | + | ;-------------------------------------------------------------------------------------------------------------- | |
- | ;Подключение библиотек и резервация места под данные | + | |
- | .include "m328Pdef.inc " | + | ;Подключение библиотек и резервация места под данные |
- | + | .include "m328Pdef.inc " | |
- | .dseg | + | |
- | adc_data: | + | .dseg |
- | .byte8 | + | adc_data: |
- | Trm:; Ячейки ОЗУ под показания датчиков DS18B20 | + | .byte8 |
- | .byte14 | + | Trm:; Ячейки ОЗУ под показания датчиков DS18B20 |
- | bmp_temp:; Ячейки ОЗУ под показания темп. датчика BMP180 | + | .byte14 |
- | .byte2 | + | bmp_temp:; Ячейки ОЗУ под показания темп. датчика BMP180 |
- | bmp_pres:; Ячейки ОЗУ под показания давления датчика BMP180 | + | |
.byte2 | .byte2 | ||
- | bh_lux: | + | bmp_pres:; Ячейки ОЗУ под показания давления датчика BMP180 |
- | .byte2 | + | .byte2 |
- | + | bh_lux: | |
- | .cseg | + | .byte2 |
- | .include "iterrupts.asm"; Библиотека векторов прерываний | + | |
- | .include "macr.asm"; Библиотека макросов | + | .cseg |
- | .include "twi_lib.asm"; Библиотека работы шины TWI | + | .include "iterrupts.asm"; Библиотека векторов прерываний |
- | .include "hextobcd.asm"; Библиотека перевода чисел в неупаковынный 2-10 код | + | .include "macr.asm"; Библиотека макросов |
- | .include "1wire.asm"; Библиотека 1-wire устройств | + | .include "twi_lib.asm"; Библиотека работы шины TWI |
- | ;-------------------------------------------------------------------------------------------------------------- | + | .include "hextobcd.asm"; Библиотека перевода чисел в неупакованный 2-10 код |
- | + | .include "1wire.asm"; Библиотека 1-wire устройств | |
- | RESET: | + | ;-------------------------------------------------------------------------------------------------------------- |
- | + | ||
- | ;Начальная_инициализация | + | RESET: |
- | ;-------------------------------------------------------------------------------------------------------------- | + | |
- | + | ;Начальная_инициализация | |
- | ldi R16, Low(RAMEND); Инициализация стека | + | ;-------------------------------------------------------------------------------------------------------------- |
- | outSPL, R16 | + | |
- | ldiR16, High(RAMEND) | + | ldi R16, Low(RAMEND); Инициализация стека |
- | out SPH, R16 | + | out SPL, R16 |
- | + | ldi R16, High(RAMEND) | |
- | .deftry = r21 | + | out SPH, R16 |
- | .deftemp = r16 | + | |
- | .def razr1 = r17 | + | .def try = r21 |
- | .def razr2 = r18 | + | .def temp = r16 |
- | .def razr3 = r19 | + | .def razr1 = r17 |
- | + | .def razr2 = r18 | |
- | + | .def razr3 = r19 | |
- | .equ W1_DDR = DDRB ; Присваиваем псевдоним регистрам порта датчиков DS18B20 | + | |
- | .equ W1_PORT = PORTB | + | |
- | .equW1_PIN = PINB | + | .equ W1_DDR = DDRB ; Присваиваем псевдоним регистрам порта датчиков DS18B20 |
- | .equ W1_BIT = 0 ; Бит порта на котором датчики (8 цифровой контакт на плате Ардуино) | + | .equ W1_PORT = PORTB |
- | + | .equ W1_PIN = PINB | |
- | .equ FREQ = 16000000 ; Частота процессора | + | .equ W1_BIT = 0 ; Бит порта на котором датчики (8 цифровой контакт на плате Ардуино) |
- | .equ baudrate = 38400; Расчитываем делитель бодрейта для UART | + | |
- | .equ bauddivider = FREQ/(16*baudrate)-1 | + | .equ FREQ = 16000000 ; Частота процессора |
- | .equFreqSCL = 200000; Расчитываем частоту работы шины TWI | + | .equ baudrate = 38400; Рассчитываем делитель бодрейта для UART |
- | .equFreqTWBR = ((FREQ/FreqSCL)-16)/2 | + | .equ bauddivider = FREQ/(16*baudrate)-1 |
- | + | .equ FreqSCL = 200000; Рассчитываем частоту работы шины TWI | |
- | ldi R16, low(bauddivider); Инициализация UART | + | .equ FreqTWBR = ((FREQ/FreqSCL)-16)/2 |
- | sts UBRR0L,R16 | + | |
- | ldi R16, high(bauddivider) | + | ldi R16, low(bauddivider); Инициализация UART |
- | sts UBRR0H,R16 | + | sts UBRR0L,R16 |
- | + | ldi R16, high(bauddivider) | |
- | ldi R16,0 | + | sts UBRR0H,R16 |
- | sts UCSR0A, R16 | + | |
- | sts UCSR0B, R16 | + | ldi R16,0 |
- | sts UCSR0C, R16 | + | sts UCSR0A, R16 |
- | + | sts UCSR0B, R16 | |
- | LDI R16, (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0) | + | sts UCSR0C, R16 |
- | sts UCSR0B, R16 | + | |
- | ldi r16,0 | + | LDI R16, (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0) |
- | + | sts UCSR0B, R16 | |
- | LDI R16, (0<<USBS0)|(0<<UMSEL0)|(0<<UMSEL1)|(1<<UCSZ00)|(1<<UCSZ01) | + | ldi r16,0 |
- | sts UCSR0C, R16 | + | |
- | + | LDI R16, (0<<USBS0)|(0<<UMSEL0)|(0<<UMSEL1)|(1<<UCSZ00)|(1<<UCSZ01) | |
- | + | sts UCSR0C, R16 | |
- | ldi r16,0b01000000; Инициализация АЦП | + | |
- | sts ADMUX,r16 | + | |
- | ldi r16,0b11011111 | + | ldi r16,0b01000000; Инициализация АЦП |
- | sts ADCSRA,r16 | + | sts ADMUX,r16 |
- | ldi r25,0 | + | ldi r16,0b11011111 |
- | + | sts ADCSRA,r16 | |
- | rcall W1_Sbros; Сбрасываем шину 1-Wire | + | ldi r25,0 |
- | rcall W1_Init_12bit; Перестраиваем конфигурационный байт на 12 битную схему работы | + | |
- | rcall W1_Sbros; Вновь сбрасываем | + | rcall W1_Sbros; Сбрасываем шину 1-Wire |
- | + | rcall W1_Init_12bit; Перестраиваем конфигурационный байт на 12 битную схему работы | |
- | ldi r16,0b00000101; Инициализация работы прерывания по таймеру для отправки показаний | + | rcall W1_Sbros; Вновь сбрасываем |
- | sts TCCR2B,r16; датчиков DS18B20 по шине 1-Wire | + | |
- | ldi r16,0b00000001 | + | ldi r16,0b00000101; Инициализация работы прерывания по таймеру для отправки показаний |
- | sts TIMSK2,r16 | + | sts TCCR2B,r16; датчиков DS18B20 по шине 1-Wire |
- | sts TIFR2,r16 | + | ldi r16,0b00000001 |
- | ldi r16,0xF0 | + | sts TIMSK2,r16 |
- | sts TCNT2,r16 | + | sts TIFR2,r16 |
- | + | ldi r16,0xF0 | |
- | ldi r16,0b00000101; Инициализация работы прерывания по таймеру для отправки показаний | + | sts TCNT2,r16 |
- | sts TCCR1B,r16; датчиков DS18B20 по шине 1-Wire | + | |
- | ldi r16,0b00000001 | + | ldi r16,0b00000101; Инициализация работы прерывания по таймеру для отправки показаний |
- | sts TIMSK1,r16 | + | sts TCCR1B,r16; датчиков DS18B20 по шине 1-Wire |
- | sts TIFR1,r16 | + | ldi r16,0b00000001 |
- | ldi r16,0xA0 | + | sts TIMSK1,r16 |
- | sts TCNT1H,temp | + | sts TIFR1,r16 |
- | sts TCNT1L,temp | + | ldi r16,0xA0 |
- | + | sts TCNT1H,temp | |
- | ldi R16, 0b00110000; Инициализация шины TWI | + | sts TCNT1L,temp |
+ | |||
+ | ldi R16, 0b00110000; Инициализация шины TWI | ||
out PORTC, R16 | out PORTC, R16 | ||
- | ldi r16,FreqTWBR | + | ldi r16,FreqTWBR |
- | sts TWBR,r16 | + | sts TWBR,r16 |
- | ldi r16,0x00 | + | ldi r16,0x00 |
- | sts TWSR,r16 | + | sts TWSR,r16 |
- | + | ||
- | clr try | + | clr try |
- | clr r2 | + | clr r2 |
- | clr r3 | + | clr r3 |
- | clr r4 | + | clr r4 |
- | clr r5 | + | clr r5 |
- | ldi r24,0x00 | + | ldi r24,0x00 |
- | ldi R16, 0b00000000 | + | ldi R16, 0b00000000 |
- | out PORTD, R16 | + | out PORTD, R16 |
- | + | ||
- | ldi R16, 0b00000100 | + | ldi R16, 0b00000100 |
- | out DDRD, R16 | + | out DDRD, R16 |
- | + | ||
- | rcall i2c_start | + | rcall i2c_start |
- | ldi r16,0x46; Если нет, то остаемся этой процедуре | + | ldi r16,0x46; Если нет, то остаемся этой процедуре |
- | rcall i2c_send | + | rcall i2c_send |
- | ldi r16,0x11 | + | ldi r16,0x11 |
- | rcall i2c_send | + | rcall i2c_send |
- | rcall i2c_stop | + | rcall i2c_stop |
- | sei; Разрешаем прерывания | + | sei; Разрешаем прерывания |
- | rjmp main | + | rjmp main |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | ;Конец_начальной_инициализации | + | ;Конец_начальной_инициализации |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | ;Основная_подпрограмма | + | ;Основная_подпрограмма |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | + | ||
- | + | ||
- | main: | + | main: |
- | cli; Запрещаем прерывания в основном цикле | + | cli; Запрещаем прерывания в основном цикле |
- | push r | + | push r |
- | mov r17,r5 | + | mov r17,r5 |
- | mov r16,r4 | + | mov r16,r4 |
- | rcall bin2ASCII15 | + | rcall bin2ASCII15 |
- | mov r17,r3 | + | mov r17,r3 |
- | mov r16,r2 | + | mov r16,r2 |
- | rcall bin2ASCII15 | + | rcall bin2ASCII15 |
- | popr | + | popr |
- | tabulate | + | tabulate |
- | + | ||
- | rcall W1_ConvTemp; Говорим датчикам конвертировать температуры | + | rcall W1_ConvTemp; Говорим датчикам конвертировать температуры |
- | + | ||
- | push r16 | + | push r16 |
- | lds r16,bh_lux+1 | + | lds r16,bh_lux+1 |
- | cpi r16,0x82 | + | cpi r16,0x82 |
- | brlo light | + | brlo light |
- | brsh no_light | + | brsh no_light |
- | light: | + | light: |
- | lds r16,bh_lux | + | lds r16,bh_lux |
- | cpi r16,0x01 | + | cpi r16,0x01 |
- | brsh light_exit | + | brsh light_exit |
- | ldi r16,0b00000100 | + | ldi r16,0b00000100 |
- | out PORTD,r16 | + | out PORTD,r16 |
- | jmp light_exit | + | jmp light_exit |
- | no_light: | + | no_light: |
- | ldi r16,0b00000000 | + | ldi r16,0b00000000 |
- | out PORTD,r16 | + | out PORTD,r16 |
- | jmp light_exit | + | jmp light_exit |
- | light_exit: | + | light_exit: |
- | + | ||
- | pop r16 | + | pop r16 |
- | ldi ZL, LOW(adc_data); Производим косвенную адресацию на показания АЦП, чтобы потом их | + | ldi ZL, LOW(adc_data); Производим косвенную адресацию на показания АЦП, чтобы потом их |
- | ldi ZH, HIGH(adc_data); последовательно отправить по UART | + | ldi ZH, HIGH(adc_data); последовательно отправить по UART |
- | clr r20 | + | clr r20 |
- | print_adc:; Цикл отправки показаний АЦП | + | print_adc:; Цикл отправки показаний АЦП |
- | inc r20 | + | inc r20 |
- | push r | + | push r |
- | ld r17,Z | + | ld r17,Z |
- | adiw ZH:ZL,1 | + | adiw ZH:ZL,1 |
- | ld r16,Z | + | ld r16,Z |
- | adiw ZH:ZL,1 | + | adiw ZH:ZL,1 |
- | rcall bin2ASCII15 | + | rcall bin2ASCII15 |
- | popr | + | popr |
- | tabulate | + | tabulate |
- | cpi r20,4 | + | cpi r20,4 |
- | brne print_adc; Закончили цикл | + | brne print_adc; Закончили цикл |
- | tabulate | + | tabulate |
- | + | ||
- | push r | + | push r |
- | lds r17,bmp_temp; Выводим показания датчика BMP180 | + | lds r17,bmp_temp; Выводим показания датчика BMP180 |
- | lds r16,bmp_temp+1 | + | lds r16,bmp_temp+1 |
- | rcall bin2ASCII15 | + | rcall bin2ASCII15 |
- | tabulate | + | tabulate |
- | lds r17,bmp_pres | + | lds r17,bmp_pres |
- | lds r16,bmp_pres+1 | + | lds r16,bmp_pres+1 |
- | rcall bin2ASCII15 | + | rcall bin2ASCII15 |
- | tabulate | + | tabulate |
- | lds r17,bh_lux | + | lds r17,bh_lux |
- | lds r16,bh_lux+1 | + | lds r16,bh_lux+1 |
- | rcall bin2ASCII15 | + | rcall bin2ASCII15 |
- | popr | + | popr |
- | + | ||
- | inc r24; Увеличили счетчик кадров и отправили его значение по UART | + | inc r24; Увеличили счетчик кадров и отправили его значение по UART |
- | newline | + | newline |
- | + | ||
- | rcall i2c_start | + | rcall i2c_start |
- | ldi r16,0x47 | + | ldi r16,0x47 |
- | rcall i2c_send | + | rcall i2c_send |
- | rcall i2c_receive | + | rcall i2c_receive |
- | sts bh_lux,r16 | + | sts bh_lux,r16 |
- | rcall i2c_receive_last | + | rcall i2c_receive_last |
- | sts bh_lux+1,r16 | + | sts bh_lux+1,r16 |
- | rcall i2c_stop | + | rcall i2c_stop |
- | sei; Разрешили прерывания, чтобы микроконтроллер смог обработать | + | sei; Разрешили прерывания, чтобы микроконтроллер смог обработать |
- | ; новые показания АПЦ, термометров и датчика BMP180 | + | ; новые показания АПЦ, термометров и датчика BMP180 |
- | rcall i2c_start | + | rcall i2c_start |
- | rjmp main | + | rjmp main |
- | + | ||
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | ;Конец_основной_подпрограммы | + | ;Конец_основной_подпрограммы |
- | + | ||
- | ;Прерывание_АЦП | + | ;Прерывание_АЦП |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | adc_conv: | + | adc_conv: |
- | cli; Запрещаем прерывания | + | cli; Запрещаем прерывания |
- | + | ||
- | lds r17,ADCL; Снимаем показания сделанные во время нашего отсутствия в прерывании | + | lds r17,ADCL; Снимаем показания сделанные во время нашего отсутствия в прерывании |
- | lds r18,ADCH | + | lds r18,ADCH |
- | cpi r25,0; Смотрим, какое число содержится в r25 | + | cpi r25,0; Смотрим, какое число содержится в r25 |
- | breq adc0; Переходим по метке для этого числа | + | breq adc0; Переходим по метке для этого числа |
- | cpi r25,1 | + | cpi r25,1 |
- | breq adc1 | + | breq adc1 |
- | cpi r25,2 | + | cpi r25,2 |
- | breq adc2 | + | breq adc2 |
- | cpi r25,3 | + | cpi r25,3 |
- | breq adc3 | + | breq adc3 |
- | cpi r25,4 | + | cpi r25,4 |
- | breq adc4 | + | breq adc4 |
- | + | ||
- | adc0: | + | adc0: |
- | sts adc_data+6,r18; Записываем снятые в начале показания АЦП | + | sts adc_data+6,r18; Записываем снятые в начале показания АЦП |
- | sts adc_data+7,r17 | + | sts adc_data+7,r17 |
- | ldi r16,0b01000000; Запускаем новое преобразования в зависимости от пина АЦП | + | ldi r16,0b01000000; Запускаем новое преобразования в зависимости от пина АЦП |
- | sts ADMUX,r16 | + | sts ADMUX,r16 |
- | rjmp adc_ex; Переходим на выход | + | rjmp adc_ex; Переходим на выход |
- | + | ||
- | adc1: | + | adc1: |
- | sts adc_data,r18 | + | sts adc_data,r18 |
- | sts adc_data+1,r17 | + | sts adc_data+1,r17 |
- | ldi r16,0b01000001 | + | ldi r16,0b01000001 |
- | sts ADMUX,r16 | + | sts ADMUX,r16 |
- | rjmp adc_ex | + | rjmp adc_ex |
- | + | ||
- | adc2: | + | adc2: |
- | sts adc_data+2,r18 | + | sts adc_data+2,r18 |
- | sts adc_data+3,r17 | + | sts adc_data+3,r17 |
- | ldi r16,0b01000010 | + | ldi r16,0b01000010 |
- | sts ADMUX,r16 | + | sts ADMUX,r16 |
- | rjmp adc_ex | + | rjmp adc_ex |
- | + | ||
- | adc3: | + | adc3: |
- | sts adc_data+4,r18 | + | sts adc_data+4,r18 |
- | sts adc_data+5,r17 | + | sts adc_data+5,r17 |
- | ldi r16,0b01000011 | + | ldi r16,0b01000011 |
- | sts ADMUX,r16 | + | sts ADMUX,r16 |
- | rjmp adc_ex | + | rjmp adc_ex |
- | + | ||
- | adc4: | + | adc4: |
- | clr r25; Если r25 = 4, очищаем его и прыгаем на adc0 | + | clr r25; Если r25 = 4, очищаем его и прыгаем на adc0 |
- | rjmp adc0 | + | rjmp adc0 |
- | + | ||
- | adc_ex:ldi r16,0b11011111; Каждый раз повторно инициализируем АЦП | + | adc_ex:ldi r16,0b11011111; Каждый раз повторно инициализируем АЦП |
- | sts ADCSRA,r16 | + | sts ADCSRA,r16 |
- | inc r25 | + | inc r25 |
- | sei | + | sei |
- | reti | + | reti |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | ;Конец_прерывания_АЦП | + | ;Конец_прерывания_АЦП |
- | + | ||
- | + | ||
- | ;Прерывание_таймера1 | + | ;Прерывание_таймера1 |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | W1_timer: | + | W1_timer: |
- | cli | + | cli |
- | + | ||
- | ldi r16,0x54 | + | ldi r16,0x54 |
- | check1 r16 | + | check1 r16 |
- | tabulate | + | tabulate |
- | rcall W1_Sbros; Сбрасываем шину и проверяем есть ли датчик | + | rcall W1_Sbros; Сбрасываем шину и проверяем есть ли датчик |
- | ldi YL, LOW(Trm) | + | ldi YL, LOW(Trm) |
- | ldi YH, HIGH(Trm) | + | ldi YH, HIGH(Trm) |
- | ldi ZL,LOW(Addr1*2) | + | ldi ZL,LOW(Addr1*2) |
- | ldi ZH,HIGH(Addr1*2) | + | ldi ZH,HIGH(Addr1*2) |
- | rcall W1_ReadMem; Читаем в ОЗУ текущую температуру | + | rcall W1_ReadMem; Читаем в ОЗУ текущую температуру |
- | ldi ZL,LOW(Addr2*2) | + | ldi ZL,LOW(Addr2*2) |
- | ldi ZH,HIGH(Addr2*2) | + | ldi ZH,HIGH(Addr2*2) |
- | rcall W1_ReadMem | + | rcall W1_ReadMem |
- | ldi ZL,LOW(Addr3*2) | + | ldi ZL,LOW(Addr3*2) |
- | ldi ZH,HIGH(Addr3*2) | + | ldi ZH,HIGH(Addr3*2) |
- | rcall W1_ReadMem | + | rcall W1_ReadMem |
- | ldi ZL,LOW(Addr4*2) | + | ldi ZL,LOW(Addr4*2) |
- | ldi ZH,HIGH(Addr4*2) | + | ldi ZH,HIGH(Addr4*2) |
- | rcall W1_ReadMem | + | rcall W1_ReadMem |
- | ldi ZL,LOW(Addr5*2) | + | ldi ZL,LOW(Addr5*2) |
- | ldi ZH,HIGH(Addr5*2) | + | ldi ZH,HIGH(Addr5*2) |
- | rcall W1_ReadMem | + | rcall W1_ReadMem |
- | ldi ZL,LOW(Addr6*2) | + | ldi ZL,LOW(Addr6*2) |
- | ldi ZH,HIGH(Addr6*2) | + | ldi ZH,HIGH(Addr6*2) |
- | rcall W1_ReadMem | + | rcall W1_ReadMem |
- | ldi ZL,LOW(Addr7*2) | + | ldi ZL,LOW(Addr7*2) |
- | ldi ZH,HIGH(Addr7*2) | + | ldi ZH,HIGH(Addr7*2) |
- | rcall W1_ReadMem | + | rcall W1_ReadMem |
- | push f; На всякий случай отправляем в стек SREG | + | push f; На всякий случай отправляем в стек SREG |
- | ldi ZL, LOW(Trm); Делаем косвенную адресацию на массив данных температуры датчиков DS18B20 | + | ldi ZL, LOW(Trm); Делаем косвенную адресацию на массив данных температуры датчиков DS18B20 |
- | ldi ZH, HIGH(Trm) | + | ldi ZH, HIGH(Trm) |
- | clr r20 | + | clr r20 |
- | print1:; Цикл печати данных | + | print1:; Цикл печати данных |
- | inc r20 | + | inc r20 |
- | push r | + | push r |
- | ld r16,Z | + | ld r16,Z |
- | adiwZH:ZL,1 | + | adiwZH:ZL,1 |
- | ld r17,Z | + | ld r17,Z |
- | adiwZH:ZL,1 | + | adiwZH:ZL,1 |
- | rcall bin2ASCII15 | + | rcall bin2ASCII15 |
- | tabulate | + | tabulate |
- | popr | + | popr |
- | cpi r20,7 | + | cpi r20,7 |
- | + | ||
- | brne print1 | + | brne print1 |
- | newline | + | newline |
- | ; Задаем число с которого таймер начнет считать до следующего прерывания | + | ; Задаем число с которого таймер начнет считать до следующего прерывания |
- | ldi r22,0xA0 | + | ldi r22,0xA0 |
- | sts TCNT1H,r22 | + | sts TCNT1H,r22 |
- | sts TCNT1L,r22 | + | sts TCNT1L,r22 |
- | popf; Возвращаем SREG из стека | + | popf; Возвращаем SREG из стека |
- | sei; Разрешаем прерывания | + | sei; Разрешаем прерывания |
- | reti | + | reti |
- | + | ||
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | ;Конец_прерывания_таймера1 | + | ;Конец_прерывания_таймера1 |
- | + | ||
- | ;Прерывание_таймера0 | + | ;Прерывание_таймера0 |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | Board_timer: | + | Board_timer: |
- | cli | + | cli |
- | + | ||
- | push f | + | push f |
- | mov r16,r2 | + | mov r16,r2 |
- | + | ||
- | cpi r16,0xFF | + | cpi r16,0xFF |
- | breq r2cap | + | breq r2cap |
- | inc r2 | + | inc r2 |
- | jmp btim_exit | + | jmp btim_exit |
- | r2cap: | + | r2cap: |
- | clr r2 | + | clr r2 |
- | mov r16,r3 | + | mov r16,r3 |
- | cpi r16,0xFF | + | cpi r16,0xFF |
- | breq r3cap | + | breq r3cap |
- | inc r3 | + | inc r3 |
- | jmp btim_exit | + | jmp btim_exit |
- | r3cap: | + | r3cap: |
- | clr r3 | + | clr r3 |
- | mov r16,r4 | + | mov r16,r4 |
- | cpi r16,0xFF | + | cpi r16,0xFF |
- | breq r4cap | + | breq r4cap |
- | inc r4 | + | inc r4 |
- | jmp btim_exit | + | jmp btim_exit |
- | r4cap: | + | r4cap: |
- | clr r4 | + | clr r4 |
- | mov r16,r5 | + | mov r16,r5 |
- | cpi r16,0xFF | + | cpi r16,0xFF |
- | breq r5cap | + | breq r5cap |
- | jmp btim_exit | + | jmp btim_exit |
- | inc r5 | + | inc r5 |
- | r5cap: | + | r5cap: |
- | clr r5 | + | clr r5 |
- | jmp btim_exit | + | jmp btim_exit |
- | + | ||
- | btim_exit: | + | btim_exit: |
- | ldi r22,0xE9 | + | ldi r22,0xE9 |
- | sts TCNT2,r22 | + | sts TCNT2,r22 |
- | popf | + | popf |
- | sei | + | sei |
- | reti | + | reti |
- | + | ||
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | ;Конец_прерывания_таймера0 | + | ;Конец_прерывания_таймера0 |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | ;Прерывание_TWI | + | ;Прерывание_TWI |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | TWI_int: | + | TWI_int: |
- | cli; Запрещаем прерывания | + | cli; Запрещаем прерывания |
- | push r16; Отправляем в стек r16 | + | push r16; Отправляем в стек r16 |
- | lds r16,TWSR; Сравниваем Статус-регистр TWI | + | lds r16,TWSR; Сравниваем Статус-регистр TWI |
- | andi r16,0xF8 | + | andi r16,0xF8 |
- | cpi r16,0x08; Если он равен 0x08, то нам надо запустить вычисление | + | cpi r16,0x08; Если он равен 0x08, то нам надо запустить вычисление |
- | breq TWI_start_samples_1 | + | breq TWI_start_samples_1 |
- | cpi r16,0x10; Если он равен 0х10, то нам надо считывать показания | + | cpi r16,0x10; Если он равен 0х10, то нам надо считывать показания |
- | breq TWI_read_samples_1 | + | breq TWI_read_samples_1 |
- | TWI_exit:popr16; Возвращаем r16 из стека | + | TWI_exit:popr16; Возвращаем r16 из стека |
- | sei; Разрешаем прерывания | + | sei; Разрешаем прерывания |
- | reti | + | reti |
- | + | ||
- | TWI_start_samples_1:; Запускаем вычисление некомпенсированной температуры | + | TWI_start_samples_1:; Запускаем вычисление некомпенсированной температуры |
- | ; Проверяем содержимое переменной try | + | ; Проверяем содержимое переменной try |
- | cpi try,1; Если 1, то прыгаем на запуск вычисления давления | + | cpi try,1; Если 1, то прыгаем на запуск вычисления давления |
- | breq TWI_start_samples_2 | + | breq TWI_start_samples_2 |
- | ldi r16,0xEE; Если нет, то остаемся этой процедуре | + | ldi r16,0xEE; Если нет, то остаемся этой процедуре |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | ldi r16,0xF4 | + | ldi r16,0xF4 |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | ldi r16,0x2E | + | ldi r16,0x2E |
- | rcall i2c_send | + | rcall i2c_send |
- | rcall i2c_start | + | rcall i2c_start |
- | rjmp TWI_exit | + | rjmp TWI_exit |
- | + | ||
- | TWI_start_samples_2:; Запускаем вычисление некомпенсированного давления | + | TWI_start_samples_2:; Запускаем вычисление некомпенсированного давления |
- | ldi r16,0xEE | + | ldi r16,0xEE |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | ldi r16,0xF4 | + | ldi r16,0xF4 |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | ldi r16,0x34 | + | ldi r16,0x34 |
- | rcall i2c_send | + | rcall i2c_send |
- | rcall i2c_start | + | rcall i2c_start |
- | rjmp TWI_exit | + | rjmp TWI_exit |
- | TWI_read_samples_1:; Считываем показания некомпенсированной температуры | + | TWI_read_samples_1:; Считываем показания некомпенсированной температуры |
- | ; Снова проверяем try | + | ; Снова проверяем try |
- | cpi try,1 | + | cpi try,1 |
- | breq TWI_read_samples_2 | + | breq TWI_read_samples_2 |
- | ldi r16,0xEE | + | ldi r16,0xEE |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | ldi r16,0xF6 | + | ldi r16,0xF6 |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | rcall i2c_start | + | rcall i2c_start |
- | + | ||
- | ldi r16,0xEF | + | ldi r16,0xEF |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | rcall i2c_receive | + | rcall i2c_receive |
- | sts bmp_temp,r16 | + | sts bmp_temp,r16 |
- | rcall i2c_receive_last | + | rcall i2c_receive_last |
- | sts bmp_temp+1,r16 | + | sts bmp_temp+1,r16 |
- | ldi try,0b00000001 | + | ldi try,0b00000001 |
- | rcall i2c_stop | + | rcall i2c_stop |
- | rjmp TWI_exit | + | rjmp TWI_exit |
- | TWI_read_samples_2: | + | TWI_read_samples_2: |
- | ldi r16,0xEE | + | ldi r16,0xEE |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | ldi r16,0xF6 | + | ldi r16,0xF6 |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | rcall i2c_start | + | rcall i2c_start |
- | + | ||
- | ldi r16,0xEF | + | ldi r16,0xEF |
- | rcall i2c_send | + | rcall i2c_send |
- | + | ||
- | rcall i2c_receive | + | rcall i2c_receive |
- | sts bmp_pres,r16 | + | sts bmp_pres,r16 |
- | rcall i2c_receive_last | + | rcall i2c_receive_last |
- | sts bmp_pres+1,r16 | + | sts bmp_pres+1,r16 |
- | ldi try,0b00000000; Уменьшаем try до 0 | + | ldi try,0b00000000; Уменьшаем try до 0 |
- | rcall i2c_stop | + | rcall i2c_stop |
- | rjmp TWI_exit | + | rjmp TWI_exit |
- | ;-------------------------------------------------------------------------------------------------------------- | + | ;-------------------------------------------------------------------------------------------------------------- |
- | ;Конец_прерывания_TWI | + | ;Конец_прерывания_TWI |
- | + | ||
- | + | ||
- | Addr1:.db0x28,0xFF,0x41,0x3,0xA3,0x15,0x1,0xBB; Адреса датчиков DS18B20 | + | Addr1:.db0x28,0xFF,0x41,0x3,0xA3,0x15,0x1,0xBB; Адреса датчиков DS18B20 |
- | Addr2:.db0x28,0xFF,0xE2,0x1A,0xA2,0x15,0x4,0xF9 | + | Addr2:.db0x28,0xFF,0xE2,0x1A,0xA2,0x15,0x4,0xF9 |
- | Addr3:.db0x28,0xFF,0x91,0xF,0xA3,0x15,0x4,0xC8 | + | Addr3:.db0x28,0xFF,0x91,0xF,0xA3,0x15,0x4,0xC8 |
- | Addr4:.db0x28,0xFF,0x90,0x82,0xA3,0x15,0x4,0x41 | + | Addr4:.db0x28,0xFF,0x90,0x82,0xA3,0x15,0x4,0x41 |
- | Addr5:.db0x28,0xFF,0xC6,0xB,0xA3,0x15,0x4,0x2 | + | Addr5:.db0x28,0xFF,0xC6,0xB,0xA3,0x15,0x4,0x2 |
- | Addr6:.db0x28,0xFF,0x9,0x5D,0xA3,0x15,0x4,0x9E | + | Addr6:.db0x28,0xFF,0x9,0x5D,0xA3,0x15,0x4,0x9E |
- | Addr7:.db0x28,0xFF,0x7F,0x83,0xA3,0x15,0x4,0x7B | + | Addr7:.db0x28,0xFF,0x7F,0x83,0xA3,0x15,0x4,0x7B |
- | + | ||
- | + | ||
- | + | ||
- | Delay: ; Стандартная задержка | + | Delay: ; Стандартная задержка |
- | push f | + | push f |
- | ldi razr1, 50 | + | ldi razr1, 50 |
- | ldi razr2, 10 | + | ldi razr2, 10 |
- | Pdelay: | + | Pdelay: |
- | dec razr1 | + | dec razr1 |
- | brne Pdelay | + | brne Pdelay |
- | dec razr2 | + | dec razr2 |
- | brne Pdelay | + | brne Pdelay |
- | popf | + | popf |
- | ret | + | ret |
- | Delay1: ; Стандартная задержка 1 | + | Delay1: ; Стандартная задержка 1 |
- | push f | + | push f |
- | ldi razr1, 50 | + | ldi razr1, 50 |
- | ldi razr2, 50 | + | ldi razr2, 50 |
- | ldi razr3, 1 | + | ldi razr3, 1 |
- | Pdelay1: | + | Pdelay1: |
- | dec razr1 | + | dec razr1 |
- | brne Pdelay1 | + | brne Pdelay1 |
- | dec razr2 | + | dec razr2 |
- | brne Pdelay1 | + | brne Pdelay1 |
- | dec razr3 | + | dec razr3 |
- | brne Pdelay1 | + | brne Pdelay1 |
- | popf | + | popf |
- | ret | + | ret |
- | + | </code> | |
- | </file> | + | </hidden> |
- | **2. Текст модуля 1wire.asm на языке ассемблера AVR** | + | |
- | <file asm 1wire.asm> | + | |
- | ;1-wire_подпрограммы | + | |
- | ;-------------------------------------------------------------------------------------------------------------- | + | |
- | + | ||
- | + | ||
- | W1_Sbros: ; Сброс шины и проверка датчик на месте ли | + | |
- | lds r16, W1_BIT ; Записываем в r16 ножку где датчик | + | |
- | sbi W1_DDR, W1_BIT ; Ногу на выход | + | |
- | cbi W1_PORT, W1_BIT ; Опрокидываем вывод на землю | + | |
- | rcall W1_DelayH ; Задержка 480 мкс, для сброса | + | |
- | cbi W1_DDR, W1_BIT ; Ногу на вход | + | |
- | rcall W1_DelayI ; Ждем тайм слот 70 мкс | + | |
- | sbis W1_PIN, W1_BIT ; Пропускаем следующую строку, если бит порта в 1 | + | |
- | ldi r17, 1 ; И установим сигнальный регистр в 1 | + | |
- | sbic W1_PIN, W1_BIT ; Пропускаем следующую строку, если бит порта в 0 | + | |
- | ldi r17, 0 ; И установим сигнальный регистр в 0 | + | |
- | rcall W1_DelayJ ; Ждем тайм слот 410 мкс | + | |
- | ret ; Если датчик на месте, в r17 по выходу отсюда будет 1, в противном случае 0 | + | |
- | + | ||
- | W1_Address: | + | |
- | clr r20 | + | |
- | read: | + | |
- | inc r20 ; Процедура считывания адреса датчиков DS18B20 | + | |
- | in r10,SREG | + | |
- | push r10 | + | |
- | lpm r16,Z | + | |
- | rcall ds_byte_wr | + | |
- | pop r10 | + | |
- | out SREG,r10 | + | |
- | adiw ZH:ZL,1 | + | |
- | cpi r20,8 | + | |
- | brne read | + | |
- | ret | + | |
- | + | ||
- | W1_ReadMem: ; Чтение памяти регистров температуры | + | |
- | ldi r16, 0x55 ; Пошлем команду 0x55, это сравнить уникальный номер датчика | + | |
- | rcall ds_byte_wr ; Так как он у нас один на проводе | + | |
- | rcall W1_Address ; Отправляем адрес датчика | + | |
- | ldi r16, 0xBE ; Говорим датчику, что мы сейчас будем читать | + | |
- | rcall ds_byte_wr ; Запуливаем байт | + | |
- | rcall ds_byte_rd ; А тут уже начинаем читать, прочитали первый | + | |
- | st Y, r16 ; И запулили его в память, по метке Trm | + | |
- | adiw YH:YL,1 | + | |
- | rcall ds_byte_rd ; Читаем второй | + | |
- | st Y, r16 ; И запулили его в память, по метке Trm+1 | + | |
- | adiw YH:YL,1 | + | |
- | rcall W1_Sbros ; Сбрасываем шину и проверяем есть ли датчик | + | |
- | ;ldi ZL,LOW(Addr2*2) | + | |
- | ;ldi ZH,HIGH(Addr2*2) | + | |
- | ;clr r20 | + | |
- | ret | + | |
- | + | ||
- | W1_ConvTemp: ; Подпрограмма конвертирования температуры | + | |
- | ldi r16, 0xCC ; Пропускаем уникальный номер датчика | + | |
- | rcall ds_byte_wr | + | |
- | ldi r16, 0x44 ; Говорим что надо бы сконвертировать температуру, этот процесс занимает 750 | + | |
- | rcall ds_byte_wr ; миллисекунд, поэтому идем что-то делать, или ленится | + | |
- | ret | + | |
- | + | ||
- | W1_Init_12bit: ; Подпрограмма перестройки на 12 бит температуры | + | |
- | ldi r16, 0xCC ; Пропускаем уникальный номер датчика | + | |
- | rcall ds_byte_wr ; Спуливаем в датчик | + | |
- | ldi r16, 0x4E ; Говорим что сейчас будем писать в RAM регистры датчика | + | |
- | rcall ds_byte_wr ; Спуливаем в датчик | + | |
- | ldi r16, 0xFF ; 0xFF записываем в первые 2 регистра, это регистры температуры, он нам не | + | |
- | rcall ds_byte_wr ; нужен, поэтому их оставляем в стандартном состоянии | + | |
- | ldi r16, 0xFF ; 0xFF второй байт температуры | + | |
- | rcall ds_byte_wr ; Спуливаем на порт | + | |
- | ldi r16, 0x7F ; А вот тут говорим что 12 бит - 7F, или 1F - 9бит, 3F - 10 бит, 5F - 11 бит | + | |
- | rcall ds_byte_wr ; Спуливаем на порт | + | |
- | ret | + | |
- | + | ||
- | ds_byte_rd: ; Подпрограмма чтения данных в регистр r16 с 1 Wire | + | |
- | ldi r17, 8 ; Пишем в r17 - 8, т.к. у нас в бит в регистре | + | |
- | clr r16 ;Чистим r16, сюда будем читать данные | + | |
- | ds_byte_rd_0: | + | |
- | sbi W1_DDR, W1_BIT ; Вывод на выход | + | |
- | cbi W1_PORT, W1_BIT ; Опрокидываем вывод на землю | + | |
- | rcall W1_DelayA ; Ждем 6 микросекунд | + | |
- | cbi W1_DDR, W1_BIT ; Вывод на вход | + | |
- | rcall W1_DelayE ; Ждем 9 микросекунд | + | |
- | sbis W1_PIN, W1_BIT | + | |
- | clc ; Очищаем бит C = 0 | + | |
- | sbic W1_PIN, W1_BIT | + | |
- | sec ; Очищаем бит C = 1 | + | |
- | ror r16 ; Производим циклический сдвиг вправо через С | + | |
- | rcall W1_DelayF ; Ждем 55 микросекунд | + | |
- | dec r17 ;Понижаем на 1 регистр r17 | + | |
- | brne ds_byte_rd_0 ; если не равен 0 вращаемся в цикле | + | |
- | ret | + | |
- | + | ||
- | ds_byte_wr: ; Подпрограмма записи данных из регистра r16 в датчик | + | |
- | ldi r17, 8 ; Пишем в r17 - 8, т.к. у нас в бит в регистре | + | |
- | ds_byte_wr0: | + | |
- | sbi W1_DDR, W1_BIT ; Вывод на выход | + | |
- | cbi W1_PORT, W1_BIT ; Опрокидываем вывод на землю | + | |
- | sbrc r16, 0 ; Проверим, в r16 бит 0 очищен или установлен | + | |
- | rjmp ds_byte_write_1 ; Если установлен перейдем по этой метке | + | |
- | rjmp ds_byte_write_0 ; Если очищен перейдем по этой метке | + | |
- | ds_byte_wr1: | + | |
- | lsr r16 ; Логический сдвиг вправо | + | |
- | dec r17 ; Понижаем r17 на 1 | + | |
- | brne ds_byte_wr0 ; Если не равен 0, вращаемся в цикле | + | |
- | ret ; Выход из подпрограммы | + | |
- | + | ||
- | ds_byte_write_0: ; Запись 0 | + | |
- | rcall W1_DelayC ; Ждем 60 микросекунд | + | |
- | cbi W1_DDR, W1_BIT ; Вывод на вход | + | |
- | rcall W1_DelayD ; Ждем 10 микросекунд | + | |
- | rjmp ds_byte_wr1 | + | |
- | + | ||
- | ds_byte_write_1: ; Запись 1 | + | |
- | rcall W1_DelayA ; Ждем 6 микросекунд | + | |
- | cbi W1_DDR, W1_BIT ; Вывод на вход | + | |
- | rcall W1_DelayB ; Ждем 64 микросекунд | + | |
- | rjmp ds_byte_wr1 | + | |
- | + | ||
- | W1_DelayA: ; Задержка 6 mcs | + | |
- | ldi XH, high(FREQ/2000000) | + | |
- | ldi XL, low(FREQ/2000000) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayB: ; Задержка 64 mcs | + | |
- | ldi XH, high(FREQ/130000) | + | |
- | ldi XL, low(FREQ/130000) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayC: ; Задержка 60 mcs | + | |
- | ldi XH, high(FREQ/136000) | + | |
- | ldi XL, low(FREQ/136000) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayD: ; Задержка 10 mcs | + | |
- | ldi XH, high(FREQ/1000000) | + | |
- | ldi XL, low(FREQ/1000000) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayE: ; Задержка 9 mcs | + | |
- | ldi XH, high(FREQ/1200000) | + | |
- | ldi XL, low(FREQ/1200000) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayF: ; Задержка 55 mcs | + | |
- | ldi XH, high(FREQ/150000) | + | |
- | ldi XL, low(FREQ/150000) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayH: ; Задержка 480 mcs | + | |
- | ldi XH, high(FREQ/16664) | + | |
- | ldi XL, low(FREQ/16664) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayI: ; Задержка 70 mcs | + | |
- | ldi XH, high(FREQ/116000) | + | |
- | ldi XL, low(FREQ/116000) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_DelayJ: ; Задержка 410 mcs | + | |
- | ldi XH, high(FREQ/19512) | + | |
- | ldi XL, low(FREQ/19512) | + | |
- | rcall W1_Delay | + | |
- | ret | + | |
- | W1_Delay: ; Подпрограмма воспроизведения задержки | + | |
- | sbiw XH:XL, 1 ; Вычитаем единицу из регистровой пары | + | |
- | brne W1_Delay ; Если не равно 0 крутимся в цикле | + | |
- | ret ; Выход из подпрограммы | + | |
- | ;-------------------------------------------------------------------------------------------------------------- | + | |
- | ;Конец_1-wire_подпрограмм | + | |
- | </file> | + | |
- | + | ||
- | **3. Текст модуля hextobcd.asm на языке ассемблера AVR** | + | |
- | <file asm hextobcd.asm> | + | |
- | .def fASCIIL =r16 | + | |
- | .def tASCII0 =r16 | + | |
- | .def fASCIIH =r17 | + | |
- | .def tASCII2 =r25 | + | |
- | .def tASCII3 =r19 | + | |
- | .def tASCII4 =r20 | + | |
- | .def tASCII1 =r21 | + | |
- | .def cnt16a =r21 | + | |
- | .def tmp16a =r22 | + | |
- | .def tmp16b =r23 | + | |
- | + | ||
- | ;***** Код | + | |
- | print_ascii: | + | |
- | check1 r20 | + | |
- | check1 r19 | + | |
- | check1 r25 | + | |
- | check1 r21 | + | |
- | check1 r16 | + | |
- | ret | + | |
- | bin2ASCII15: | + | |
- | ldi tmp16a, low(10000) | + | |
- | ldi tmp16b, high(10000) | + | |
- | rcall bin2ASCII_digit | + | |
- | mov tASCII4, cnt16a | + | |
- | ldi tmp16a, low(1000) | + | |
- | ldi tmp16b, high(1000) | + | |
- | rcall bin2ASCII_digit | + | |
- | mov tASCII3, cnt16a | + | |
- | ldi tmp16a, low(100) | + | |
- | ldi tmp16b, high(100) | + | |
- | rcall bin2ASCII_digit | + | |
- | mov tASCII2, cnt16a | + | |
- | ldi tmp16a, low(10) | + | |
- | ldi tmp16b, high(10) | + | |
- | rcall bin2ASCII_digit | + | |
- | ldi r17,0x30 | + | |
- | add r16,r17 | + | |
- | add r21,r17 | + | |
- | add r25,r17 | + | |
- | add r19,r17 | + | |
- | add r20,r17 | + | |
- | rcall print_ascii | + | |
- | ret | + | |
- | bin2ASCII_digit: | + | |
- | ldi cnt16a, -1 | + | |
- | bin2ASCII_digit_loop: | + | |
- | inc cnt16a | + | |
- | sub fASCIIL, tmp16a | + | |
- | sbc fASCIIH, tmp16b | + | |
- | brsh bin2ASCII_digit_loop | + | |
- | add fASCIIL, tmp16a | + | |
- | adc fASCIIH, tmp16b | + | |
- | + | ||
- | ret | + | |
- | + | ||
- | </file> | + | |
- | + | ||
- | **4. Текст модуля iterrupts.asm на языке ассемблера AVR** | + | |
- | <file asm iterrupts.asm> | + | |
- | ;Векторы_прерываний | + | |
- | ;----------------------------------------------------------------------- | + | |
- | + | ||
- | .org 0x0000 ; Reset | + | |
- | jmp RESET | + | |
- | .org 0x0002 ; External Interrupt Request 0 | + | |
- | reti | + | |
- | .org 0x0004 ; External Interrupt Request 1 | + | |
- | reti | + | |
- | .org 0x0006 ; Pin Change Interrupt Request 0 | + | |
- | reti | + | |
- | .org 0x0008 ; Pin Change Interrupt Request 1 | + | |
- | reti | + | |
- | .org 0x000A ; Pin Change Interrupt Request 2 | + | |
- | reti | + | |
- | .org 0x000C ; Watchdog Time-out Interrupt | + | |
- | reti | + | |
- | .org 0x000E ; Timer/Counter 2 Compare Match A | + | |
- | reti | + | |
- | .org 0x0010 ; Timer/Counter 2 Compare Match B | + | |
- | reti | + | |
- | .org 0x0012 ; Timer/Counter 2 Overflow | + | |
- | jmp Board_timer | + | |
- | .org 0x0014 ; Timer/Counter 1 Capture Event | + | |
- | reti | + | |
- | .org 0x0016 ; Timer/Counter 1 Compare Match A | + | |
- | reti | + | |
- | .org 0x0018 ; Timer/Counter 1 Compare Match B | + | |
- | reti | + | |
- | .org 0x001A ; Timer/Counter 1 Overflow | + | |
- | rjmp W1_timer | + | |
- | ;reti | + | |
- | .org 0x001C ; Timer/Counter 0 Compare Match A | + | |
- | reti | + | |
- | .org 0x001E ; Timer/Counter 0 Compare Match B | + | |
- | reti | + | |
- | .org 0x0020 ; Timer/Counter 0 Overflow | + | |
- | reti | + | |
- | .org 0x0022 ; SPI Serial Transfer Complete | + | |
- | reti | + | |
- | .org 0x0024 ; USART, Rx Complete | + | |
- | reti | + | |
- | .org 0x0026 ; USART, UDR Empty | + | |
- | reti | + | |
- | .org 0x0028 ; USART, Tx Complete | + | |
- | reti | + | |
- | .org 0x002A ; ADC Conversion Complete | + | |
- | jmp adc_conv | + | |
- | .org 0x002C ; EEPROM Ready | + | |
- | reti | + | |
- | .org 0x002E ; Analog Comparator | + | |
- | reti | + | |
- | .org 0x0030 ; Two-wire Serial Interface | + | |
- | jmp TWI_int | + | |
- | ;reti | + | |
- | .org 0x0032 ; Store Program Memory Read | + | |
- | reti | + | |
- | + | ||
- | .org INT_VECTORS_SIZE | + | |
- | </file> | + | |
- | + | ||
- | + | ||
- | **5. Текст модуля macr.asm на языке ассемблера AVR** | + | |
- | <file asm macr.asm> | + | |
- | + | ||
- | ;Макросы | + | |
- | ;----------------------------------------------------------------------- | + | |
- | .macro pushf | + | |
- | push r10 | + | |
- | in r10,SREG | + | |
- | push r10 | + | |
- | .endm | + | |
- | .macro popf | + | |
- | pop r10 | + | |
- | out SREG,r10 | + | |
- | pop r10 | + | |
- | .endm | + | |
- | .macro pushr | + | |
- | push r10 | + | |
- | in r10,SREG | + | |
- | push r10 | + | |
- | push r16 | + | |
- | push r17 | + | |
- | push r18 | + | |
- | push r19 | + | |
- | push r20 | + | |
- | push r21 | + | |
- | push r22 | + | |
- | push r23 | + | |
- | push r25 | + | |
- | push r26 | + | |
- | push r27 | + | |
- | push r28 | + | |
- | push r29 | + | |
- | .endm | + | |
- | .macro popr | + | |
- | pop r29 | + | |
- | pop r28 | + | |
- | pop r27 | + | |
- | pop r26 | + | |
- | pop r25 | + | |
- | pop r23 | + | |
- | pop r22 | + | |
- | pop r21 | + | |
- | pop r20 | + | |
- | pop r19 | + | |
- | pop r18 | + | |
- | pop r17 | + | |
- | pop r16 | + | |
- | pop r10 | + | |
- | out SREG,r10 | + | |
- | pop r10 | + | |
- | .endm | + | |
- | .macro check | + | |
- | push @0 | + | |
- | lds @0,@1 | + | |
- | sts UDR0,@0 | + | |
- | check_loop: ldi @0,UCSR0A | + | |
- | sbrs @0,TXC0 | + | |
- | rjmp check_loop | + | |
- | pop @0 | + | |
- | rcall Delay | + | |
- | .endm | + | |
- | + | ||
- | .macro check_kosv | + | |
- | push @0 | + | |
- | ld @0,@1 | + | |
- | sts UDR0,@0 | + | |
- | check_loop1: ldi @0,UCSR0A | + | |
- | sbrs @0,TXC0 | + | |
- | rjmp check_loop1 | + | |
- | pop @0 | + | |
- | rcall Delay | + | |
- | .endm | + | |
- | .macro check1 | + | |
- | sts UDR0,@0 | + | |
- | check_loop1: ldi @0,UCSR0A | + | |
- | sbrs @0,TXC0 | + | |
- | rjmp check_loop1 | + | |
- | rcall Delay | + | |
- | .endm | + | |
- | + | ||
- | .macro tabulate | + | |
- | push r16 | + | |
- | ldi r16,0x09 | + | |
- | check1 r16 | + | |
- | pop r16 | + | |
- | .endm | + | |
- | .macro newline | + | |
- | push r16 | + | |
- | ldi r16,0x0D | + | |
- | check1 r16 | + | |
- | ldi r16,0x0A | + | |
- | check1 r16 | + | |
- | pop r16 | + | |
- | .endm | + | |
- | </file> | + | |
- | **6. Текст модуля twi_lib.asm на языке ассемблера AVR** | + | \\ |
- | <file asm twi_lib.asm> | + | ====Текст модуля 1wire.asm==== |
+ | <hidden развернуть> | ||
+ | <code asm> | ||
+ | ;1-wire_подпрограммы | ||
+ | ;-------------------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | |||
+ | W1_Sbros: ; Сброс шины и проверка датчик на месте ли | ||
+ | lds r16, W1_BIT ; Записываем в r16 ножку где датчик | ||
+ | sbi W1_DDR, W1_BIT ; Ногу на выход | ||
+ | cbi W1_PORT, W1_BIT ; Опрокидываем вывод на землю | ||
+ | rcall W1_DelayH ; Задержка 480 мкс, для сброса | ||
+ | cbi W1_DDR, W1_BIT ; Ногу на вход | ||
+ | rcall W1_DelayI ; Ждем тайм слот 70 мкс | ||
+ | sbis W1_PIN, W1_BIT ; Пропускаем следующую строку, если бит порта в 1 | ||
+ | ldi r17, 1 ; И установим сигнальный регистр в 1 | ||
+ | sbic W1_PIN, W1_BIT ; Пропускаем следующую строку, если бит порта в 0 | ||
+ | ldi r17, 0 ; И установим сигнальный регистр в 0 | ||
+ | rcall W1_DelayJ ; Ждем тайм слот 410 мкс | ||
+ | ret ; Если датчик на месте, в r17 по выходу отсюда будет 1, в противном случае 0 | ||
+ | |||
+ | W1_Address: | ||
+ | clr r20 | ||
+ | read: | ||
+ | inc r20 ; Процедура считывания адреса датчиков DS18B20 | ||
+ | in r10,SREG | ||
+ | push r10 | ||
+ | lpm r16,Z | ||
+ | rcall ds_byte_wr | ||
+ | pop r10 | ||
+ | out SREG,r10 | ||
+ | adiw ZH:ZL,1 | ||
+ | cpi r20,8 | ||
+ | brne read | ||
+ | ret | ||
+ | |||
+ | W1_ReadMem: ; Чтение памяти регистров температуры | ||
+ | ldi r16, 0x55 ; Пошлем команду 0x55, это сравнить уникальный номер датчика | ||
+ | rcall ds_byte_wr ; Так как он у нас один на проводе | ||
+ | rcall W1_Address ; Отправляем адрес датчика | ||
+ | ldi r16, 0xBE ; Говорим датчику, что мы сейчас будем читать | ||
+ | rcall ds_byte_wr ; Запуливаем байт | ||
+ | rcall ds_byte_rd ; А тут уже начинаем читать, прочитали первый | ||
+ | st Y, r16 ; И запулили его в память, по метке Trm | ||
+ | adiw YH:YL,1 | ||
+ | rcall ds_byte_rd ; Читаем второй | ||
+ | st Y, r16 ; И запулили его в память, по метке Trm+1 | ||
+ | adiw YH:YL,1 | ||
+ | rcall W1_Sbros ; Сбрасываем шину и проверяем есть ли датчик | ||
+ | ;ldi ZL,LOW(Addr2*2) | ||
+ | ;ldi ZH,HIGH(Addr2*2) | ||
+ | ;clr r20 | ||
+ | ret | ||
+ | |||
+ | W1_ConvTemp: ; Подпрограмма конвертирования температуры | ||
+ | ldi r16, 0xCC ; Пропускаем уникальный номер датчика | ||
+ | rcall ds_byte_wr | ||
+ | ldi r16, 0x44 ; Говорим что надо бы сконвертировать температуру, этот процесс занимает 750 | ||
+ | rcall ds_byte_wr ; миллисекунд, поэтому идем что-то делать, или ленится | ||
+ | ret | ||
+ | |||
+ | W1_Init_12bit: ; Подпрограмма перестройки на 12 бит температуры | ||
+ | ldi r16, 0xCC ; Пропускаем уникальный номер датчика | ||
+ | rcall ds_byte_wr ; Спуливаем в датчик | ||
+ | ldi r16, 0x4E ; Говорим что сейчас будем писать в RAM регистры датчика | ||
+ | rcall ds_byte_wr ; Спуливаем в датчик | ||
+ | ldi r16, 0xFF ; 0xFF записываем в первые 2 регистра, это регистры температуры, он нам не | ||
+ | rcall ds_byte_wr ; нужен, поэтому их оставляем в стандартном состоянии | ||
+ | ldi r16, 0xFF ; 0xFF второй байт температуры | ||
+ | rcall ds_byte_wr ; Спуливаем на порт | ||
+ | ldi r16, 0x7F ; А вот тут говорим что 12 бит - 7F, или 1F - 9бит, 3F - 10 бит, 5F - 11 бит | ||
+ | rcall ds_byte_wr ; Спуливаем на порт | ||
+ | ret | ||
+ | |||
+ | ds_byte_rd: ; Подпрограмма чтения данных в регистр r16 с 1 Wire | ||
+ | ldi r17, 8 ; Пишем в r17 - 8, т.к. у нас в бит в регистре | ||
+ | clr r16 ;Чистим r16, сюда будем читать данные | ||
+ | ds_byte_rd_0: | ||
+ | sbi W1_DDR, W1_BIT ; Вывод на выход | ||
+ | cbi W1_PORT, W1_BIT ; Опрокидываем вывод на землю | ||
+ | rcall W1_DelayA ; Ждем 6 микросекунд | ||
+ | cbi W1_DDR, W1_BIT ; Вывод на вход | ||
+ | rcall W1_DelayE ; Ждем 9 микросекунд | ||
+ | sbis W1_PIN, W1_BIT | ||
+ | clc ; Очищаем бит C = 0 | ||
+ | sbic W1_PIN, W1_BIT | ||
+ | sec ; Очищаем бит C = 1 | ||
+ | ror r16 ; Производим циклический сдвиг вправо через С | ||
+ | rcall W1_DelayF ; Ждем 55 микросекунд | ||
+ | dec r17 ;Понижаем на 1 регистр r17 | ||
+ | brne ds_byte_rd_0 ; если не равен 0 вращаемся в цикле | ||
+ | ret | ||
+ | |||
+ | ds_byte_wr: ; Подпрограмма записи данных из регистра r16 в датчик | ||
+ | ldi r17, 8 ; Пишем в r17 - 8, т.к. у нас в бит в регистре | ||
+ | ds_byte_wr0: | ||
+ | sbi W1_DDR, W1_BIT ; Вывод на выход | ||
+ | cbi W1_PORT, W1_BIT ; Опрокидываем вывод на землю | ||
+ | sbrc r16, 0 ; Проверим, в r16 бит 0 очищен или установлен | ||
+ | rjmp ds_byte_write_1 ; Если установлен перейдем по этой метке | ||
+ | rjmp ds_byte_write_0 ; Если очищен перейдем по этой метке | ||
+ | ds_byte_wr1: | ||
+ | lsr r16 ; Логический сдвиг вправо | ||
+ | dec r17 ; Понижаем r17 на 1 | ||
+ | brne ds_byte_wr0 ; Если не равен 0, вращаемся в цикле | ||
+ | ret ; Выход из подпрограммы | ||
+ | |||
+ | ds_byte_write_0: ; Запись 0 | ||
+ | rcall W1_DelayC ; Ждем 60 микросекунд | ||
+ | cbi W1_DDR, W1_BIT ; Вывод на вход | ||
+ | rcall W1_DelayD ; Ждем 10 микросекунд | ||
+ | rjmp ds_byte_wr1 | ||
+ | |||
+ | ds_byte_write_1: ; Запись 1 | ||
+ | rcall W1_DelayA ; Ждем 6 микросекунд | ||
+ | cbi W1_DDR, W1_BIT ; Вывод на вход | ||
+ | rcall W1_DelayB ; Ждем 64 микросекунд | ||
+ | rjmp ds_byte_wr1 | ||
+ | |||
+ | W1_DelayA: ; Задержка 6 mcs | ||
+ | ldi XH, high(FREQ/2000000) | ||
+ | ldi XL, low(FREQ/2000000) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayB: ; Задержка 64 mcs | ||
+ | ldi XH, high(FREQ/130000) | ||
+ | ldi XL, low(FREQ/130000) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayC: ; Задержка 60 mcs | ||
+ | ldi XH, high(FREQ/136000) | ||
+ | ldi XL, low(FREQ/136000) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayD: ; Задержка 10 mcs | ||
+ | ldi XH, high(FREQ/1000000) | ||
+ | ldi XL, low(FREQ/1000000) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayE: ; Задержка 9 mcs | ||
+ | ldi XH, high(FREQ/1200000) | ||
+ | ldi XL, low(FREQ/1200000) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayF: ; Задержка 55 mcs | ||
+ | ldi XH, high(FREQ/150000) | ||
+ | ldi XL, low(FREQ/150000) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayH: ; Задержка 480 mcs | ||
+ | ldi XH, high(FREQ/16664) | ||
+ | ldi XL, low(FREQ/16664) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayI: ; Задержка 70 mcs | ||
+ | ldi XH, high(FREQ/116000) | ||
+ | ldi XL, low(FREQ/116000) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_DelayJ: ; Задержка 410 mcs | ||
+ | ldi XH, high(FREQ/19512) | ||
+ | ldi XL, low(FREQ/19512) | ||
+ | rcall W1_Delay | ||
+ | ret | ||
+ | W1_Delay: ; Подпрограмма воспроизведения задержки | ||
+ | sbiw XH:XL, 1 ; Вычитаем единицу из регистровой пары | ||
+ | brne W1_Delay ; Если не равно 0 крутимся в цикле | ||
+ | ret ; Выход из подпрограммы | ||
+ | ;-------------------------------------------------------------------------------------------------------------- | ||
+ | ;Конец_1-wire_подпрограмм | ||
+ | </code> | ||
+ | </hidden> | ||
+ | \\ | ||
+ | ====Текст модуля hextobcd.asm==== | ||
+ | <hidden развернуть> | ||
+ | <code asm> | ||
+ | .def fASCIIL =r16 | ||
+ | .def tASCII0 =r16 | ||
+ | .def fASCIIH =r17 | ||
+ | .def tASCII2 =r25 | ||
+ | .def tASCII3 =r19 | ||
+ | .def tASCII4 =r20 | ||
+ | .def tASCII1 =r21 | ||
+ | .def cnt16a =r21 | ||
+ | .def tmp16a =r22 | ||
+ | .def tmp16b =r23 | ||
+ | |||
+ | ;***** Код | ||
+ | print_ascii: | ||
+ | check1 r20 | ||
+ | check1 r19 | ||
+ | check1 r25 | ||
+ | check1 r21 | ||
+ | check1 r16 | ||
+ | ret | ||
+ | bin2ASCII15: | ||
+ | ldi tmp16a, low(10000) | ||
+ | ldi tmp16b, high(10000) | ||
+ | rcall bin2ASCII_digit | ||
+ | mov tASCII4, cnt16a | ||
+ | ldi tmp16a, low(1000) | ||
+ | ldi tmp16b, high(1000) | ||
+ | rcall bin2ASCII_digit | ||
+ | mov tASCII3, cnt16a | ||
+ | ldi tmp16a, low(100) | ||
+ | ldi tmp16b, high(100) | ||
+ | rcall bin2ASCII_digit | ||
+ | mov tASCII2, cnt16a | ||
+ | ldi tmp16a, low(10) | ||
+ | ldi tmp16b, high(10) | ||
+ | rcall bin2ASCII_digit | ||
+ | ldi r17,0x30 | ||
+ | add r16,r17 | ||
+ | add r21,r17 | ||
+ | add r25,r17 | ||
+ | add r19,r17 | ||
+ | add r20,r17 | ||
+ | rcall print_ascii | ||
+ | ret | ||
+ | bin2ASCII_digit: | ||
+ | ldi cnt16a, -1 | ||
+ | bin2ASCII_digit_loop: | ||
+ | inc cnt16a | ||
+ | sub fASCIIL, tmp16a | ||
+ | sbc fASCIIH, tmp16b | ||
+ | brsh bin2ASCII_digit_loop | ||
+ | add fASCIIL, tmp16a | ||
+ | adc fASCIIH, tmp16b | ||
+ | |||
+ | ret | ||
+ | </code> | ||
+ | </hidden> | ||
+ | \\ | ||
+ | ====Текст модуля iterrupts.asm==== | ||
+ | <hidden развернуть> | ||
+ | <code asm> | ||
+ | ;Векторы_прерываний | ||
+ | ;----------------------------------------------------------------------- | ||
+ | |||
+ | .org 0x0000 ; Reset | ||
+ | jmp RESET | ||
+ | .org 0x0002 ; External Interrupt Request 0 | ||
+ | reti | ||
+ | .org 0x0004 ; External Interrupt Request 1 | ||
+ | reti | ||
+ | .org 0x0006 ; Pin Change Interrupt Request 0 | ||
+ | reti | ||
+ | .org 0x0008 ; Pin Change Interrupt Request 1 | ||
+ | reti | ||
+ | .org 0x000A ; Pin Change Interrupt Request 2 | ||
+ | reti | ||
+ | .org 0x000C ; Watchdog Time-out Interrupt | ||
+ | reti | ||
+ | .org 0x000E ; Timer/Counter 2 Compare Match A | ||
+ | reti | ||
+ | .org 0x0010 ; Timer/Counter 2 Compare Match B | ||
+ | reti | ||
+ | .org 0x0012 ; Timer/Counter 2 Overflow | ||
+ | jmp Board_timer | ||
+ | .org 0x0014 ; Timer/Counter 1 Capture Event | ||
+ | reti | ||
+ | .org 0x0016 ; Timer/Counter 1 Compare Match A | ||
+ | reti | ||
+ | .org 0x0018 ; Timer/Counter 1 Compare Match B | ||
+ | reti | ||
+ | .org 0x001A ; Timer/Counter 1 Overflow | ||
+ | rjmp W1_timer | ||
+ | ;reti | ||
+ | .org 0x001C ; Timer/Counter 0 Compare Match A | ||
+ | reti | ||
+ | .org 0x001E ; Timer/Counter 0 Compare Match B | ||
+ | reti | ||
+ | .org 0x0020 ; Timer/Counter 0 Overflow | ||
+ | reti | ||
+ | .org 0x0022 ; SPI Serial Transfer Complete | ||
+ | reti | ||
+ | .org 0x0024 ; USART, Rx Complete | ||
+ | reti | ||
+ | .org 0x0026 ; USART, UDR Empty | ||
+ | reti | ||
+ | .org 0x0028 ; USART, Tx Complete | ||
+ | reti | ||
+ | .org 0x002A ; ADC Conversion Complete | ||
+ | jmp adc_conv | ||
+ | .org 0x002C ; EEPROM Ready | ||
+ | reti | ||
+ | .org 0x002E ; Analog Comparator | ||
+ | reti | ||
+ | .org 0x0030 ; Two-wire Serial Interface | ||
+ | jmp TWI_int | ||
+ | ;reti | ||
+ | .org 0x0032 ; Store Program Memory Read | ||
+ | reti | ||
+ | |||
+ | .org INT_VECTORS_SIZE | ||
+ | </code> | ||
+ | </hidden> | ||
+ | \\ | ||
+ | ====Текст модуля macr.asm==== | ||
+ | <hidden развернуть> | ||
+ | <code asm> | ||
+ | ;Макросы | ||
+ | ;----------------------------------------------------------------------- | ||
+ | .macro pushf | ||
+ | push r10 | ||
+ | in r10,SREG | ||
+ | push r10 | ||
+ | .endm | ||
+ | .macro popf | ||
+ | pop r10 | ||
+ | out SREG,r10 | ||
+ | pop r10 | ||
+ | .endm | ||
+ | .macro pushr | ||
+ | push r10 | ||
+ | in r10,SREG | ||
+ | push r10 | ||
+ | push r16 | ||
+ | push r17 | ||
+ | push r18 | ||
+ | push r19 | ||
+ | push r20 | ||
+ | push r21 | ||
+ | push r22 | ||
+ | push r23 | ||
+ | push r25 | ||
+ | push r26 | ||
+ | push r27 | ||
+ | push r28 | ||
+ | push r29 | ||
+ | .endm | ||
+ | .macro popr | ||
+ | pop r29 | ||
+ | pop r28 | ||
+ | pop r27 | ||
+ | pop r26 | ||
+ | pop r25 | ||
+ | pop r23 | ||
+ | pop r22 | ||
+ | pop r21 | ||
+ | pop r20 | ||
+ | pop r19 | ||
+ | pop r18 | ||
+ | pop r17 | ||
+ | pop r16 | ||
+ | pop r10 | ||
+ | out SREG,r10 | ||
+ | pop r10 | ||
+ | .endm | ||
+ | .macro check | ||
+ | push @0 | ||
+ | lds @0,@1 | ||
+ | sts UDR0,@0 | ||
+ | check_loop: ldi @0,UCSR0A | ||
+ | sbrs @0,TXC0 | ||
+ | rjmp check_loop | ||
+ | pop @0 | ||
+ | rcall Delay | ||
+ | .endm | ||
+ | |||
+ | .macro check_kosv | ||
+ | push @0 | ||
+ | ld @0,@1 | ||
+ | sts UDR0,@0 | ||
+ | check_loop1: ldi @0,UCSR0A | ||
+ | sbrs @0,TXC0 | ||
+ | rjmp check_loop1 | ||
+ | pop @0 | ||
+ | rcall Delay | ||
+ | .endm | ||
+ | .macro check1 | ||
+ | sts UDR0,@0 | ||
+ | check_loop1: ldi @0,UCSR0A | ||
+ | sbrs @0,TXC0 | ||
+ | rjmp check_loop1 | ||
+ | rcall Delay | ||
+ | .endm | ||
+ | |||
+ | .macro tabulate | ||
+ | push r16 | ||
+ | ldi r16,0x09 | ||
+ | check1 r16 | ||
+ | pop r16 | ||
+ | .endm | ||
+ | .macro newline | ||
+ | push r16 | ||
+ | ldi r16,0x0D | ||
+ | check1 r16 | ||
+ | ldi r16,0x0A | ||
+ | check1 r16 | ||
+ | pop r16 | ||
+ | .endm | ||
+ | </code> | ||
+ | </hidden> | ||
- | ;Библиотека_TWI | + | \\ |
- | ;----------------------------------------------------------------------- | + | ====Текст модуля twi_lib.asm==== |
+ | <hidden развернуть> | ||
+ | <code asm> | ||
- | ;======= Стартовая посылка по шине i2c ================================================= | + | ;Библиотека_TWI |
- | i2c_start: | + | ;----------------------------------------------------------------------- |
- | push r16 | + | |
- | ldi r16,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE) ; Выполняем посылку стартовой комбинации | + | ;======= Стартовая посылка по шине i2c ================================================= |
- | sts TWCR,r16 ; Посылаем полученный байт в TWCR | + | i2c_start: |
- | rcall i2c_wait ; Ожидание формирования start в блоке TWI | + | push r16 |
- | pop r16 ; Возвращаем данные в r16 из стека | + | ldi r16,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE) ; Выполняем посылку стартовой комбинации |
- | ret | + | sts TWCR,r16 ; Посылаем полученный байт в TWCR |
- | ;======= Стоповая посылка по шине i2c ================================================== | + | rcall i2c_wait ; Ожидание формирования start в блоке TWI |
- | i2c_stop: | + | pop r16 ; Возвращаем данные в r16 из стека |
- | push r16 | + | ret |
- | ldi r16,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN) ; Отправляем стоповую посылку | + | ;======= Стоповая посылка по шине i2c ================================================== |
- | sts TWCR,r16 ; Посылаем полученный байт в TWCR | + | i2c_stop: |
- | pop r16 ; Возвращаем данные в r16 из стека | + | push r16 |
- | ret | + | ldi r16,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN) ; Отправляем стоповую посылку |
- | ;======= Посылка байта информации по шине i2c ========================================== | + | sts TWCR,r16 ; Посылаем полученный байт в TWCR |
- | i2c_send: | + | pop r16 ; Возвращаем данные в r16 из стека |
- | push r16 | + | ret |
- | sts TWDR,r16 ; Записываем передаваемый байт в регистр TWDR | + | ;======= Посылка байта информации по шине i2c ========================================== |
- | ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWIE) ; Формируем байт, отвечающий | + | i2c_send: |
- | ; за пересылку информационного байта | + | push r16 |
- | sts TWCR,r16 ; Посылаем полученный байт в TWCR | + | sts TWDR,r16 ; Записываем передаваемый байт в регистр TWDR |
- | rcall i2c_wait ; Ожидание окончания пересылки байта | + | ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWIE) ; Формируем байт, отвечающий |
- | pop r16 ; Возвращаем данные в r16 из стека | + | ; за пересылку информационного байта |
- | ret | + | sts TWCR,r16 ; Посылаем полученный байт в TWCR |
- | ;======= Приём информационного байта по шине i2c ======================================= | + | rcall i2c_wait ; Ожидание окончания пересылки байта |
- | i2c_receive: | + | pop r16 ; Возвращаем данные в r16 из стека |
- | ; Принятый байт помещается в регистр r16, поэтому рекомендуется | + | ret |
- | ; продумать программу так, чтобы в этот момент в нём не было | + | ;======= Приём информационного байта по шине i2c ======================================= |
- | ; важной информации, байт не сохраняется в стеке в коде данной | + | i2c_receive: |
- | ; процедуры | + | ; Принятый байт помещается в регистр r16, поэтому рекомендуется |
- | ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWEA)|(1<<TWIE) ; Формируем байт, отвечающий за прием | + | ; продумать программу так, чтобы в этот момент в нём не было |
- | sts TWCR,r16 ; Посылаем полученный байт в TWCR | + | ; важной информации, байт не сохраняется в стеке в коде данной |
- | rcall i2c_wait ; Ожидание окончания приёма байта | + | ; процедуры |
- | lds r16,TWDR ; Считываем полученную информацию из TWDR | + | ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWEA)|(1<<TWIE) ; Формируем байт, отвечающий за прием |
- | ret | + | sts TWCR,r16 ; Посылаем полученный байт в TWCR |
- | ;======= Приём последнего байта (NACK) ================================================= | + | rcall i2c_wait ; Ожидание окончания приёма байта |
- | i2c_receive_last: | + | lds r16,TWDR ; Считываем полученную информацию из TWDR |
- | ; Принятый байт помещается в регистр r16, поэтому рекомендуется | + | ret |
- | ; продумать программу так, чтобы в этот момент в нём не было | + | ;======= Приём последнего байта (NACK) ================================================= |
- | ; важной информации, байт не сохраняется в стеке в коде данной | + | i2c_receive_last: |
- | ; процедуры | + | ; Принятый байт помещается в регистр r16, поэтому рекомендуется |
- | ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWIE) ; Формируем байт, отвечающий за прием информационного байта | + | ; продумать программу так, чтобы в этот момент в нём не было |
- | sts TWCR,r16 ; Посылаем полученный байт в TWCR | + | ; важной информации, байт не сохраняется в стеке в коде данной |
- | rcall i2c_wait ; Ожидание окончания приёма байта | + | ; процедуры |
- | lds r16,TWDR ; Считываем полученную информацию из TWDR | + | ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWIE) ; Формируем байт, отвечающий за прием информационного байта |
- | ret | + | sts TWCR,r16 ; Посылаем полученный байт в TWCR |
- | ;======= Ожидание готовности TWI ======================================================= | + | rcall i2c_wait ; Ожидание окончания приёма байта |
- | i2c_wait: | + | lds r16,TWDR ; Считываем полученную информацию из TWDR |
- | lds r16,TWCR ; Загружаем значение из TWCR в r16 | + | ret |
- | sbrs r16,TWINT ; Функция ожидания выполняется до тех пор, пока поднят флаг | + | ;======= Ожидание готовности TWI ======================================================= |
- | ; прерывания в 1 | + | i2c_wait: |
- | rjmp i2c_wait | + | lds r16,TWCR ; Загружаем значение из TWCR в r16 |
- | ret | + | sbrs r16,TWINT ; Функция ожидания выполняется до тех пор, пока поднят флаг |
- | ;======================================================================================= | + | ; прерывания в 1 |
- | </file> | + | rjmp i2c_wait |
+ | ret | ||
+ | ;======================================================================================= | ||
+ | </code> | ||
+ | </hidden> |