
- •Курсовой проект
- •Структурная схема
- •Выбор компонентов Анализ заданной микросхемы ad7495
- •Выбор микроконтроллера
- •Выбор жки экрана
- •Для реализации проекта понадобятся следующие устройства:
- •Принципиальная электрическая схема Пояснения к электрической схеме
- •О бщий алгоритм работы
- •Усреднение
- •Интерфейс spi
- •Листинг программы
- •Заключение
- •Список литературы
Листинг программы
Основной:
.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 ; Возвращаемся.