; ПРОГРАММА - счетчик электронный для счета импульсов
; Кварц - 4 МГц
;
.include "2313def.inc"
 
;======================================================
#define F_CPU (4000000)
;Здесь идёт определение тактовой частоты. Нужно для
;библиотеки задержек,используемой в этой либе.
;Частота в Герцах.
;======================================================
.def temp =r16 ;временный
.def temp1 =r17 ;временный
.def temp2 =r18 ;временный
.def temp3 =r19 ;временный
.def temp4 =r20 ;временный
 
.def	flags	= r21	; state flags
	.equ	EventForward	= 0	;=1 если надо обслужить прямой счет
	.equ	EventRevers	= 1	;=1 если надо обслужить обратный счет


.CSEG
.org 0
	rjmp START ; На основную программу
 .org INT0addr
	rjmp IntForward ;Oбработкa прерывания по INT0 (инкремент)
.org INT1addr
	rjmp Back ;Oбработкa прерывания по INT1 (декремент)

;*************************************************************************
IntForward:;(ПРИБАВИТЬ)
	sbr	flags, (1<<EventForward)
	reti
;*************************************************************************
IntBack:;(Отнять)
	sbr	flags, (1<<EventRevers)
	reti
;*************************************************************************


 
;*************************************************************************
START:
;	ldi temp,$0F
;	out WDTCR,temp ;Включение сторожевого таймера 1,9 секунды.
 
;Инициализация стека. Обязательно!!!
	ldi	Temp1,RamEnd ; установка указателя стека
	out	SPL,Temp1
	clr	flags
;настройка портов 
	ldi temp1,0b00000000
	out DDRD,temp1 ;Направление данных PortD (1)-выходы
	ldi temp1,0b11111111
	out PORTD,temp1
	ldi temp1,0b11111111
	out DDRB,temp1 ;Направление данных порта B на вывод,В.1,2 -как входы
	out PORTB,temp1 ;Выдать данные на порт В
 
 
;	rcall LongDelay ;программная задержка при включении
	wdr ;сбросить стор. таймер
 
;	sbic pinb,Kn_2 ;если кнопка не нажата перейти на следующую команду
	ldi temp1,(1<<ISC01|1<<ISC11);устанавливаем прерывания INT0 и INT1 по спадающему фронту (ШУЛМ)
 
	out MCUCR,temp1
 
;	rcall lcd_init;Инициализация дисплея.
	nop
	nop
 
	ldi temp,225
 
 	ldi temp1,(1<<INT1)+(1<<INT0);разрешаем прерывания INT1,INT0
	out GIMSK,temp1

	sei ;разрешаем прерывания

;*************************************************************************
Inf:	sbrc	flags, EventForward	;переход если установлен EventForward
	rjmp	Forward			;
	sbrc	flags, EventRevers	;соотв. для EventRevers
	rjmp	Forward			;
 
	rjmp	Inf		;бесконечный цикл

;**************************************************************************
Forward:
	cbr	flags, (1<<EventForward)	;сбросить флаг, обработали событие
	inc temp
	ldi r17,0
;	ldi r16,9
 
	rcall bin16_ascii
 
;	ldi r16,0x45
;	rcall LCD_SetAddressDD
	ret

Back:
	cbr	flags, (1<<EventRevers)	;сбросить флаг, обработали событие
	dec temp
	ldi r17,0
;	ldi r16,9
 
	rcall bin16_ascii
 
;	ldi r16,0x45
;	rcall LCD_SetAddressDD
	ret

;-------------------------------------------------------------------------
bin16_ascii:
;*************************************************************************
;* *
;* Convert unsigned 16 bit to 5 digit ASCII *
;* *
;* *
;* *
;*************************************************************************
;
;входной: R17, R16 = 16 bit значение 0... 65535
; выход: R20, R18, R19, R17, R16 = 5 цифр (ASCII)
; цикл: 20... 170
 
	ldi r21, 10 + '0'
_bcd0:	dec r21
	subi r16, low(-100000) ;+100000
	sbci r17, high(-100000)
	brcs _bcd0
 
	ldi r20, -1 + '0'
_bcd1:	inc r20
	subi r16, low(10000) ;-10000
	sbci r17, high(10000)
	brcc _bcd1
 
	ldi r19, 10 + '0'
_bcd2:	dec r19
	subi r16, low(-1000) ;+1000
	sbci r17, high(-1000)
	brcs _bcd2
 
	ldi r18, -1 + '0'
_bcd3:	inc r18
	subi r16, low(100) ;-100
	sbci r17, high(100)
	brcc _bcd3
 
	ldi r17, 10 + '0'
_bcd4:	dec r17
	subi r16, -10 ;+10
	brcs _bcd4
 
	subi r16, -'0'
 
;-------------------------------------------------------------------------
 
 
;	push temp
;
;	ldi r16,0x01 ;Команда очистки дисплея
;;	rcall LCD_WriteCommand
;	ldi r16,0x45
;;	rcall LCD_SetAddressDD
; 
;	pop temp
 

;Число должно быть в r16,чтоб отобразить на LCD
;	rcall LCD_WriteData
 
; А вывод кода неупакованного BCD на дисплей зависит от его типа (дисплея).
; Если требуются ASCII символы, перед выводом добавляете к цифре $30 (0x30h).
	ret
 




; Подпрограммы выдержек времени (0,5 сек и 2,5 миллисекунды)
 
LongDelay: ;Задержка 0,5 сек
	push temp1
	ldi temp1,$85
	out TCNT1H,temp1 ;загрузим старший байт Т1
	ldi temp1,$EE
	out TCNT1L,temp1 ;загрузим младший байт Т1
	rjmp PUSK
 
Delay: ;Задержка 2,5 мсек
	push temp1
	ldi temp1,$FF
	out TCNT1H,temp1 ;загрузим старший байт Т1
	ldi temp1,$64
	out TCNT1L,temp1 ;загрузим младший байт Т1
 
PUSK: ;запуск таймера
	ldi temp1,3
	out TCCR1B,temp1 ;загрузим к-т предделителя Т1 и запустим его
 
LooP: ;цикл
	in temp1,TIFR
	sbrs temp1,7 ;таймер-счетчик переполнен?
	rjmp LooP
	ldi temp1,0
	out TCCR1B,temp1 ;остановить счетчик таймера
	ldi temp1,$80
	out TIFR,temp1 ;сбросить флаг переполнения таймера
	pop temp1
	ret
 
;.include file "C:\AVR\WH4\hd44780.asm"
 
; Подключение библиотеки для
; работы с дисплеем.
