;Модуль для работы с сегментными индикаторами,
;Подключёнными через сдвиговые регистры-защёлки 74hc595(и многие другие)
;SPI реализован программно. Не спрашивайте, почему :).
;==========================================================================
;Указываем выводы, на которых будет сидеть шина данных
;Сначала порты и DDR
.equ DS_PORT =   PORTA
.equ DS_DDR =    DDRA; Данные

.equ TAKT_PORT = PORTA
.equ TAKT_DDR =  DDRA;Вход тактировки 74hc595

.equ ZAS_PORT =  PORTA
.equ ZAS_DDR =   DDRA;Защёлка


;А дальше указываем конкретные выводы
.equ ZAS = PA2; Защёлка
.equ TAKT =PA1; Вход тактировки 74hc595
.equ DS =  PA0; Данные
;=========================================================================
;Переменные для хранения данных
.dseg
Digits: .byte 5




.cseg
;=========================================================================
Display_init:
;Инициализация пинов дисплея. Просто вызовите эту процедуру в начале проги
sbi DS_DDR,DS
sbi TAKT_DDR,TAKT
sbi ZAS_DDR,ZAS

cbi DS_PORT,DS
cbi TAKT_PORT,TAKT
cbi ZAS_PORT,ZAS

ret
;=========================================================================
;Процедура, осуществляющая непосредственный вывод данных в регистры
;Чисто технологическая вещь, из программы не будет вызываться. 
sr_out:
push r17;Сохр. R17 - его придётся затереть.
clr r17; Затираем

;Приготовления окончены
sr_code:
Cpi r17,8;Если переданы 8 бит - готово.
BREQ sr_complete
;Ну а если нет...

lsr r16;Сдвигаем данные, если в 0 бите была 1 - выскочит флаг С.
BRLO sr_one;Тогда мы выведем 1 в регистр
CBI DS_PORT,DS;Если флаг не выскочил - бит был равен 0. выводим 0
rjmp togge

sr_one:;Вывод 1 в регистр
SBI DS_PORT,DS

;-------------------------------------------------------------------------

togge:
SBI TAKT_PORT,TAKT;Дрыгнем тактовой ножкой, чтобы пихнуть данные в регистр
CBI TAKT_PORT,TAKT

inc r17;Увеличим счётчик битов
rjmp sr_code;Ещё раз


sr_complete:;Сюда мы попадём после завершения передачи 8-и бит

pop r17; Вернём затёртый регистр обратно
ret; Всем спасибо, все свободны
;=========================================================================


;Процедура для вывода символов на дисплей. Она непосредственно 
;Будет вызываться из программы. 


display:
push r18
lds r19,digits+4
push r19
push r17
push r16
push r18


lds r17,Digits+3; Значение из первой ячейки -> R17
rcall digit_out


lds r17,Digits+2; Значение из первой ячейки -> R17
rcall digit_out

lds r17,Digits+1; Значение из первой ячейки -> R17
rcall digit_out

lds r17,Digits; Значение из первой ячейки -> R17
rcall digit_out

sbi ZAS_PORT,ZAS;Защёлкнем данные, дрыгнув ножкой
cbi zas_port,zas

pop r18
pop r16
pop r17
pop r19
sts digits+4,r19
pop r18

ret

;=========================================================================

; Подпрограма, преобразующая десятичное число в код сегм. индикатора

Decoder:

ldi ZL,Low(Digits_Table*2) ;Инициализация массива, в котором хранятся коды
ldi ZH,High(Digits_Table*2);Индикатора

add ZL,r17;Прибавления нашего числа к адресу массива

lpm;        Загрузка значения
mov r17,r0; Копируем значение в temp1
ret
;=========================================================================
;Осуществление вывода точек

tochka:
sbr r17,0b00000001;Устанавливаем точку
rjmp out_tck;Выход

;=========================================================================

tck:
lds r18,digits+4;Загружаем значение

lsr r18;Сдвигаем вправо, если будет1  - возникнет флаг переноса
brlo tochka; Тогда выводит точку

out_tck:;Выход
sts digits+4,r18;Сохраняем результат для дальнейшего сдвига

ret

;=========================================================================
;Процедура для экономии памяти

digit_out:
rcall Decoder; Преобразуем его в код сегм. индикатора
rcall tck; Ставим точку, если надо
mov r16,r17
rcall sr_out;Выводим
ret


;=========================================================================
;Таблица символов дисплея

Digits_Table:
.db 0b11111100, 0b01100000;0,1
.db 0b11011010, 0b11110010;2,3
.db 0b01100110, 0b10110110;4,5
.db 0b10111110, 0b11100000;6,7
.db 0b11111110, 0b11110110;8,9
.db 0b00000010, 0b11000110;Знак "-",Знак "градуса"
.db 0b00000000, 0b11111111;Пустота, полнота =))

