16+
Вторник
20 ноября
Вход |Карта сайта | |Upload |codebook | PARTS

 О смысле всего сущего 0xFF

 Средства и методы разработки

 Мобильная и беспроводная связь

 Блошиный рынок Объявления

caxapa

Микроконтроллеры ARM 

AVR PIC MSP PLD,FPGA,DSP 

Кибернетика Технологии 

Схемы, платы, компоненты 

Микроконтроллеры AVR

 
   Новая тема Правила Регистрация Поиск »» Архив
Вернуться в конференциюТопик полностью
Adept  (10.09.2015 06:24 - 03.10.2015 01:04, просмотров: 41900)
чего-то заплутал в трёх соснах. Не могу понять в чём дело :( 
Делаю скроллинг для драйвера дисплея (простой сегментный многоразрядный индикатор). В статике, все работает прекрасно. Как только начинаю скроллить, показывается всякая фигня. Идея простая. Есть "стационарное" экранное ОЗУ в которое могут писаться данные для отображения на дисплее. И есть окно просмотра, которое отображает на дисплее драйвер. Драйвер никуда ничего не пишет (кроме одной своей служебной ячейки - нмера текущего отображаемого знакоместа), толко читает данные и выводит их по очереди на знакоместа дисплея. По стартапу адрес окна отображения совпадает с адресом экранного ОЗУ. И всё, что мы туда пишем, сразу отображается на дисплее. По задумке, можно изменять адрес окна отображения (оно при этом будет как бы двигаться по массиву памяти), и дисплей будет отображать всё, что в него попадает. На этом я хочу построить механизм скроллинга (дисплей , хоть и многоразрядный, но строчный, и скроллинг нужен) Так вот, пока окно статично, в нём всё отображается правильно. Как только начинаем делать инкремент/декремнт его адреса, показываемая ранее строка конечно сдвигается в нужную сторону, на нужную величину (на одно знакоместо при каждом инкременте/декременте), но по краям этой строки (слева или справа) показывается динамично меняющаяся хрень (одинаковые символы, но меняющиеся на каждом шаге сдвига строки) Херня какая-то :(( Драйвер , в принципе простой, как ситцевые трусы, вот часть исходника, ответственная именно за вывод изображения (в полном исходнике есть ещё управления яркостью и работа с атрибутами мигания "то, что скрыто за многоточием"), но я их даже заглушал, т.е. обходил джампом. Один фиг - ничего не меняется. Подкинет кто умных мыслей, что бы это значило?? и где копнуть?? N.B. перед вызовом хэндлера, контекст процессора и регистр "TMP" есс-но сохраняются, применённые макросы используют только регистр TMP префикс "S_" означает, что это переменная в SRAM
#define	DisplaySIZE	10	;размер дисплея (в знакоместах), т.е. 10 означает 10 знакомест
;----------------------------------------------------------------------------
Int_DISPLAYdriver:; CompareMatch A
	PUSH_X
	Update_DisplayDriver_Timer	;обновление регистра сравнения "A" таймера драйвера дисплея
					;
	.
	.
	.

CHAR_processing:	;обработка знакоместа
	;-----------------------------  ;Анализа на выход за границу экранного ОЗУ
	lds	TMP,S_Display_CHAR	;Загрузим номер знакоместа, обработанного в прошлый раз, т.е. при предыдущем вызове драйвера
	inc	TMP			;Изменяем его (т.е. переключимся на следующее)
	cpi	TMP,DisplaySIZE		;если ещё не вышли за границу дисплея, т.е НЕ показали все имеющиеся разряды, 
	brcs	BeginCHAR_processing	;  то работаем далее (показываем очередной разряд дисплея)
	clr	TMP			;  иначе обнуляем счётчик знакомест перед работой, т.к. пришла очередь показывать "нулевое" знакоместо,
					;  т.е. работать с дисплеем с начала.
	;--------------------------------
BeginCHAR_processing:
	sts	S_Display_CHAR,TMP	;Сохраним изменённый (парой строчек выше) счётчик знакомест.
	;-- вычисления адреса актуальных данных для вывода
	lds	XL,S_DisplayWindowL	;Установим указатель на начало области просмотра экранного ОЗУ
	lds	XH,S_DisplayWindowH
	;
	add	XL,TMP			;вычислим актуальное положение указателя экранного ОЗУ (для текущего знакоместа, номер которого сейчас в TMP)
	clr	TMP
	adc	XH,TMP
	;
	ld	TMP,X				;загрузим данные для текущего обрабатываемого знакоместа
	call	ASCII_to_17segLED_converter	;преобразуем его в семнадцатисегментный код
						;  (ИСПОЛЬЗУЕМЫЕ РЕГИСТРЫ X,TMP. регистр X на текущий момент не содержит полезных данных 
						;   и не требует предварительного сохранения)
	Latch_17SegmentDATA			;защёлкиваем данные знакоместа в регистре
	;---
	lds	TMP,S_Display_CHAR	;опять загрузим номер текущего знакоместа (для управления дешифратором выбора знакомест на дисплее)
	DISPLAY_CurrentCHAR		;показываем текущий символ (в TMP должен быть его номер)
	;
	;-------------------------------------------------------------------------------------------------------
DISPLAYdriver_exit:
	;
	POP_X
	;
	ret
сопутствующие макросы:
;-----------------------------------
;Макрос защёлкивания данных знакоместа в регистрах 17-сегментного дисплея 
;
;Синтаксис: Latch_17SegmentDATA (без параметров)
;данные для защёлкивания берём в ячейках SRAM S_SegmentDATA2..0)
;31/VIII.15
.macro	Latch_17SegmentDATA
	call	Latch_17SegmentDATA_SUB
.endmacro
;------
;задержка в 4такта (нужна для формирования строба на регистры, которые начинают работать только со стробом с задержкой от 2T
.macro	Delay4T
	nop
	nop
	nop
	nop
.endmacro
;---
Latch_17SegmentDATA_SUB:
	Display_TurnOFF			;отключаем ключи знакомест (гасим дисплей)
	;SegmentDATA0
	lds	TMP,S_SegmentDATA0	;читаем данные
	rcall	SetDATA2BUS		;помещаем на шину данные
	sbi	SB0STB_PORT,SB0STB_line	;формируем импульс строба для регистра
	Delay4T				;Задержка (чтобы строб был не слишком короткий)
	cbi	SB0STB_PORT,SB0STB_line
	;SegmentDATA1			;-- повторяем всё то же самое ещё для двух байт
	lds	TMP,S_SegmentDATA1			
	rcall	SetDATA2BUS		;помещаем на шину данные
	sbi	SB1STB_PORT,SB1STB_line	
	Delay4T				;Задержка (чтобы строб был не слишком короткий)
	cbi	SB1STB_PORT,SB1STB_line
	;SegmentDATA2
	lds	TMP,S_SegmentDATA2	
	rcall	SetDATA2BUS		;помещаем на шину данные
	sbi	SB2STB_PORT,SB2STB_line	
	Delay4T				;Задержка (чтобы строб был не слишком короткий)
	cbi	SB2STB_PORT,SB2STB_line
	;
	ret
;----------
SetDATA2BUS:
	out	DATA_PORT,TMP		;помещаем на шину данные
	Delay4T				;Задержка (чтобы данные успели установиться на шине)
	ret
;-----------------------------------
;Макрос показа текущего символа (номер знакоместа должен быть в регистре TMP)
;
;Синтаксис: DISPLAY_CurrentCHAR (без параметров)
;номер знакоместа должен лежать в TMP
;22/VIII.15
.macro	DISPLAY_CurrentCHAR
	out	DATA_PORT,TMP		;выводим номер знакоместа на шину данных
	Display_TurnON			;включаем ключи знакомест (зажигаем дисплей)
.endmacro
;-----------------------------------
;Макросы включения/выключения дисплея (работа с ключами знакомест)
;(версия для дешифратора 74HC154 с активным уровнем "LOW" на входе разрешения работы)
;Синтаксис: Display_TurnON/OFF (без параметров)
;30/VIII.15
.macro	Display_TurnON			
	cbi	CHAR_PORT,CHAR_line	;включаем ключи знакомест (зажигаем дисплей)
.endmacro
;--------
.macro	Display_TurnOFF			
	sbi	CHAR_PORT,CHAR_line	;отключаем ключи знакомест (гасим дисплей)
.endmacro
;-----------------------------------
Главная | Карта сайта | О проекте | Проекты | Файлообменник | Регистрация | Вебмастер | RSS
Лето 7527 от сотворения мира. При использовании материалов сайта ссылка на caxapу обязательна.
MMI © MMXVIII