.include	"m128def.inc"



.def temp = r16
.def Direct_value = r17
.def CountDel = r18
.def Time_Value = r19
.def Uart_Recep = r20
.def Uart_Trans = r21
;----------------------------- Начало програмного кода--------------------------------;
.cseg						   
.org 0

;----------------------------- Вектора прерывания ------------------------------------;
start:
rjmp			init				;Нулевой адрес, переход на инициализацию.
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
rjmp			inter1				;Таймер счетчик 1, совпадение, Канал A.
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;			Модуль инициализации			  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;

init:
rcall Timer_On
;-------------------------------------------инициализция стека--------------------------------------------------------------;
	
	ldi		temp,low(RAMEND)	
	out		spl,temp			
	ldi		temp,high(RAMEND)	
	out		sph,temp

;-------------------------------------------инициализация портов------------------------------------------------------------;
	ldi		temp,0xff			
	out		DDRD,temp			;Выключаем двигатель
	ldi		temp,0xff			
	out		PORTD,temp
	
	ldi		temp, 0b11110000	;Кнопки управления с джойстика
	out		PORTE,temp
	
	ldi		temp, 0b11110000	;Стоп кнопки
	out		PORTC,temp
	

;--------------------------------------------инициализация UART-------------------------------------------------------------;
	
	ldi temp,51					;Скорость 9600					
	out UBRR0L, temp


	ldi temp,0					;програмно обнуляем регистор статуса 
	out UCSR0A, temp


	
	ldi temp, (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)	;прерывания запрещены, прием-передача разрешена
	out UCSR0B, temp

		LDI R16, (1<<UMSEL0)|(1<<UCSZ00)|(1<<UCSZ01)
	out UCSR0C,temp


	
;----------------------------------------------инициализация таймера----------------------------------------------------------;            
Timer_init:


ldi		temp,high(19000)		;  загружаем в компаратор значение 19000
out		OCR1AH,temp				
ldi		temp,low(19000)			
out		OCR1AL,temp				

clr		temp					
out		TCNT1H,temp				;обнуляем счетчик
out		TCNT1L,temp				
;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;					M A I N					  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;

main:

rjmp main						;бесконечный цикл




;----------------------------------------------инициализаия подпрограммы задержки---------------------------------------------;	
Delay_Init:
				
	ldi	Uart_Trans,'D'			;Отправляем на ПК, что бы он высылал значение,
	rcall Uart_Send				;задержки, тем самым регулируя скорость вращения.
	rcall Uart_Get				;Принимаем значение задержки
	mov CountDel, Uart_recep
	
reti
;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;			Подпрограмма задержки			  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;


Delay:
	dec CountDel				; Уменьшаем счетчик на единицу
	nop							; Пустой такт
	cpi	CountDel, 0				; Сравниваем temp со счетчиком и пока он не ноль прыгаем на delay и выполняем пустой цикл.
	brne delay	
ret							


;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;		Разрешение и запрет на прерывание	  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;

;Разрешаем прерывания
Timer_ON:
	clr		temp
	ldi		temp,(1<<4)  	
	out		TIMSK,temp
ret

;Запрещаем прерывания
Timer_Off:
	clr		temp
	ldi		temp,0   
	out		TIMSK,temp
ret

;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;		Подпрограмма отправки по UART		  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;
								

Uart_Send:
	sbis 	UCSR0A,UDRE0		;пропуск если нет флага готовности
	rjmp	Uart_Send			;ждем готовности - флага UDRE
 
	out	UDR0, Uart_Trans		;шлем байт
	ret							;Возврат
	
	
	
;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;		Подпрограмма получения по UART		  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;

Uart_Get:
	sbis	UCSR0A,RXC0	; Ждем флага прихода байта
	rjmp	Uart_Get	
 
	in	Uart_Recep,UDR0	; байт пришел - забираем
	ret					; Выходим


;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;			Обработчик прерывания			  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;


inter1:
	
	sbis 	PINC,0					;Кнопки остановки
	rcall	stopR
	sbis 	PINC,1
	rcall	stopL

	ldi Uart_Trans,'1'				;отправляем единицу на пк, запрос на направление вращения
	rcall Uart_Send					;подпрограмма отправки
	
	rcall Uart_Get					;получаем символ
	mov Direct_Value, Uart_Recep	;который хранится в Direc_Value
	
	cpi Direct_Value, 0				;1 - то вправо
	brne right

	cpi Direct_Value, 0				;0 - то влево
	breq left
	ldi temp, 0b0
	out PORTD, temp
reti



;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;		Подпрограмма поворота вправо		  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;
Right:
rcall Delay_init				;запрос на величину задержки

ldi Uart_Trans,'0'				;отправляем ноль на пк, запрос на время вращения
rcall Uart_Send					;подпрограмма отправки

rcall Uart_Get					;получаем символ
mov Time_Value, Uart_Recep		;копируем

Right1:
dec Time_value					;декрементируем счетчик
clr temp						;чистим temp
ldi temp, 0b00001010			;пишем в порт
out PORTD, temp					;
rcall Delay						;Задержка

clr temp
ldi temp, 0b00000110
out PORTD, temp
rcall Delay

clr temp
ldi temp, 0b00000101
out PORTD, temp
rcall Delay

clr temp
ldi temp, 0b00001001
out PORTD, temp
rcall Delay
cpi Time_value, 0

brne Right1
ret


								;=============================================;
								;		Подпрограмма поворота влево			  ;
								;=============================================;	
Left:
rcall Delay_init				;запрос на величину задержки

ldi Uart_Trans,'0'				;отправляем ноль на пк, запрос на время вращения
rcall Uart_Send					;подпрограмма отправки

rcall Uart_Get					;получаем символ
mov Time_Value, Uart_Recep		;копируем

Left1:
dec Time_Value
clr temp
ldi temp, 0b00001001
out PORTD, temp
rcall Delay

clr temp
ldi temp, 0b00000101
out PORTD, temp
rcall Delay

clr temp
ldi temp, 0b00000110
out PORTD, temp
rcall Delay

clr temp
ldi temp, 0b00001010
out PORTD, temp
rcall Delay
cpi Time_value, 0

brne Left1
ret

;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;Остановка, при достижении стопкнопки справа  ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;

stopR:

	ldi temp, 0b0					;выключаем двигатели
	out PORTD, temp
						;
	ldi Uart_Trans,'S'				;отправляем на ПК, что дальше двигатся нельзя
	rcall Uart_Send

	ldi Uart_Trans,'R'				;SR (Stop Right)
	rcall Uart_Send
reti


;-------------------------------;=============================================;------------------------------------------------;
;-------------------------------;Остановка, при достижении стопкнопки слева   ;------------------------------------------------;
;-------------------------------;=============================================;------------------------------------------------;

stopL:

	ldi temp, 0b0					;выключаем двигатели
	out PORTD, temp					;

	ldi Uart_Trans,'S'				;отправляем на ПК, что дальше двигатся нельзя
	rcall Uart_Send

	ldi Uart_Trans,'L'				;SL (Stop Left)
	rcall Uart_Send

reti



   