Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Динамическая индикация
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Андрей_М
Подскажите как реализовать сдвиг цифр, чтобы получить на индикаторах следующее 1234 2345 3456 4567 5678 6789 789a 89ab 9abc abcd bcde cdef [__]
Имеющийся код выводит только 1234.
В проекте протеуса перепутан катод и анод.
CODE
.include "tn2313def.inc"
.def Temp1=R16
.def Temp2=R17
.def Temp3=R18
.def Temp=R20
.def flag1=r21
.def flag2=r22
.def noga=r23
.def nogga=r24
.def cifra=R25
.def temp6=r19
.def i=r1


.dseg
timer1: .byte 1; 1 ячейку под переменную timer1
timer2: .byte 1
Digit: .byte 4


.cseg
.org 0
rjmp init
.org OVF0addr
rjmp T0_OVF

T0_OVF:
in temp3, SREG
push temp3
;PIND 3 16
lds temp3, timer1
dec temp3
brne t1
ldi temp3,5
ldi flag1, 1
t1: sts timer1, temp3
lds temp3, timer2
dec temp3
brne t2
ldi temp3,255
ldi flag2, 1
t2: sts timer2, temp3
pop temp3
out SREG, temp3
reti

init:
ldi R16,low(RamEnd)
out spl,R16
; настройка портов
ldi R16,0b11111111
out ddrb,R16
ldi R16,0b00001111
out ddrd,R16
ldi temp, 5
sts timer1, temp
ldi temp, 255
sts timer2, temp
ldi flag1, 0
ldi flag2, 0
ldi noga, 1
ldi temp, 0
mov i, temp



; настройка таймера счетчика T0

cli
ldi temp, (1<<1)
out TCCR0B, temp
ldi temp, 1<<TOIE0
out TIMSK, temp
sei

ldi temp,1
sts digit,temp
ldi temp,2
sts digit+1,temp
ldi temp,3
sts digit+2,temp
ldi temp,4
sts digit+3,temp
main:
cpi flag1,1
brne tt1
rcall display
ldi flag1,0
tt1:
cpi flag2,1
brne tt2
rcall sdvig
ldi flag2,0
tt2:
rjmp main
Display:
ldi yh,high(digit)
ldi yl,low(digit)
add yl,i
inc i
;add yl,noga
;dec yl
ld cifra,y
rcall decoder
out portb,cifra
;--------------------
mov nogga,noga
ldi temp,0xFF
eor nogga,temp
out portD,nogga
lsl noga
sbrs noga, 4
rjmp ex1
ldi noga, 1
ldi temp, 0
mov i, temp
ex1: ret
;------------------------
sdvig: inc cifra
cpi cifra,19
breq main
ret

Decoder:;преобразование двоичного числа в код 7-сегментного индикатора
ldi ZL,Low(DcMatrix*2) ;инициализация массива
ldi ZH,High(DcMatrix*2)
ldi Temp6,0 ;прибавление переменной
add ZL,cifra ;к 0-му адресу массива
adc ZH,Temp6
lpm ;загрузка значения
mov cifra,r0
ret


DcMatrix:
;массив - таблица истинности декодера
; hgfedcba hgfedcba
.db 0b11000000,0b11111001;0,1
.db 0b10100100,0b10110000;2,3
.db 0b10011001,0b10010010;4,5
.db 0b10000010,0b11111000;6,7
.db 0b10000000,0b10010000;8,9
.db 0b10001000,0b10000011;a,b
.db 0b11000110,0b10100001;c,d
.db 0b10000110,0b10001110;e,f
.db 0b11000110,0b11110110;c,=
.db 0b11110110,0b11110000;=.э

Нажмите для просмотра прикрепленного файла
kovigor
Цитата(Андрей_М @ May 11 2013, 09:33) *
Подскажите как реализовать сдвиг цифр, чтобы получить на индикаторах следующее 1234 2345 3456 4567 5678 6789 789a 89ab 9abc abcd bcde cdef [__]
Имеющийся код выводит только 1234.

Запишите в массив строку "123456789abcdef". Создайте в программе глобальную переменную "starting_index", и пусть блок, который отображает картинку на индикаторе, берет для отображения четыре цифры, начиная с цифры с индексом "starting_index". Раз в полсекунды (например) увеличивайте "starting_index" на "1". Вот и все ...
P.S. Такие вещи лучше делать по прерыванию - обработчик прерывания от таймера отображает картинку на экране, а фоновый процесс для него эту картинку подготавливает (если это нужно, но у вас более простой случай) и раз в полсекунды увеличивает "starting_index" на "1".
Андрей_М
Цитата
Запишите в массив строку "123456789abcdef". Создайте в программе глобальную переменную "starting_index", и пусть блок, который отображает картинку на индикаторе, берет для отображения четыре цифры, начиная с цифры с индексом "starting_index". Раз в полсекунды (например) увеличивайте "starting_index" на "1". Вот и все ...

Вариант в целом понятен.
Однако, хотелось бы поподробнее как можно сделать через обработчик прерывания
Цитата
P.S. Такие вещи лучше делать по прерыванию - обработчик прерывания от таймера отображает картинку на экране, а фоновый процесс для него эту картинку подготавливает (если это нужно, но у вас более простой случай) и раз в полсекунды увеличивает "starting_index" на "1".
ARV
Цитата(Андрей_М @ May 11 2013, 17:14) *
Вариант в целом понятен.
Однако, хотелось бы поподробнее как можно сделать через обработчик прерывания
смотрите, например, здесь: http://arv.radioliga.com/content/view/172/49/
Андрей_М
Цитата
смотрите, например, здесь: http://arv.radioliga.com/content/view/172/49/

В этой статье примеры реализации на C, в моем случае программа написана на ассемблере.
ARV
Цитата(Андрей_М @ May 14 2013, 08:38) *
В этой статье примеры реализации на C, в моем случае программа написана на ассемблере.

да хоть на фортране! в статье основное внимание уделено АЛГОРИТМАМ с примерами на Си. как я понял, у вас проблема именно с АЛГОРИТМОМ при работе по прерываниям - неужели вы не сумеете реализовать описанный алгоритм на ассемблере?!
ae_
Цитата(Андрей_М @ May 11 2013, 15:33) *
Имеющийся код выводит только 1234.

Динамическая индикация выводит на дисплей числа из области памяти digit0...digit3. Чтобы получить бегущую строку, надо содержимое памяти digit0...digit3 менять из п/п sdvig, но этого не происходит, т.к. в программе вообще нет кода, который бы менял digit0...digit3, и на дисплей всегда выводится одно и тоже - то, что было записано при инициализации "1234".
В тоже время, п/п sdvig не понятно для чего меняет регистр cifra, это же не глобальная переменная, а временный регистр, который используется в другой п/п и постоянно затирается.
Чтобы всё заработало, как задумано, надо при каждом вызове sdvig копировать digit0 <- digit1; digit1 <- digit2; digit2 <- digit3 и в digit3 записывать новое(следующее) значение из строки "56789..."
kolobok0
Цитата(ae_ @ May 14 2013, 19:22) *
...надо при каждом вызове sdvig копировать digit0 <- digit1; digit1 <- digit2; digit2 <- digit3...


для того чтобы данные двигались относительно определённой точки отчёта, не обязательно двигать эти данные - можно менять точку отчёта. как правило это тяжелее для восприятия, но с точки зрения построения программы - более кэпэдэшно по всем параметрам.
ae_
Цитата(kolobok0 @ May 16 2013, 23:19) *
...можно менять точку отчёта.

Полностью согласен. Этот совет уже дал kovigor в первом ответе автору темы.
Но у ТС и строки никакой нет, по которой можно двигать указатель "окна" дисплея.
Я лишь предложил минимальные доработки, чтоб "забегало", сделать:
d0<-d1; d1<-d2; d2<-d3; d3<-(d3+1)
Запустить, обрадоваться, что "заработало!!!" и полностью переделать программу.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.