Всем привет. Наконец-то сделал хоть что-то немного похожее на робота! Предлагаю просмотреть листинг программы на которой робот работает. Программа написана на Ассемблере. Некоторые задержки были изменены и могут не соответствовать комментариям. Можно скачать файл в архиве.
.include "m8def.inc"
.def temp=r16 .def temp1=r17 .def temp2=r18
.org 0x000 rjmp init .org 0x012 rjmp timer_0
;**************************************************** ;*** прерывание по переполнению таймера/счетчика0 *** ;**************************************************** timer_0: ; push temp ;помещение содержимого регистра в стек ldi temp,0x00 ;остановка счетчика out TCCR0,temp ; SET ;установка флага T в регисте SREG pop temp ;извлечение из стека в регистр reti ;Возврат из прерывания ;****************************************************
;******************************************************** ldi temp,0b11111111 ;настройка порта B 1-выход 0-вход out DDRB,temp ldi temp,0b00000000 ;настройка порта B out PORTB,temp ldi temp,0b11111111 ;настройка порта C 1-выход 0-вход out DDRC,temp ldi temp,0b00000000 ;настройка порта C out PORTC,temp ldi temp,0b10011111 ;настройка порта D 1-выход 0-вход out DDRD,temp ldi temp,0b01100000 ;настройка порта D out PORTD,temp ;******************************************************** ldi temp,0x04 ;***************** out sph,temp ;*** Настройка *** ldi temp,0x5f ;*** стека *** out spl,temp ;***************** ;********************************************************
;******************* настройка таймера/счетчика 0 ldi temp,0b00000001 ;Разрешаем прерывание out TIMSK,temp ;установкой "1" в разряда TOIE0 SEI ;Общее разрешение прерываний
;********************************** ;*** onward *** (OW) *** вперед *** ;********************************** OnWard: sbi portd,3 ;on вперед sbi portb,0 ;on LED передний ldi temp,0x0 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0x5 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024
;*** едем в перед *** ;in temp2,PIND ; ;sbrs temp2,5 ; ;sbi portB,0 ; ;sbrs temp2,6 ; ;sbi portB,0 ;
sbi portd,3 ;on вперед sbi portb,0 ;on LED передний
;*** отьезжаем *** in temp2,PIND ; sbrs temp2,5 ; rcall Left ; in temp2,PIND ; sbrs temp2,6 ; rcall Right ; brts twinkle ;переход, если флаг T установлен
rjmp Main ;********************************************************
;************************ ;*** right *** вправо *** ;************************ Right: push temp ldi temp,0x00 ;остановка счетчика out TCCR0,temp ; cbi portd,3 ;off вперед cbi portb,0 ;off LED передний rcall led_10 ;задержка ;*** назад-вправо *** ldi temp,0b11110010 ;назад, вправо, LED задний out PORTD,temp ; rcall time_1s ; ldi temp,0b11100000 ;LED задний out PORTD,temp ; rcall led_10 ;задержка ;*** вперед-влево *** sbi portd,3 ;on вперед sbi portd,2 ;on left sbi portb,0 ;on LED передний rcall timer_70 ;delay cbi portd,2 ;off left ldi temp,0x0 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0x5 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024 pop temp ; ret ;
;********************** ;*** left *** влево *** ;********************** Left: push temp ldi temp,0x00 ;остановка счетчика out TCCR0,temp ; cbi portd,3 ;off вперед cbi portb,0 ;off LED передний rcall led_10 ;задержка ;*** назад-влево *** ldi temp,0b11110100 ;назад, влево, LED задний out PORTD,temp ; rcall time_1s ; ldi temp,0b11100000 ;LED задний out PORTD,temp ; rcall led_10 ;задержка ;*** вперед-вправо *** sbi portd,3 ;on вперед sbi portd,1 ;on right sbi portb,0 ;on LED передний rcall timer_70 ;delay cbi portd,1 ;off right ldi temp,0x0 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0x5 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024 pop temp ; ret ;
;******************************************** twinkle: push temp ; push temp1 ; clt ;Сброс флага T в регисте SREG in temp1,PORTD ; ldi temp,0x80 ; опрос порта D eor temp,temp1 ; и моргание задним LED out PORTD,temp ; ldi temp,0x0 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0x5 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024 pop temp1 ; pop temp ; ret ; ;********************************************
;*********************************** ;*** backward *** (BW) *** назад *** ;*********************************** BackWard: sbi portd,4 ;on назад sbi portd,7 ;on LED задний rcall time_1s ; cbi portd,4 ;off назад ret
;*************** ;*** LED ten *** ;*************** led_10: push temp ;помещение содержимого регистра в стек push temp1 ; push temp2 ; ldi temp2,4 ;повтор 10 раз
time_1sec: in temp1,PORTD ; ldi temp,0x1 ; опрос порта D eor temp,temp1 ; и моргание индикатором out PORTD,temp ; rcall timer_100 ; dec temp2 ; tst temp2 ; breq time_1sec_end; rjmp time_1sec ;
time_1sec_end: pop temp2 ; pop temp1 ; pop temp ;извлечение из стека в регистр ret ;возврат из подпрограммы ;******************* ;*** end LED ten *** ;*******************
;************************************************************ ;*** Подпрограмма отсчета времени 100 мс на 8МГц ************ ;*** при помощи внутреннего таймера/счетчика 0 ************ ;************************************************************ timer_100: push temp ;помещение содержимого регистра в стек
ldi temp,0b00000000 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0b00000101 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024
timer_100_1: brts timer_100_1end ;переход, если флаг T установлен rjmp timer_100_1 ;
timer_100_1end: ; CLT ;Сброс флага T в регисте SREG ldi temp,0b00000000 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0b00000101 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024 rjmp timer_100_2 ;
timer_100_2: brts timer_100_2end ;переход, если флаг T установлен rjmp timer_100_2 ;
timer_100_2end: ; CLT ;Сброс флага T в регисте SREG ldi temp,0b00000000 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0b00000101 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024 rjmp timer_100_3 ;
timer_100_3: brts timer_100_3end ;переход, если флаг T установлен rjmp timer_100_3 ;
timer_100_3end: ; CLT ;Сброс флага T в регисте SREG pop temp ;извлечение из стека в регистр ret ;возврат из подпрограммы ;************************************************************* ;*** Окончание подпрограммы отсчета времени 100 мс на 8МГц *** ;*************************************************************
;*********************************************************** ;*** Подпрограмма отсчета времени 70 мс на 8МГц ************ ;*** при помощи внутреннего таймера/счетчика 0 ************ ;*********************************************************** timer_70: push temp ;помещение содержимого регистра в стек
ldi temp,0b00000000 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0b00000101 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024
timer_70_1: brts timer_70_1end ;переход, если флаг T установлен rjmp timer_70_1 ;
timer_70_1end: ; CLT ;Сброс флага T в регисте SREG ldi temp,0b00000000 ;обнуляем счетчик out TCNT0,temp ; ldi temp,0b00000101 ;запускаем счетчик out TCCR0,temp ;в режиме деления на 1024 rjmp timer_70_2 ;
timer_70_2: brts timer_70_2end ;переход, если флаг T установлен rjmp timer_70_2 ;
timer_70_2end: ; CLT ;Сброс флага T в регисте SREG pop temp ;извлечение из стека в регистр ret ;возврат из подпрограммы ;************************************************************ ;*** Окончание подпрограммы отсчета времени 70 мс на 8МГц *** ;************************************************************
;********************************************************* ;*** Подпрограмма отсчета времени 1c на 8МГц ************* ;********************************************************* time_1s: push temp push temp1 push temp2
time_1s_1: dec temp ;********************************* tst temp ;*** внутреннее тело цикла 5кц *** breq time_1s_2 ;********************************* rjmp time_1s_1 ;*********************************
time_1s_2: dec temp1 tst temp1 breq time_1s_3 rjmp time_1s_01
time_1s_3: dec temp2 tst temp2 breq time_1s_end rjmp time_1s_001
time_1s_end:pop temp2 pop temp1 pop temp ret ;********************************************************* ;*** Окончание подпрограммы отсчета времени 1с на 8МГц *** ;*********************************************************