; ******************************************************
; * Автор: СКАЗОЧНИК 								   *                           
; * Дата: 21.05.2013                                   *                                              
; * Версия: 130521                                     *                                            
; * Имя файла: Управление сервоприводом и энкодером    *                                      
; * Для AVR: ATTiny2313                                *                                                    
; * Тактовая частота: 8 MHz	(внутренняя RC)			   *
; * Среда разработки: AVR Studio 4.12				   *
; *													   *
; * Выполняемые функции: Программа тест для управления *
; * китайским сервоприводом в ноге хексапода с помощью *
; * простого мех-го энкодера от компьютерной мыши      *
; ******************************************************

; ==================================
; ПОДКЛЮЧАЕМЫЕ БИБЛИОТЕКИ (.include)
; ==================================

	.include "tn2313def.inc"	

; ==============================
; ТИП МИКРОКОНТРОЛЛЕРА (.device)
; ==============================

	.device ATtiny2313
 
; ===================================
; ОБЪЯВЛЕНИЯ И КОНСТАНТЫ (.def, .equ)
; ===================================
 
	.def	temp = R16			
	.def 	ugol = R18		; Для выставления угла поворота 
	.def 	t1 = R19
	.def	t2 = R20
	.def 	encoder = R22
	.def	newenc = R23

; ========================================
; МАССИВЫ И Т.Д. (.eseg) EEPROM (.db, .dw)
; ========================================
	
	.eseg

; ******************************
; НАЧАЛО ПРОГРАММЫ (.cseg) FLASH
; ******************************
	
	.cseg

; ------------------
; ВЕКТОРЫ ПРЕРЫВАНИЙ
; ------------------
	
	rjmp RESET 			; Reset Handler
 	rjmp INT_0 			; External Interrupt0 Handler
 	rjmp INT_1 			; External Interrupt1 Handler
 	rjmp TIM1_CAPT 		; Timer1 Capture Handler
 	rjmp TIM1_COMPA 	; Timer1 CompareA Handler
 	rjmp TIM1_OVF 		; Timer1 Overflow Handler
	rjmp TIM0_OVF 		; Timer0 Overflow Handler
	rjmp USART0_RXC 	; USART0 RX Complete Handler
	rjmp USART0_DRE 	; USART0,UDR Empty Handler
	rjmp USART0_TXC 	; USART0 TX Complete Handler
	rjmp ANA_COMP 		; Analog Comparator Handler
	rjmp PCINT 			; Pin Change Interrupt
	rjmp TIMER1_COMPB 	; Timer1 Compare B Handler
	rjmp TIMER0_COMPA 	; Timer0 Compare A Handler
	rjmp TIMER0_COMPB 	; Timer0 Compare B Handler
	rjmp USI_START 		; USI Start Handler
	rjmp USI_OVERFLOW 	; USI Overflow Handler
	rjmp EE_READY 		; EEPROM Ready Handler
	rjmp WDT_OVERFLOW 	; Watchdog Overflow Handler
	
	
	;RESET 			; Reset Handler
 	INT_0: 			; External Interrupt0 Handler
 	INT_1:			; External Interrupt1 Handler
 	TIM1_CAPT: 		; Timer1 Capture Handler
 	TIM1_COMPA: 	; Timer1 CompareA Handler
 	TIM1_OVF: 		; Timer1 Overflow Handler
	TIM0_OVF: 		; Timer0 Overflow Handler
	USART0_RXC: 	; USART0 RX Complete Handler
	USART0_DRE: 	; USART0,UDR Empty Handler
	USART0_TXC: 	; USART0 TX Complete Handler
	ANA_COMP: 		; Analog Comparator Handler
	PCINT: 			; Pin Change Interrupt
	TIMER1_COMPB: 	; Timer1 Compare B Handler
	;TIMER0_COMPA: 	; Timer0 Compare A Handler исправил в ТН2313ДЕФ.ИНК
	TIMER0_COMPB: 	; Timer0 Compare B Handler исправил в ТН2313ДЕФ.ИНК
	USI_START: 		; USI Start Handler
	USI_OVERFLOW: 	; USI Overflow Handler
	EE_READY: 		; EEPROM Ready Handler
	WDT_OVERFLOW: 	; Watchdog Overflow Handler
	
	reti			; Выход из прерываний, которые не используются

; ----------------------
; ОБРАБОТЧИКИ ПРЕРЫВАНИЙ
; ----------------------

 	TIMER0_COMPA:	in temp, SREG 	; Сохраняем значение СРЕГ в стек
					push temp
	
					in temp, PINB
					andi temp, 0b00000001
					cpi temp, 1	; Сравниваем значение переменной и 1, если равно, значение 0!!!
					breq Pauza		; Если предыдущий 0, значит переход на Пауза

				
							ldi temp, 0b00000111	; Ставим порт
					    	out PORTB, temp

							ldi temp, 0b00000100   	; Тактовый сигнал = CK/256
							out TCCR0B, temp

							out OCR0A, ugol			; Инициализация компаратора А (0.8 мс)

							ldi temp, 0             ; Обнуление таймера
							out TCNT0, temp

							pop temp				; Восстанавливаем значение СРЕГ из стека
							out SREG, temp
							
							reti

					Pauza:	ldi temp, 0b00000110	; Сбрасываем порт
						    out PORTB, temp

							ldi temp, 0b00000101   	; Тактовый сигнал = CK/1024
							out TCCR0B, temp

							ldi temp, 0x8C          ; Инициализация компаратора А (18 мс)
							out OCR0A, temp

							ldi temp, 0             ; Обнуление таймера
							out TCNT0, temp

							pop temp				; Восстанавливаем значение СРЕГ из стека
							out SREG, temp

							reti

; **************************************************************************************************
; ИНИЦИАЛИЗАЦИЯ МК (логическое начало основной программы) ******************************************
; **************************************************************************************************

;           --------- конфигурация портов -----------------------------------------------           

	Reset:	ldi temp, 0b00000001	; Конфигурируем порт B 
			out DDRB, temp			; Направление порта В (РВ0 на выход, остальные вход)
			ldi temp, 0b00000111
			out PORTB, temp			; Сразу выводим единицу в РВ0, а РВ1 и РВ2 подтяжка
			
;			---------- начальные значения переменных, массивы ---------------------------
			          
			ldi ugol, 0x19
			
			in encoder, PINB			; Загружаем значение порта в переменную
			;andi encoder, 0b00000110	; Накладываем маску (вычисляем только РВ1 и РВ2)
			cbr encoder, 0b11111001		; Аналогично (см. выше) делает И-НЕ
		
;           ----- конфигурация прерываний, стека, аналогового компаратора, таймеров -----

			ldi temp, 0xFF	
			out EIFR, temp			; Сбросить флаги внешних прерываний 
			
			ldi temp, RAMEND		; Загрузка указателя стека
			out SPL, temp

			ldi temp, 1<<ACD 		; Выключаем аналоговый компаратор (для меньшего потребления)
			out ACSR, temp 			

			ldi temp, 0b00000010	; Включаем режим СТС при совпадении с каналом А, таймер обнуляется
			out TCCR0A, temp

			ldi temp, 0b00000100   	; Тактовый сигнал = CK/256
        	out TCCR0B, temp

 			out OCR0A, ugol			; Инициализация компаратора А (0.8 мс)

			ldi temp, 0xFF   		; Сброс флагов прерываний таймера
        	out TIFR, temp

			ldi temp, 0b00000001    ; Разрешить прерывание компаратора таймера 0, канал А 
          	out TIMSK, temp

			ldi temp, 0             ; Обнуление таймера
          	out TCNT0, temp
            			       	
;           ---------- разрешение прерываний --------------------------------------------			

			sei						; Разрешаем прерывания	

; ***************************************************************************************************
; ОСНОВНАЯ ПРОГРАММА (основной цикл) ****************************************************************
; ***************************************************************************************************

	Start:	in newenc, PINB
			;andi newenc, 0b00000110	; Закидываем в переменную новое значение энкодера
			cbr newenc, 0b11111001	; Аналогично (см. выше)

			cpi encoder, 0b00000000
			breq Obr1
			cpi encoder, 0b00000010
			breq Obr2
			cpi encoder, 0b00000100
			breq Obr3
			cpi encoder, 0b00000110
			breq Obr4

			Obr1:	cpi newenc, 0b00000100
					breq Else 
					cpi newenc, 0b00000010
					breq Else1
					rjmp Del1
					Else: inc ugol
					rjmp Del2
					Else1: dec ugol
					rjmp Del2

			Obr2:	cpi newenc, 0b00000000
					breq Else2 
					cpi newenc, 0b00000110
					breq Else3
					rjmp Del1
					Else2: inc ugol
					rjmp Del2
					Else3: dec ugol
					rjmp Del2

			Obr3:	cpi newenc, 0b00000110
					breq Else4 
					cpi newenc, 0b00000000
					breq Else5
					rjmp Del1
					Else4: inc ugol
					rjmp Del2
					Else5: dec ugol
					rjmp Del2

			Obr4:	cpi newenc, 0b00000010
					breq Else6 
					cpi newenc, 0b00000100
					breq Else7
					rjmp Del1
					Else6: inc ugol
					rjmp Del2
					Else7: dec ugol
					rjmp Del2


	
			Del2: 	mov encoder, newenc
			Del1:
					ldi t1, 0
					ldi t2, 5
					
			Loop1: 	dec t1
					brne loop1
					dec t2
					brne loop1
				
					
	rjmp	Start	; Конец программы, переход на начало

