.include "D:\Program Files\Atmel\AVR Studio\Appnotes\m168def.inc" ;Автор: Кравченко А.В. ;Дата: 8.03.2011 ;Версия: 1.1.8 ;Имя файла: sumoard.asm ;Микроконтроллер: AVR mega168. ;Тактовая частота: 16 мГц ;Питание: стабилизированное 5 В .list .def adr = r0 ; Рабочий регистр .def adr2 = r13 ; Рабочий регистр .def skor = r15 ; Рабочий регистр .def adc1 = r27 ; Рабочий регистр .def prg1 = r24 ; Рабочий регистр .def prg2 = r25 ; Рабочий регистр .def Xa = r16 ; Рабочий регистр .def Ya = r17 ; Рабочий регистр .def tmp2 = r26 ; Рабочий регистр .def tmp3 = r28 ; Рабочий регистр .def tmp = r20 ; Рабочий регистр .def adc2 = r21 ; Рабочий регистр .def F = r22 ; Рабочий регистр .def F1 = r23 ; Рабочий регистр .def par = r18 ; Рабочий регистр .def Ma = r19 ; Рабочий регистр .def bit = r29 ; Рабочий регистр .def d2 = r11 ; Рабочий регистр .def s2 = r12 ; Рабочий регистр .def tmp1 = r13 ; Рабочий регистр .cseg .org 0 rjmp RESET nop rjmp EXT_INT0 ;прерывание nop rjmp EXT_INT1 ;прерывание nop nop ;rjmp EXT_INT0 ;прерывание nop ;rjmp EXT_INT1 ;прерывание nop ;rjmp EXT_INT1 ;прерывание nop ;rjmp wdt nop ;rjmp TIMER2_COMPA прерывание от таймера nop ;rjmp TIMER2_COMPB прерывание от таймера nop nop nop nop nop nop rjmp TIMER2_OVF ;прерывание от таймера nop ;rjmp TIMER1_CAPT прерывание от таймера nop nop rjmp TIMER1_COMPA ;прерывание от таймера nop ;rjmp TIMER1_COMPB прерывание от таймера nop ;rjmp TIMER1_OVF ;прерывание от таймера nop ;rjmp TIMER0_COMPA прерывание от таймера nop ;rjmp TIMER0_COMPB прерывание от таймера nop nop nop nop nop rjmp TIMER0_OVF ;прерывание от таймера nop nop nop ;rjmp SPI_STC прерывание не используется nop ;rjmp UCASRT_RXC прерывание от USART nop ;rjmp UCASRT_UDRE прерывание от USART nop ;rjmp UCASRT_TXC прерывание от USART nop ;rjmp ADC прерывание от АЦП nop ;rjmp EE_RDY прерывание от таймера nop ;rjmp ANA_COMP прерывание от компаратора nop ;rjmp TWI прерывание от TWI nop ;rjmp SPM_RDY прерывание не используется .org 50 RESET: nop ;************************************************** ;настройка портов ввода - вывода clr tmp ldi tmp, $00 ; out DDRC, tmp out PORTC, tmp ;обнулить порт C clr tmp ldi tmp, $3F ;PB0-6 -выход out DDRB, tmp clr tmp out PORTB, tmp ;обнулить порт D clr tmp out DDRD, tmp clr tmp out PORTD, tmp ;обнулить порт D ;***************************************************** ;Маска прерывания INT0, INT1 ldi tmp, $03 ;разрешение прерывание INT0,INT1 out EIMSK, tmp ldi tmp, $00 ;режим ;условие прерывания по низкому уровню на INT0, INT1 sts EICRA, tmp ;**************************************************** ;настройка программного стека ldi tmp, low(RAMEND) ;указатель стека out SPL, tmp ;полный стек ldi tmp, high(RAMEND) out SPH, tmp ;**************************************************** sei clr tmp mov r13, tmp ;чтение DIP переключателей in tmp, PORTD sbis PIND, 4 ;пропустить если не нажат DIP1 rjmp qq0 nop sbis PIND, 5 ;пропустить если не нажат DIP2 rjmp qq2 nop rjmp nStart qq0: nop sbis PIND, 5 ;пропустить если не нажат DIP2 rjmp qq1 nop rjmp Motor qq1: nop rjmp Test qq2: nop rjmp pet ;**************************************************************** ;Начало программы с паузой в 5 секунд pet: nop ;Пауза 5 С (4934786,13 mkS). Ход 1 ;запуск таймера Т1 ;реализация прерывания через 5 С ;дважды по 2,5 секунды ldi tmp,$05 sts TCCR1B,tmp ;деление СК/1024 ldi tmp,$98 sts OCR1AH,tmp ldi tmp,$90 sts OCR1AL,tmp ldi bit, $00 sts TCNT1H, bit ldi tmp3, $02 sts TCNT1L, bit ldi bit, $00 sts TIMSK1,tmp3 ;разрешаем прерывания по переполнению от Т1 nop clr F rcall retp nop ldi tmp3,$05 sts TCCR1B,tmp3 ;деление СК/1024 ldi tmp,$98 sts OCR1AH,tmp ldi tmp,$90 sts OCR1AL,tmp sts TCNT1H, bit ldi tmp3, $02 ldi bit, $00 sts TCNT1L, bit ldi bit, $00 sts TIMSK1,tmp3 ;разрешаем прерывания по переполнению от Т1 nop clr F nop rcall retp2 nop ;**************************************************** ;Стратегия крест накрест ;Начало программы без паузы в 5 секунд nStart: nop rcall stop ;************************************** ;Запуск таймера Т0 датчики периферии clr tmp out TCCR0A,tmp ldi tmp3,$05 out TCCR0B,tmp3 ;деление СК/256 ldi bit, $1F out TCNT0, bit ldi tmp3, $06 sts TIMSK0,tmp3 ;разрешаем прерывания по переполнению от Т0 ;************************************** ;Запуск таймера Т2 датчики передние clr tmp sts TCCR2A,tmp ldi tmp3,$05 sts TCCR2B,tmp3 ;деление СК/256 ldi bit, $0A sts TCNT2, bit ldi tmp3, $00 sts TIMSK2,tmp3 ;разрешаем прерывания по переполнению от Т2 nop ;************************************** ;устанавливаем минимальное движение sbi PORTB, 4 sbi PORTB, 5 ;сброс всех значений ;сброс всех значений clr tmp clr tmp2 clr tmp3 nop ;начало цикла чтения крест накрест и записи в ОЗУ rob: nop cln clz clc cpi par, $0E ;14 значений данных по 4 раза дадут крест накрест breq zop ldi ZH, high(2*prog1) ldi ZL, Low(2*prog1) Add ZL, par LPM mov prg1, adr ldi r31, $02 st Z, prg1 nop inc par rjmp rob nop zop: nop ;выполнение программы действий согласно данным памяти ОЗУ clr par assw: nop ;4 раза по 14 значений clr tmp mov adr2, tmp qoo: nop mov tmp, adr2 cpi tmp, $04 breq chet rjmp dale nop chet: nop rjmp coche nop dale: nop clr par nop wert: nop cpi par, $0E ;14 значений данных по 4 раза дадут крест накрест breq chet2 rjmp dale2 nop chet2: nop rjmp coche2 nop dale2: nop ldi r27, $02 mov r26, par ld tmp3, X ;чтение из ОЗУ0 nop rcall decade nop inc par rjmp wert coche2: nop mov tmp, adr2 inc tmp mov adr2, tmp rjmp qoo coche: nop rjmp nStart ;**************************************************************** ;Тест программа с учетом датчиков test: nop ;разрешение всех прерываний clr par test1: nop rcall stop nop rcall perfo nop cln clz clc rcall datch nop rbx: nop wdr rjmp test1 ;*************************************** ;подпрограмма декодировки и выполнения команд decade: nop cli cln clc clz cpi tmp3, $05 ;вперед медленно breq eeq rjmp vpm nop eeq: nop rcall onestep nop rcall zader nop rjmp qoom vpm: nop cpi tmp3, $14 ;вправо медленно breq eew rjmp vlm nop eew: nop clr tmp mov skor, tmp rcall onevprav nop rcall zader nop rjmp qoom vlm: nop cpi tmp3, $41 ;влево медленно breq eee rjmp stp nop eee: nop mov skor, tmp rcall onevlev nop rcall zader nop rjmp qoom stp: nop cpi tmp3, $44 ;стоп breq eer rjmp naz nop eer: nop rcall stop nop rcall zader nop rjmp qoom naz: nop cpi tmp3, $FF ;назад breq eet rjmp nvlm nop eet: nop rcall zadstep nop rcall zader nop rjmp qoom nvlm: nop cpi tmp3, $F1 ;назад влево медленно breq eey rjmp kljf nop eey: nop mov skor, tmp rcall zadleft nop rcall zader nop rjmp qoom kljf: nop cpi tmp3, $F4 ;назад вправо медленно breq eei rjmp zadright nop eei: nop ldi tmp, $01 mov skor, tmp rcall zadright nop rcall zader nop rjmp qoom vprspr: nop cpi tmp3, $06 ;вперед среднее breq eeu rjmp vpmas nop eeu: nop rcall onestep nop rcall zader nop rjmp qoom vpmas: nop cpi tmp3, $15 ;вправо среднее breq eewq rjmp vlmq nop eewq: nop ldi tmp, $01 mov skor, tmp rcall onevprav nop rcall zader nop rjmp qoom vlmq: nop cpi tmp3, $42 ;влево среднее breq eewt rjmp vlmt nop eewt: nop ldi tmp, $01 mov skor, tmp rcall onevlev nop rcall zader nop rjmp qoom vlmt: nop cpi tmp3, $F5 ;назад вправо среднее breq eez rjmp vlmz nop eez: nop ldi tmp, $01 mov skor, tmp rcall zadright nop rcall zader nop rjmp qoom vlmz: nop cpi tmp3, $F2 ;назад влево среднее breq eexs rjmp vlzx nop eexs: nop ldi tmp, $01 mov skor, tmp rcall zadleft nop rcall zader nop rjmp qoom vlzx: nop cpi tmp3, $07 ;вперед быстро breq eewqnm rjmp vlmqxc nop eewqnm: nop ldi tmp, $02 mov skor, tmp rcall onestep nop rcall zader nop rjmp qoom vlmqxc: nop cpi tmp3, $16 ;вправо быстро breq emnb rjmp vopi nop emnb: nop ldi tmp, $02 mov skor, tmp rcall onevprav nop rcall zader nop rjmp qoom vopi: nop cpi tmp3, $43 ;влево быстро breq edfg rjmp vdfg nop edfg: nop ldi tmp, $02 mov skor, tmp rcall onevlev nop rcall zader nop rjmp qoom vdfg: nop cpi tmp3, $F6 ;назад вправо быстро breq wqnm rjmp mqxc nop wqnm: nop ldi tmp, $02 mov skor, tmp rcall zadright nop rcall zader nop rjmp qoom mqxc: nop cpi tmp3, $F3 ;назад влево быстро breq dwqnm rjmp dvlmqc nop dwqnm: nop ldi tmp, $02 mov skor, tmp rcall zadleft nop rcall zader nop rjmp qoom dvlmqc: nop qoom: nop rcall stop nop ret ;************************************************************ ;подпрограмма проверки передних датчиков perfo: nop ;вход в подпрограмму опроса АЦП1 ph1 левый nop cli ldi adc1, $62 ;источник питания, ADC2, ldi adc2, $C7 ;одиночное, запуск, 1/128 ;опрос уровня освещенности rcall adcn mov d2, tmp3 ;загрузка старшего разряда ;вход в подпрограмму опроса АЦП2 ph2 правый nop ldi adc1, $65 ;источник питания, AD5, ldi adc2, $C7 ;одиночное, запуск, 1/128 ;опрос уровня освещенности rcall adcn mov s2, tmp3 ;загрузка старшего разряда ;сравнение уровня срабатывания cli ;запрет прерывания mov tmp, d2 nop ror tmp clc cln clz cls cpi tmp, $6A ;уровень срабатывания на соперника brmi rtfc rjmp fass nop rtfc: nop cbi PORTB, 4 cbi PORTB, 5 rcall onevprav nop rcall zader1 ldi par, $45 fass: nop mov tmp3, s2 nop ror tmp3 clc cln cls clz cli cpi tmp3, $6A ;уровень срабатывания на соперника brmi rtfc2 rjmp fass2 nop rtfc2: nop cbi PORTB, 4 cbi PORTB, 5 rcall onevlev nop rcall zader1 ;вычитания одно байтного числа ;проверка на ноль старшего байта clc cln cls clz cli mov tmp, d2 mov tmp3, s2 sub tmp, tmp3 clc cln cls clz cli cpi tmp, $09 brmi dsklj rjmp vdsqkl dsklj: nop rcall onevprav nop rcall zader1 nop vdsqkl: nop fass2: nop nop ret nop ret ;************************************************** ;Проверка правильного включения двигателей ;1 Левый вперед ;2 Правый вперед ;3 Оба вперед ;4 Оба назад ;5 Левый назад ;6 Правый назад motor: nop ;Запрет прерываний clr tmp ldi tmp, $3F ;PB0-6 -выход out DDRB, tmp cli clr par ww: nop rcall onevlev nop rcall zader1 ;подпрограмма задержки nop inc par clz cpi par, $08 ;20 циклов по 100 мС breq asd rjmp ww asd: nop clr par ww2: nop rcall onevprav nop rcall zader1 ;подпрограмма задержки nop inc par clz cpi par, $08 ;20 циклов по 100 мС breq asd2 rjmp ww2 asd2: nop clr par ww3: nop rcall onestep nop rcall zader1 ;подпрограмма задержки nop inc par clz cpi par, $08 ;20 циклов по 100 мС breq asd3 rjmp ww3 asd3: nop clr par ww4: nop rcall zadstep nop rcall zader1 ;подпрограмма задержки nop inc par clz cpi par, $08 ;20 циклов по 100 мС breq asd4 rjmp ww4 asd4: nop clr par ww5: nop rcall zadleft nop rcall zader1 ;подпрограмма задержки nop inc par clz cpi par, $08 ;20 циклов по 100 мС breq asd5 rjmp ww5 asd5: nop clr par ww6: nop rcall zadright nop rcall zader1 ;подпрограмма задержки nop inc par clz cpi par, $08 ;20 циклов по 100 мС breq asd6 rjmp ww6 asd6: nop rjmp motor ;*********************************************** ;Подпрограмма проверки датчиков периметра datch: nop cli ;сброс всех значений clr tmp clr tmp1 clr tmp2 clr tmp3 ;вход в подпрограмму опроса АЦП1 nop ldi adc1, $60 ;источник питания, ADC0 перед лево ldi adc2, $C7 ;одиночное, запуск, 1/128 ;опрос уровня rcall adcn ldi r27, $03 ldi r26, $61 ;запись в ОЗУ старший байт st x, tmp3 nop nop nop ;вход в подпрограмму опроса АЦП2 nop ldi adc1, $61 ;источник питания, ADC1 перед право ldi adc2, $C7 ;одиночное, запуск, 1/128 ;опрос уровня rcall adcn ldi r27, $03 ldi r26, $62 ;запись в ОЗУ старший байт st x, tmp3 nop nop nop ;вход в подпрограмму опроса АЦП3 nop ldi adc1, $64 ;источник питания, ADC4 задний правый ldi adc2, $C7 ;одиночное, запуск, 1/128 ;опрос уровня rcall adcn ldi r27, $03 ldi r26, $63 ;запись в ОЗУ старший байт st x, tmp3 nop nop nop ;вход в подпрограмму опроса АЦП4 nop ldi adc1, $63 ;источник питания, ADC3 задний левый ldi adc2, $C7 ;одиночное, запуск, 1/128 ;опрос уровня rcall adcn ldi r27, $03 ldi r26, $64 ;запись в ОЗУ старший байт st x, tmp3 nop nop nop nop ;анализ полученных данных АЦП ldi r27, $03 ldi r26, $61 ld tmp, x nop nop nop ror tmp clc cln cls clz cpi tmp, $3F ;вычесть 200 единиц brpl redf rjmp kzadlev redf: nop ldi r27, $03 ldi r26, $62 ld tmp, x nop nop nop ror tmp clc cln cls clz cpi tmp, $3F ;вычесть 200 единиц brpl redf2 rjmp kzadprv redf2: nop ldi r27, $03 ldi r26, $63 ld tmp, x nop nop nop ror tmp clc cln cls clz cpi tmp, $3F ;вычесть 200 единиц brpl redf3 rjmp klev redf3: nop ldi r27, $03 ldi r26, $64 ld tmp, x nop nop nop ror tmp clc cln cls clz cpi tmp, $3F ;вычесть 200 единиц nop brpl redf4 rjmp kpr redf4: nop rjmp wex ;окончание неравенств переменных klev: nop ldi r27, $03 ldi r26, $64 ld tmp, x nop nop nop ror tmp clc cln cls clz cpi tmp, $3F ;вычесть 200 единиц nop brpl spra rjmp kpr spra: nop sbi PORTB, 5 sbi PORTB, 4 rcall onevlev nop rcall zader1 nop rcall zader1 nop rcall stop nop rjmp wex kprv: nop sbi PORTB, 5 sbi PORTB, 4 rcall onevprav nop rcall zader1 nop rcall zader1 nop rcall stop nop rjmp wex kpr: nop sbi PORTB, 5 sbi PORTB, 4 rcall onestep nop rcall zader1 nop rcall zader1 nop rcall stop nop rjmp wex kzad: nop sbi PORTB, 5 sbi PORTB, 4 rcall zadstep nop rcall zader1 nop rcall zader1 nop rcall stop nop rjmp wex nop kzadprv: nop sbi PORTB, 5 sbi PORTB, 4 rcall zadleft nop rcall zader1 nop rcall zader1 nop kzadlev: nop sbi PORTB, 5 sbi PORTB, 4 rcall zadright nop rcall zader1 nop rcall zader1 nop rcall stop nop wex: nop nop sei ret nop ret ;**************************************** ;Прерыание по INT0 EXT_INT1: nop ;подпрограмма проверки контактов sbi PORTB, 5 cbi PORTB, 4 nop nop rcall onevlev nop sbi PORTB, 5 cbi PORTB, 4 nop rcall zader1 nop rcall onevprav nop rcall zader1 nop reti ;**************************************** ;Прерыание по INT1 EXT_INT0: nop sbi PORTB, 5 cbi PORTB, 4 nop rcall zadstep nop rcall zader1 nop rcall zadstep nop rcall zader1 nop ldi par, $DA reti ;**************************************************** ;Подпрограмма обработки прерывания таймера 0 TIMER0_OVF: nop ldi tmp3, $00 sts TIMSK0,tmp3 ;разрешаем прерывания по переполнению от Т0 cli nop rcall datch nop ;********** ;Запуск таймера Т2 датчики передние clr tmp sts TCCR2A,tmp ldi tmp3,$05 sts TCCR2B,tmp3 ;деление СК/256 ldi bit, $0A sts TCNT2, bit ldi tmp3, $06 sts TIMSK2,tmp3 ;разрешаем прерывания по переполнению от Т2 nop ;************************************** ldi F, $D2 reti ;***************************************************** ;Подпрограмма обработки прерывания таймера 1 TIMER1_COMPA: nop nop ldi F, $D2 nop reti ;***************************************************** ;Подпрограмма обработки прерывания таймера 2 TIMER2_OVF: nop ldi tmp3, $00 sts TIMSK2,tmp3 ;разрешаем прерывания по переполнению от Т2 nop nop rcall perfo ;******** ;Запуск таймера Т0 датчики периферии clr tmp out TCCR0A,tmp ldi tmp3,$05 out TCCR0B,tmp3 ;деление СК/256 ldi bit, $1F out TCNT0, bit ldi tmp3, $06 sts TIMSK0,tmp3 ;разрешаем прерывания по переполнению от Т0 nop ldi F, $D2 nop reti ;***************************************************** ;Подпрограмма АЦП обработки данных ;Настройка АЦП adcn: nop cli ;отключение цифровых входов ldi tmp, $3F sts DIDR0, tmp nop nop nop clr tmp awe: nop cpi tmp, $04 brsh ass sts ADMUX, adc1 ;коммутация входов АЦП clr tmp2 clr tmp3 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop sts ADCSRA, adc2 ;запуск АЦП на преобразование clr tmp3 sts ADCSRB, tmp3 fln: nop lds tmp, ADCSRA sbrs tmp, 4 rjmp fln ;Сохранение данных АЦП lds tmp2, ADCL lds tmp3, ADCH mov r2, tmp2 mov r3, tmp3 mov r4, r2 mov r5, r3 mov r6, r4 mov r7, r5 inc tmp rjmp awe ;среднее арифметическое действие ass: nop clr r8 clc add tmp2, r2 adc r9, r8 add tmp2, r4 adc r9, r8 add tmp2, r6 adc r9, r8 clc lsr r9 ror tmp2 lsr r9 ror tmp2 clr r9 clc add tmp3, r3 adc r9, r8 add tmp3, r5 adc r9, r8 add tmp3, r7 adc r9, r8 clc lsr r9 ror tmp3 lsr r9 ror tmp3 nop ret ;****************************************** ;Подпрограмма задержки включения на 100 мС zader: nop ldi prg1, $00 rcall zader20ms nop rcall datch nop rcall zader20ms nop rcall datch nop rcall zader20ms nop rcall datch nop rcall zader20ms nop rcall datch nop rcall zader20ms nop rcall datch nop wdr clr tmp clr Ma clr Ya ldi Ya, $1A ldi Ma, $1F nop ldi Xa, $1F nop goo: nop nop dm: nop nop goq: nop mov Xa, tmp2 dv: nop wdr nop dx: nop nop eede: nop inc tmp cln cpi tmp, $1A brlo eede nop clr tmp nop cln dec Ya nop brpl dx cln dec Xa brpl dv clz dec Ma brne dm clr Ya clr Xa clr Ma ret ;********************************************** zader1: nop wdr clr tmp clr Ma clr Ya ldi Ya, $5A ldi Ma, $4F nop ldi Xa, $7F dm1: nop nop dv1: nop wdr nop dx1: nop nop eee1: nop inc tmp cln cpi tmp, $CA brlo eee1 nop clr tmp nop cln dec Ya nop brpl dx1 cln dec Xa brpl dv1 clz dec Ma brne dm1 clr Ya clr Xa clr Ma ret nop ret ;********************************************** ;Подпрограмма задержки включения на 20 мС zader20ms: nop wdr clr tmp clr Ma clr Ya ldi Ya, $0A sub Ya, prg1 ldi Ma, $21 sub Ma, prg1 ldi Xa, $2C sub Xa, prg1 dm4: nop nop dv4: nop wdr nop dx4: nop nop eee4: nop inc tmp cln cpi tmp, $0A brlo eee4 nop clr tmp nop cln dec Ya nop brpl dx4 cln dec Xa brpl dv4 clz dec Ma brne dm4 clr Ya clr Xa clr Ma ret nop ret ;*************************************** ;Подпрограмма коммутации двигателей onevlev: nop clr tmp ;порт B левый вперед sbi PORTB, 0 ret onevprav: nop clr tmp ;порт В правый вперед sbi PORTB, 2 ret onestep: nop clr tmp sbi PORTB, 0 sbi PORTB, 2 ret stop: nop clr tmp out PORTB, tmp ;порт В стоп sbi PORTB, 4 sbi PORTB, 5 ret zadstep: nop clr tmp ;порт В назад оба sbi PORTB, 1 sbi PORTB, 3 ret zadleft: nop clr tmp ;порт В левый назад sbi PORTB, 1 ret zadright: nop clr tmp ;порт В правый назад sbi PORTB, 3 ret nop ret ;************************************************ retp: nop clz cpi F, $D2 brne retp nop ret retp2: nop clz cpi F, $D2 brne retp2 nop ret ;в случае проскока nop rjmp RESET .org $F00 prog1: .DB $05, $05, $05, $FF, $F1, $F1, $F1, $FF .DB $FF, $FF, $05, $05, $05, $05 .dseg .org 100