Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Падалко кп мпс (Восстановлен).docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
965.19 Кб
Скачать

Листинг программы

Основной:

.include " hd44780.с" ; Используем HD44780

.include "m16def.inc" ; Используем ATMega16

.include "define.asm" ; определения переменных

.include "macro.asm" ; Все макросы

.include "vectors.asm" ; Все вектора прерываний

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

.ORG INT_VECTORS_SIZE

Reset: OUTI SPL,low(RAMEND)

OUTI SPH,High(RAMEND)

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

.include "init.asm" ; Все инициализации.

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

Main: SEI ; Разрешаем прерывания.

SET SPE ; Если бит установлен в 1, модуль SPI включен.

SET SPIE ; Если бит установлен в 1, прерывания от SPI разрешены.

RJMP Main

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

; Interrupts

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

; Прерывание от SPI на передачу

SPI_TX: PUSH R16 ; регистры в стеке

IN R16,SREG

PUSH R16

; Сумма набрана в прерывании по АЦП

CLC ; Сбрасываем флаг переноса

; ROR - операция циклического сдвига операнда вправо.

ROR SUMH ; И сдвигаем значение вправо сначала старший

ROR SUML ; потом младший. Через флаг переноса.

CLC ; Всего нам надо 4 сдвигов 2^4=16

ROR SUMH ; Что будет эквивалентно делению на 16

ROR SUML

CLC

ROR SUMH

ROR SUML

CLC

ROR SUMH ; 10 байтное усредненное число

ROR SUML ; отбрасывем еще два младших бита, превращая число

; в восьмибитное, через перенос

CLC

ROR SUMH

ROR SUML

CLC

ROR SUMH

ROR SUML ; старший байт равен нулю

; число находится в младшем байте SUML

OUT SPDR,SUML ; Его то мы и отсылаем в SPI.

; отправка идет исключительно по прерыванию

POP R16 ; Достаем из стека регистры

OUT SREG,R16

POP R16

RETI ; Выход из прерывания

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

; Прерывание от SPI на прием

UART_RX: PUSH R16 ; Прячем в стек регистры

IN R16,SREG

PUSH R16

IN R16,UDR ; Берем пойманный байт

CPI R16,'s' ; И анализируем. Если S - значит стоп

BREQ StopADC

CPI R16,'r' ; Если r значит - запуск.

BREQ RunADC

; Запускаем АЦП, на непрерывное преобразование и включаем SPI на передачу

RunADC: SPCR, (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);

OUTI SPDR,'R'

RJMP ExitRX

StopADC: OUTI SPCR, (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);

ExitRX: POP R16 ; Достаем из стека регистры

OUT SREG,R16

POP R16

RETI ; Выходим в главный цикл

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

; Прерывание от АЦП - обработка завершена

ADC_OK: PUSH R16 ; Сохранить регистры в стеке

PUSH R17

IN R16,SREG ; Сохранить SREG

PUSH R16

; Определяем ряд макросов для удобства использования

.def ADSH = R15 ; Старший байт суммы

.def ADSL = R14 ; Младший байт суммы

.def ACT = R13 ; Счетчик усредняемых значений

.def SUMH = R12 ; Выходной регистр старший

.def SUML = R11 ; Выходной регистр младший

IN R16,ADCL ; Взять значение из АЦП

IN R17,ADCH

; Теперь пару R17:R16 надо просуммировать с их n-1 значением. При первой итерации

; ноль. При второй уже будет сумма с первой выборкой и так далее.

ADD ADSL,R16 ; Младший байт суммируем без переноса

ADC ADSH,R17 ; Старший байт суммируем с учетом переноса

; В результате, в ADSH:ASSL будет накоплена сумма ADSH:ASSL(n) + ADSH:ASSL(n+1)

; Максимальное значение для 10битного АЦП - 1024, в то время как в 16разрядах

; Помещается 65536 значений, 65536/1024 = 64. Поэтому переменная АСТ должна быть

; Заранее инициализирована числом 64

DEC ACT ; Считаем сколько уже выборок мы сделали

BRNE Exit ; Если это не последнее слагаемое, то выход

MOV SUML,ADSL ; Записываем выходное значение в регистр

MOV SUMH,ADSH ; младший и старший байты

CLR ADSL ; Потом мы очищаем регистры суммирования

CLR ADSH ; Чтобы новый результат был с нуля

LDI R16,64 ; Заполняем счетчик новым числом

MOV ACT,R16

Exit: POP R16 ; Достаем из стека все как было.

OUT SREG,R16

POP R17

POP R16

RETI ; Возвращаемся.