
.include "d:\Program Files\AVRStudio4_Tools\AvrAssembler\Appnotes\m168def.inc"

 
 ; объявление названий регистров
 
.def rTempReg=r16                 ; используется для всего подряд
.def rAddressReg=r17              ; хранит адрес в памяти (SRAM,EEPROM или ещё где-то)
.def rConstReg=r18                ; хранит константы
.def rMyCounterReg=r19            ; название регистра для счёта битов
.def rAdditionReg1=r20
.def rAdditionReg2=r21
.def rSaveSenseReg=r22            ; регистр хранения данных
.def rInterruptReg=r23            ; регистр хранит данные связанные с обработкой прерываний
.def rKeepLowByteReg=r1           ; хранит младший байт двухбайтных данных 
.def rKeepHighByteReg=r2          ; хранит старший байт двухбайтных данных

; объявление линий контроллера
; линии, вылеленныые @ - доступны для управления как внутренним, так и внешним устройствам

; так как часть кода из прошлой версии не нравится ассемблеру, буду называть порты по-другому 
;.equ SDA=PortB.0              ; @-линия SDA шины I2С
.equ SDA_B=0                   ; будет называть бит порта В (объявить нужно в проге) 
;.equ SCL=PortB.1              ; @-линия SCL шины I2С
.equ SCL_B=1                   ; (объявить нужно в проге)  
;.equ WirePort=PortB.2          ; @-линия шины OneWire
.equ WirePort_B=2
;.equ KbrdIn=PortB.3            ; @-линия ввода состояния кнопок
.equ KbrdIn_B=3
;.equ Ind2=PortB.4              ; это IA2 бит номера индикатора на исплее и номер кнопки при опросе клавы 
.equ IA2_PB=2                   ; вывод IA2 -  на PortB.2 (для ATmega168) 
;.equ Ind1=PortB.5              ; это IA1 бит номера индикатора на исплее и номер кнопки при опросе клавы 
.equ IA1_PB=3                   ; вывод IA1 -  на PortB.3 (для ATmega168) 
;.equ Ind0=PortB.6              ; это IA0 бит номера индикатора на исплее и номер кнопки при опросе клавы 
.equ IA0_PB=4                   ; вывод IA0 -  на PortB.4 (для ATmega168) 
;.equ WDC=PortB.7               ; сброс Watch-Dog таймера
.equ WDC_B=7
;.equ INTERRUPT=PortD.3         ; прерывание от будильника (у него так)
.equ INTERRUPT_D=3
;.equ DC=PortD.4                ; импульс сдвига в регистр индикации
.equ DC_PD=4
;.equ DD=PortD.6                ; данные для записи в регистр индикации
.equ DD_PD=7

; линии, доступные для управления только внешними устройствам и

;.equ RxD=PortD.0               ; RxD
.equ RxD_D=0
;.equ TxD=PortD.1               ; TxD
.equ TxD_D=1
;.equ INT_0=PortD.2              ; запрос на прерывание высшего приоритета

;.equ T1=PortD.5                ; счётный вход таймера1 (у него)
.equ T1_D=5
    
;================================================================= 

 .CSEG

; символы, константы, относящиеся к дисплею и индикации
.equ _Letter1=0b00000000             ; восьмёрка с включенной точкой                                                                           
.equ _Letter2=0b10111111             ; МИНУС
.equ _Letter3=0b11110111             ; штрих внизу
.equ _Letter4=0b11101111             ; штрих слева внизу
.equ _Letter5=0b11011111             ; штрих слева вверху
.equ _Letter6=0b11111110             ; штрих сверху
.equ _Letter7=0b11111101             ; штрих справа сверху
.equ _Letter8=0b11111011             ; штрих справа внизу
.equ _Letter9=0b01111111             ; точка 
.equ _Letter10=0b11111111            ; SPACE - прочерк (пустое место)
.equ _Letter11=0b10011100            ; знак градуса Цельсия
.equ _Letter12=0b11000000            ; цифра 0  ($3F)
.equ _Letter13=0b11111001            ; цифра 1  ($6)
.equ _Letter14=0b10100100            ; цифра 2  ($5B)
.equ _Letter15=0b10110000            ; цифра 3  ($4F) 
.equ _Letter16=0b10011001            ; цифра 4  ($66)
.equ _Letter17=0b10010010            ; цифра 5  ($6D)  
.equ _Letter18=0b10000010            ; цифра 6  ($7D)
.equ _Letter19=0b11111000            ; цифра 7  ($7)
.equ _Letter20=0b10000000            ; цифра 8  ($7F)
.equ _Letter21=0b10010000            ; цифра 9  ($6F)
.equ _Letter22=0b10001000            ; буква A  ($77)
.equ _Letter23=0b10000011            ; буква b  ($7C)    
.equ _Letter24=0b11000110            ; буква C  ($39)
.equ _Letter25=0b10100001            ; буква d  ($5E)
.equ _Letter26=0b10000110            ; буква Е  ($79)  
.equ _Letter27=0b10001110            ; буква F  ($71)
.equ _Letter28=0b10010000            ; буква g  ($7D)
.equ _Letter29=0b10001001            ; буква H  ($76)
.equ _Letter30=0b11111011            ; буква i  ($3)
.equ _Letter31=0b11110001            ; буква J  ($E)
.equ _Letter32=0b11000111            ; буква L  ($38)
.equ _Letter33=0b10101011            ; буква n  ($54)
.equ _Letter34=0b11000000            ; буква О  ($3F)
.equ _Letter35=0b10001100            ; буква P  ($73)
.equ _Letter36=0b10101111            ; буква R  ($77)
.equ _Letter37=0b10010010            ; буква S  ($6D)    
.equ _Letter38=0b10000111            ; буква t  ($78)
.equ _Letter39=0b11100011            ; буква u  ($1C)  (то есть "ю"-англ.)
.equ _Letter40=0b11000001            ; буква V  ($3E)
.equ _Letter41=0b10010001            ; буква y  ($6E)
.equ _Letter42=0b10011111            ; буква r  ($60)  (маленькая)
.equ _Letter43=0b10100011            ; буква о  ($5C)  (маленькая)
.equ _Letter44=0b10100111            ; буква с  ($58)  (маленькая)

; режимы работы М-контроллера(находятся в переменной @Mode)
.equ _TestMode=0b00000001       ; тестовый режим работы МК
.equ _KbdMode=0b00000010        ; режим опроса клавы
.equ _IndMode=0b00000011        ; режим индикации и вывода значений
.equ _TemprMode=0b00000100       ; режим измерения температуры
.equ _EXramMode=0b00000101      ; режим работы с внешней памятью
.equ _TimerMode=0b00000110      ; режим работы таймера 
.equ _HoursMode=0b00000111      ; режим вывода времени на дисплей
.equ _AlarmMode=0b00001000      ; режим ввода значения в будильник

; мигания и его типы
.equ _BlinkNO=0b00000000        ; не мигать! 
.equ _BlinkAll=0b00000001       ; мигание всеми индикаторами
.equ _BlinkOne=0b00000010       ; мигание одного индикатора
.equ _BlinkName=0b00000100      ; мигать "именем" параметра
.equ _BlinkValue=0b00001000     ; мигать "значением" параметра

;=================================================================
.DSEG                         ; адресное пространство SRAM
;.ORG $60                      ; это адрес начала SRAM для ATtiny2313
.ORG $100                      ; это адрес начала SRAM для ATmega168

sSCR: .BYTE 6                  ; экранная область      
.equ Pos1=sSCR                 ; присвоение имён всем 6-ти позициям индикатора
.equ Pos2=sSCR+1               ; в данные ячейки записываються соответ-щие символы для вывода на
.equ Pos3=sSCR+2               ; индикатор
.equ Pos4=sSCR+3
.equ Pos5=sSCR+4
.equ Pos6=sSCR+5
sMode: .BYTE 1                 ; переменная содержит текущий режим работы МК
sBlink: .BYTE 1                ; переменная содержит разрешение мигания и режим мигания
sDataType_Division: .BYTE 1    ; переменная содержит типы выводимых на дисплей данных и способ деления дисплея
sSeconds: .BYTE 1              ; содержит количество секунд в режиме таймера    
sMinutes: .BYTE 1              ; содержит количество минут 
sHours: .BYTE 1                ; содержит количество часов 
sTimerSet_ms: .BYTE 1          ; установленное в будильнике значение милисекунд
sTimerSet_sec: .BYTE 1         ; установленное в будильнике значение секунд
sTimerSet_minutes: .BYTE 1     ; установленное в будильнике значение минут
sTimerSet_hours: .BYTE 1       ; установленное в будильнике значение часов
sSwitcherDD: .BYTE 1           ; содержит количество обновлений дисплея
sBitsSave: .BYTE 1             ; хранит в битах "индикаторы" состояния необходимых процессов
sInterfaceMode: .BYTE 1        ; хранит режими интерфейсного оборудования, виты устанавливаются в "1" при срабатывании оборуд. 
sPushButton_State: .BYTE 1     ; в битах хранятся состояния кнопок клавиатуры. "1" - кнопка нажата
sPushButton_Memory: .BYTE 1    ; в битах хратятся состояния кнопок при опросе клавиатуры в предыдущем прерывании
sItemMenu_Number: .BYTE 1      ; номер пункта меню, который был активным при предыдущем обращении к меню 
sSubMenu_Number: .BYTE 1       ; номер текущего подменю

sSTACK_PRT: .BYTE 1            ; похоже, это метка конца области памяти данных (макс. адрес)

; НИЖЕ НЕ ДОЛЖНО БЫТЬ ОПИСАНИЯ РАБОЧИХ ЯЧЕЕК!!!

;==================================================================================
.ESEG
; содержимое EEPROM памяти


;==================================================================================
.CSEG

.ORG $0                       
; векторы прерываний ATMEGA168 - несколько специально зарезервированных адресов в начале памяти программ предназначенных для обслуживания прерываний
; обработка прерываний (векторы прерываний  и команды перехода на обработку этих прерываний)

rjmp Reset                     ; обработка прерывания по сбросу
rjmp INT_0                     ; IRQ0 - запрос внешнего прерывания 0
rjmp INT_1                     ; IRQ1 - запрос внешнего прерывания 1
rjmp PinChangeINT0             ; прерывание изменения пина 0
rjmp PinChangeINT1             ; прерывание изменения пина 1  
rjmp PinChangeINT2             ; прерывание изменения пина 2
rjmp WDT                       ; при ... WD таймера  	
rjmp Timer2_CompA              ; при совпадении А ТС2
rjmp Timer2_CompB              ; при совпадении В ТС2
rjmp Timer2_OVF2               ; при переполнении ТС2
rjmp Timer1_capt1              ; захват Т1
rjmp Timer1_compA              ; при совпадении А Т1
rjmp Timer1_compB              ; при совпадении В Т1
rjmp Timer1_OVF1               ; переполнение Т1
rjmp Timer0_CompA              ; при совпадении А Т0
rjmp Timer0_CompB              ; при совпадении В Т0 
rjmp Timer0_OVF0               ; при переполнение Т0      
rjmp SPI_STC                   ; передача по SPI закончена
rjmp USART_RX                  ; 
rjmp USART_UDRE
rjmp USART_TX
rjmp ADC_Conversion            ; АЦП преобразование завершено
rjmp EEPROM_READY              ; EEPROM готово 
rjmp ANALOG_COMP                  ; аналоговый компаратор
rjmp TWI                       ; 2-проводной последовательный интерфейс 
rjmp SPM_READY                 ; память хранения программ готова ???

      

;обработчики не использованных прерываний
;Reset:
INT_0: ; - не знаю, почему-то компилятор выпендриваеться
nop
INT_1:
nop
PinChangeINT0:
nop
PinChangeINT1:
nop
PinChangeINT2:
nop
WDT:
nop
Timer2_CompA:
nop
Timer2_CompB: 
nop
Timer2_OVF2:
nop
Timer1_capt1:
;reti
nop
Timer1_compA:
nop
Timer1_compB:
nop
Timer1_OVF1:                  ; обработка прерывания по переполнению Т1
;Timer0_CompA:
nop
Timer0_CompB:
;Timer0_OVF0:
nop
SPI_STC:
nop
USART_RX:
nop
USART_UDRE:
nop
USART_TX:
nop
ADC_Conversion:
nop
EEPROM_READY:
nop
ANALOG_COMP:
nop
TWI:
nop
SPM_READY:
nop
nop
nop
nop
nop
reti                          ; команда-заглушка
;==================================================================================
Reset: 
; определения типа Резета

ldi r16,high(RAMEND)                 ; инициализация стека
out SPH,r16                    ; ???почему-то в SP загружаеться 0xFF, а не 0x6В (уже загружается $DF)
ldi r16,low(RAMEND)
out SPL,r16 
cli                            ; запрет всех прерываний

nop
nop
nop
nop
nop
rjmp Reset_Cold
;*************************************************************************************
;*************************************************************************************

Timer0_OVF0:
nop
nop
nop
nop
nop
reti

Timer0_CompA:
	
;*************************************************************************************
;*************************************************************************************

;*************************************************************************************
;*************************************************************************************

;------------------ ИНИЦИАЛИЗАЦИЯ --------------------------------------------------
Reset_Cold:                   
; при холодном резете(при вкл. устройства проводим инициализацию)

ldi rTempReg,_TestMode
sts sMode,rTempReg             ; установка начального режима работы
ldi rTempReg,_BlinkNO
sts sBlink,rTempReg            ; установка запрета на мигание                              
ldi rTempReg,_Letter1
sts Pos1,rTempReg              ; установка начальных значений символов для индикации, то есть
sts Pos2,rTempReg              ; "пустого места" для всех разрядов индикатора
sts Pos3,rTempReg
sts Pos4,rTempReg
sts Pos5,rTempReg
sts Pos6,rTempReg                               
;ldi rTempReg,0b01110000
;out DDRB,rTempReg              ; сконфигурировать только IA0,IA1,IA2 порта Б как выходы  
sbi DDRB,IA0_PB
sbi DDRB,IA1_PB
sbi DDRB,IA2_PB
;ldi rTempReg,0b01010000
;out DDRD,rTempReg              ; сконфигурировать только DC,DD порта D как выходы 
sbi DDRD,DC_PD
sbi DDRD,DD_PD

ldi rTempReg,$0
ldi ZH,HIGH(sSeconds)
ldi ZL,LOW(sSeconds)           ; обнуление ячеек ОЗУ, связанных с таймером1
st Z+,rTempReg                 ; текущее значение секунд 
st Z+,rTempReg                 ; текущее значение минут 
st Z+,rTempReg                 ; текущее значение часов
st Z+,rTempReg                 ; милисекунды
st Z+,rTempReg                 ; секунды
st Z+,rTempReg                 ; минуты
st Z+,rTempReg                 ; часы 

sts sInterfaceMode,rTempReg 
sts sPushButton_State,rTempReg 
sts sPushButton_Memory,rTempReg 
sts sItemMenu_Number,rTempReg
sts sSubMenu_Number,rTempReg

; инициализация MCUCR
ldi rTempReg,$0
set
bld rTempReg,1	                 ; IVSEL=1
;sts $55,rTempReg               ; установка бита регистра РВВ MCUCR

; инициализация Т0
ldi rTempReg,0b00000000        ; TCCR0A - загрузка, указывал здесь адрес рег-ра $30
out TCCR0A,rTempReg 
clr rTempReg
ldi rTempReg,(1<<CS02)+(0<<CS01)+(0<<CS00)
;ldi rTempReg,0b00000100        ; TCCR0B - загрузка, указывал адрес геристра $33
out TCCR0B,rTempReg            ; CS02=1;CS01=0; CS00=0; установка f тактирования Т0=f0/256 (F обновления дисплея=152,579Гц) 
clr rTempReg                   ; очистить регистр 
ldi rTempReg,(1<<TOIE0)+(1<<OCIE0A)        ; TOIE0=1 - разрешение прерывания  по переполнению Т0
sts $6E,rTempReg               ; out TIMSK0,rTempReg   = ; TIMSK - загрузка           
ldi rTempReg,$0                
sts sSwitcherDD,rTempReg       ; обнуление количества обновлений дисплея
sts sBitsSave,rTempReg         ; обнуление битов sBitsSave

ldi rTempReg,$1
out OCR0A,rTempReg
; инициализация Т1

sei                            ; разрешил все прерывания                
;*************************************************************************************
;*************************************************************************************

Proceed_Calculation:           ; основная подпрограмма

;ldi rTempReg,_Letter10
;mov r0,rTempReg
;ldi YH,$0 ; HIGH(rTempReg)
;ldi YL,$10 ; LOW(rTempReg)
;ld r4,Y
;st Y,r17
nop
nop
ldi rTempReg,$1
mov r15,rTempReg
ldi rTempReg,1
mov r14,rTempReg
ldi rTempReg,2
mov r13,rTempReg
ldi rTempReg,3
mov r12,rTempReg
ldi rTempReg,4
mov r11,rTempReg
ldi rTempReg,5
mov r10,rTempReg
ldi rTempReg,6
mov r9,rTempReg
nop
nop
;ldi ZL,LOW(2*(CelsiumDegree))
;ldi ZH,HIGH(2*(CelsiumDegree))
ldi rTempReg,0b10001000
sts sDataType_Division,rTempReg	
;call PushButton_Menu_Processing
;call ValueName_To_sSCR
nop
nop
nop
rjmp Proceed_Calculation

;*************************************************************************************
;*************************************************************************************
