Программа для микроконтроллера

В УКОВ применяется микроконтроллер ATtiny26 фирмы ATMEL. Отладка производилась в AVR Studio. Исходный код программы приведен ниже


		.include "tn26def.inc"	;файл описаний имен регистров
		.def	tmp=r16		;рабочая переменная
		.def	hrs=r20		;количество часов
		.def	num=r18		;рабочая переменная
		.def	m=r21		;m=0, если задействован таймер.
					;m используется для
					;предотвращения режима BLINK
					;в режиме "ТАЙМЕР"

		rjmp	RESET		;переход после сброса
		rjmp	EXT_INT0	;переход после внешнего прерывания

RESET:					;главная программа
		ldi	tmp,RAMEND	;инициализация стека
		out	sp,tmp			

		ldi	tmp,0b01000000
		out	GIMSK,tmp	;разрешаем внешнее прерывание INT0
		ldi	tmp,0b00000010	
		out	MCUCR,tmp	;настроим прерывание по заднему
					;фронту импульса
		ldi	tmp,0b01111111	;настройка портов
		out	ddra,tmp	;РА0..РА6 - на вывод, РА7 - на ввод
		ldi	tmp,0b00000110	;РB4,PB6,PB5,PB3 - на ввод,
		out	ddrb,tmp	;PB2,PB1 - на вывод

		clr	tmp		;tmp = 0
		clr	hrs		;hrs = 0
		rcall	INDICATE

START:		clr	tmp
		clr	hrs
		rcall	INDICATE
		sei			;разрешаем прерывания
STRT:		sbis	pina,7		;ждем нажантия кнопки "ПУСК"
		rjmp	STRT
		rcall	del_s		;задержка 1 сек
		rcall	del_s			
		sbis	pina,7		;если "ПУСК" всё еще нажат - работаем
		rjmp	STRT		;иначе - ждем снова
		
		sbi	portb,1		;оповещаем
		rcall	del_s		;пользователя
		cbi	portb,1		;о начале
		rcall	del_s		;отработки
		sbi	portb,1		;алгоритма
		rcall	del_s		;мерцанием
		cbi	portb,1		;светодиода

		sbis	pinb,3		;если РВ3 = 1, то идем
		rjmp	REPEAT		;на режим "ТАЙМЕР", иначе - "ПОВТОР"
		rcall	INDICATE
								
TIMER:		cli			;режим "ТАЙМЕР"
		rcall	INDICATE		
		tst	hrs		;если hrs = 0, то откачиваем воду
		breq	IMMEDIATE	;если нужно подождать, то
		dec	hrs		;инкрементируем hrs и
		rcall	del_h		;ждем
		rjmp	TIMER


IMMEDIATE:	rcall	IND_LS
		sbis	pinb,5
		rjmp	START
		rcall	PUMPING
		clr	hrs
		rjmp	START
		
INDICATE:				;отображение hrs на 7-сегментнике
		cpi	hrs,1		;сравниваем hrs с единицей если
					;hrs <> 1, то проверяем равенство
		brne	TWO		;hrs двойке. Если же hrs = 1, то
		ldi	num,0b00000110	;пишем в num число, для "1"
		out	porta,num	;и выводим на индикацию
		ret			;выходим из подпрограммы
TWO:		cpi	hrs,2
		brne	THREE
		ldi	num,0b01011011
		out	porta,num
		ret
THREE:		cpi	hrs,3
		brne	FOUR
		ldi	num,0b01001111
		out	porta,num
		ret
FOUR:		brne	FIVE
		ldi	num,0b01100110
		out	porta,num
		ret
FIVE:		cpi	hrs,5
		brne	SIX
		ldi	num,0b01101101
		out	porta,num
		ret
SIX:		cpi	hrs,6
		brne	SEVEN
		ldi	num,0b01111101
		out	porta,num
		ret
SEVEN:		cpi	hrs,7
		brne	EIGHT
		ldi	num,0b00000111
		out	porta,num
		ret
EIGHT:		cpi	hrs,8
		brne	NINE
		ldi	num,0b01111111
		out	porta,num
		ret
NINE:		cpi	hrs,9
		brne	ZERO
		ldi	num,0b01101111
		out	porta,num
		ret
ZERO:		ldi	num,0b00111111
		out	porta,num
		ret

REPEAT:		cli			;режим "ПОВТОР"
		rcall	INDICATE
		tst	hrs
		breq	PUMP
		rcall	del_h
		dec	hrs
		rcall	INDICATE
		rcall	REPEAT
		
PUMP:		mov	hrs,tmp		;восстанавливаем данные

		rcall	IND_LS
		sbis	pinb,5		;проверяем, если ДУ=0, то
		rjmp	REPEAT			
		rcall	PUMPING
		rjmp	REPEAT

PUMPING:				;подпрограмма откачки
		ldi	m,1
		sbi	portb,1		;оповещаем пользователя 
		sbi	portb,2		;и включяем насос
CONT:		com	m		;задержка 1 мин с анимацией

		mov	num,m
		inc	num
		andi	num,1
		breq	INV

		ldi	num,0b00000001	;горит сегмент A
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00000011	;B
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00000111	;C
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00001111	;D
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00011111	;E
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00111111	;F
		out	porta,num
		rcall	del_s
		rjmp	CHK

INV:		ldi	num,0b00111110	;горит сегмент A
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00111100	;B
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00111000	;C
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00110000	;D
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00100000	;E
		out	porta,num
		rcall	del_s
		rcall	del_s
		ldi	num,0b00000000	;F
		out	porta,num
		rcall	del_s

CHK:		rcall	del_s
		sbic	pinb,5		;если уровень высокий, то
		rjmp	CONT		;продолжаем откачку

					;если уровень стал низким, то
		cbi	portb,1		;завершаем прозвон, отключаем
		cbi	portb,2		;насос и сигнализацию откачки
		clr	hrs
		rcall	INDICATE
		ret			;выходим из подпрограммы


IND_LS:					;оповещаем о проверке ДУ:
					;два раза мерцает "d"
		clr	num
		out	porta,num		
		rcall	del_s		;на индикаторе 0.5 сек пусто
		ldi	num,0b01011110	
		out	porta,num		
		rcall	del_s		;затем 0.5 сек горит "d"
		clr	num
		out	porta,num		
		rcall	del_s		;снова пусто
		ldi	num,0b01011110	
		out	porta,num		
		rcall	del_s		;и опять "d"
		clr	num
		out	porta,num	;пусто
		ret			;выходим из подпрограммы


EXT_INT0:				;отработка внешнего прерывания
		cpi	hrs,9		;если hrs не равно 9, то
		brne	SKIP		;не изменяем его
		clr	hrs		;иначе - обнуляем
		rjmp	S
SKIP:		inc	hrs		;hrs = hrs - 1
S:		mov	tmp,hrs		;tmp = hrs
		rcall	INDICATE
		reti


del_s:					;задержка 0.5 сек
		push	r16		;сохраняем
		push	r17		;данные
		push	r18		;в стеке
		ldi	r18,65		;внешняя петля 65
del11:		ldi	r17,49		;средняя петля 49
del12:		ldi	r16,52		;внутренняя петля 52
del13:		dec	r16		;декрементируем
		brne	del13		;если 0,продолжаем среднюю
		dec	r17		;декрементируем
		brne	del12		;если 0,продолжаем внешнюю
		dec	r18		;декрементируем
		brne	del11		;ели 0,задержка окончена
		pop	r18		;восстанавливаем
		pop	r17		;данные
		pop	r16		;со стека
		ret			;выходим в осно. прогу

del_h:					;подпрограмма задержки 1 час
		push	r16		;сохраняем
		push	r17		;данные
		push	r18		;в стеке
		push	r19
		ldi	r19,246		;246 (109 для 5 сек)
del34:		ldi	r18,140		;140 (150 для 5 сек)
del33:		ldi	r17,180		;180 (10 для 5 сек)
del32:		ldi	r16,195		;195 (10 для 5 сек)
del31:		dec	r16
		brne	del31
		dec	r17
		brne	del32
		dec	r18
		brne	del33
		dec	r19
		brne	del34
		pop	r19
		pop	r18		;восстанавливаем
		pop	r17		;данные
		pop	r16		;со стека
		ret	

© 2010 Логинов Вадим




Автобиография | Автореферат | Библиотека | Ссылки | Отчет о поиске | Индивидуальный раздел
ДонНТУ | Портал магистров