ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
23 ноября
618683
Adept (10.09.2015 06:24 - 03.10.2015 01:04, просмотров: 75647)
чего-то заплутал в трёх соснах. Не могу понять в чём дело :( Делаю скроллинг для драйвера дисплея (простой сегментный многоразрядный индикатор). В статике, все работает прекрасно. Как только начинаю скроллить, показывается всякая фигня. Идея простая. Есть "стационарное" экранное ОЗУ в которое могут писаться данные для отображения на дисплее. И есть окно просмотра, которое отображает на дисплее драйвер. Драйвер никуда ничего не пишет (кроме одной своей служебной ячейки - нмера текущего отображаемого знакоместа), толко читает данные и выводит их по очереди на знакоместа дисплея. По стартапу адрес окна отображения совпадает с адресом экранного ОЗУ. И всё, что мы туда пишем, сразу отображается на дисплее. По задумке, можно изменять адрес окна отображения (оно при этом будет как бы двигаться по массиву памяти), и дисплей будет отображать всё, что в него попадает. На этом я хочу построить механизм скроллинга (дисплей , хоть и многоразрядный, но строчный, и скроллинг нужен) Так вот, пока окно статично, в нём всё отображается правильно. Как только начинаем делать инкремент/декремнт его адреса, показываемая ранее строка конечно сдвигается в нужную сторону, на нужную величину (на одно знакоместо при каждом инкременте/декременте), но по краям этой строки (слева или справа) показывается динамично меняющаяся хрень (одинаковые символы, но меняющиеся на каждом шаге сдвига строки) Херня какая-то :(( Драйвер , в принципе простой, как ситцевые трусы, вот часть исходника, ответственная именно за вывод изображения (в полном исходнике есть ещё управления яркостью и работа с атрибутами мигания "то, что скрыто за многоточием"), но я их даже заглушал, т.е. обходил джампом. Один фиг - ничего не меняется. Подкинет кто умных мыслей, что бы это значило?? и где копнуть?? 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 ;-----------------------------------
...делать нужно так, как нужно. А как ненужно - делать не нужно (С) Винни-Пух :)