реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Вопрос новичка по бегущей строке
Mark71
сообщение Jan 15 2010, 08:50
Сообщение #1





Группа: Участник
Сообщений: 9
Регистрация: 31-03-08
Пользователь №: 36 358



Поднимаю в очередной раз уже избитую и давно поднадоевшую всем тему по организации динамической индикации в бегущей строке. Просто ни на одном из форумов, посвященой этой теме, не могу найти ответ на, казалось-бы, простой вопрос: какими програмными или аппаратными методами добиваются плавного движения текста (чтобы не было растяжения и сжатия при движении, скачков, при переходе с одной матрицы на другую).
У меня 16 светодиодных матриц 8х8, постолбцовая регенерация слева направо (хотя пробовал и наоборот, но улучшения не получил), соответственно скважность 8. Частота регенерации 100Гц (хотя пререпробовал много других частот), соответственно для одного пикселя частота 800Гц. Движение текста справа налево.
Привожу текст обработки прерывания для одного столбца c подробными комментариями:

CODE
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)________//вывод одного столбца(0-7) во всех 16 индикаторах на 1,25мс (1,25мс * 8 = 10мс = 100Гц)
{
unsigned char number_indic = 0,_//номер индикатора
____________gb_index, delay;__//номер позиции в графическом буффере
//number_col - номер столбца - внешняя переменная
ClrBit(PORTC,COL);___________//выключаем все столбцы (выводы дешифратора 1 из 8 в состоянии лог.1)
TCNT0 = 0xB2;______________ //перезагрузка таймера
tick++;_____________________//тикалка
//WDR();___________________//сброс сторожевого таймера
for (gb_index = number_col; gb_index < 128; gb_index += 8) {__//распихиваем данные из буффера в 574-е регистры по
_______________________________________________________//положительному перепаду
______________________________________________________//всего 16 итераций в этом цикле
______________________________________________________WR_BUS_DATA = graphic_buffer[gb_index];
______________________________________________________delay++; //задержка
______________________________________________________PORTB = number_indic; //выбираем индикатор
______________________________________________________number_indic++;
______________________________________________________SetBit(PORTB,WR_INDICATOR)
;__//формируем положительный перепад
______________________________________________________delay++; //задержка
______________________________________________________ }//end for
WR_BUS_DATA = number_col;__//выставляем на шину номер столбца
number_col++;______________//увеличение номера столбца (внешняя переменная)
SetBit(PORTC,COL);__________//включаем текущий столбец на всех 16-ти индикаторах на 1,25мс до следующего прерывания
if (number_col > 7 ) {
___________________ number_col = 0;
____________________shift_graphic_buffer(); //сдвиг графического буфера влево на одну позицию
___________________}
}

Понимаю, что все банально, тупо в лоб, без изысков, но текст двигается, но двигается с большими проблемами (см.выше)
shift_graphic_buffer() - по времени занимает 165мкс, если верить протеусу
Причем и в реально собранном устройстве и смоделированном в протеусе проблемы с движением одни и теже ( протеус рулит smile.gif )
Я даже не прошу исправить код, просто подскажите теоретически в каком направлении двигаться sad.gif
Скачок текста при переходе с одного индикатора на друой связан, как я понимаю, с увеличением паузы между 1-го столбцом одного индикатора и 7-м столбцом следующего. Фактически время между засветками равно времени двух регенераций. Вот и возникает скачок. И как с этим бороться?
Кстати очень сильное увеличение чатоты регенерации привело к более менее приличному результату, но яркость упала до еле различимой. Несколько циклов регенерации между сдвигами также улучшают ситуацию, но приводит к удвоению, утроению и т.п.
пикселов. Ведь как-то делают на частоте 75 или 100Гц регенерация-сдвиг-регенерация и текст без проблем бежит, вот только как...

К сожалению не удалось вставить в текст программы символы табуляции для удобочитаемости, так что не взыщите...

Сообщение отредактировал Omen_13 - Jan 21 2010, 01:20
Причина редактирования: Оформление кода
Go to the top of the page
 
+Quote Post
_dem
сообщение Jan 15 2010, 09:01
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Простой ответ на простой вопрос - используйте двойную буферизацию, переключайте буфера по окончанию строки.

ps. Пардон, не досмотрел код. Оформите, пожалуйста, код нужным тегом - ну очень грустно смотреть в такой текст в пятницу )

Да, прерывание у вас как-то неправильно сделано. Отделите мух от котлет, т.е. вывод от сдвига.
Прерывание - строго вывод, основной код - сдвиг. И два буфера, да.
Go to the top of the page
 
+Quote Post
dimka76
сообщение Jan 15 2010, 09:01
Сообщение #3


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(Mark71 @ Jan 15 2010, 11:50) *
Скачок текста при переходе с одного индикатора на друой связан, как я понимаю, с увеличением паузы между 1-го столбцом одного индикатора и 7-м столбцом следующего. Фактически время между засветками равно времени двух регенераций. Вот и возникает скачок. И как с этим бороться?


А рачем весь буфер сдвигать?
Код
shift_graphic_buffer();


Может достаточно только позицию в буфере смещать.

Цитата
или аппаратными методами добиваются плавного движения текста


Может попробовать использовать внешнюю шину данных, такие есть в m162, m128 и др.


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
Mark71
сообщение Jan 15 2010, 09:10
Сообщение #4





Группа: Участник
Сообщений: 9
Регистрация: 31-03-08
Пользователь №: 36 358



Цитата(_dem @ Jan 15 2010, 13:01) *
Простой ответ на простой вопрос - используйте двойную буферизацию, переключайте буфера по окончанию строки.


Да, мне много раз встречалось на форумах понятие двойной буфферизации, но как это реализутся на практике...

Цитата(dimka76 @ Jan 15 2010, 13:01) *
А рачем весь буфер сдвигать?


Так если я весь буфер не сдвину, как потом одновременно распихать уже изменненые данные по всем регистрам. Да и занимает это по времени всего 165 мкс, что никак не влияет на время индикации, и сдвиш идет между прерываниями.

Сообщение отредактировал rezident - Jan 16 2010, 19:50
Причина редактирования: Излишнее цитирование.
Go to the top of the page
 
+Quote Post
_dem
сообщение Jan 15 2010, 09:23
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



В любом случае весь вывод нужно вынести в прерывание.

1. Двойная буферизация - у вас два буфера и указатель на активный. Вы спокойно заносите данные в неактивный буфер, дожидаетесь конца строки, переключаете указатель на него. Вывод работает независимо от этого процесса, по прерываниям.

2. Сдвиг позиции. Расположите данные в буфере так, чтобы побайтно у вас читались столбцы. Дальше просто сдвигаете указатель "начало строки", опять-таки синхронно с "конец вывода строки".

ps. "Полное редактирование", "Спец элементы", CodeBox
Go to the top of the page
 
+Quote Post
Mark71
сообщение Jan 15 2010, 09:38
Сообщение #6





Группа: Участник
Сообщений: 9
Регистрация: 31-03-08
Пользователь №: 36 358



Цитата(_dem @ Jan 15 2010, 13:01) *
ps. Пардон, не досмотрел код. Оформите, пожалуйста, код нужным тегом - ну очень грустно смотреть в такой текст в пятницу )


Немного отредактировал для удобочитаемости. Ну не получается табуляцию вставить...

Кстати, если кого не затруднит, можно пообщаться на эту тему и по аське 495872629

Цитата(_dem @ Jan 15 2010, 13:23) *
1. Двойная буферизация - у вас два буфера и указатель на активный. Вы спокойно заносите данные в неактивный буфер, дожидаетесь конца строки, переключаете указатель на него. Вывод работает независимо от этого процесса, по прерываниям.


Т.е. все восемь столбцов на всех 16-ти индикаторах зажигать в одном цикле прерывания. Я правильно понял?

Сообщение отредактировал rezident - Jan 16 2010, 19:52
Причина редактирования: Излишнее цитирование.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 15 2010, 10:23
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Mark71 @ Jan 15 2010, 11:50) *
Скачок текста при переходе с одного индикатора на друой связан, как я понимаю, с увеличением паузы между 1-го столбцом одного индикатора и 7-м столбцом следующего. Фактически время между засветками равно времени двух регенераций. Вот и возникает скачок. И как с этим бороться?
Наверное, опечатка: между первым и восьмым столбцами?
Попробуйте "размазать" этот скачек по всей строке: "зажигайте" столцы не в порядке 1,2,3,..,8, а, например, в каком-то таком: 1,4,6,8,2,5,3,7
Go to the top of the page
 
+Quote Post
Mark71
сообщение Jan 15 2010, 10:33
Сообщение #8





Группа: Участник
Сообщений: 9
Регистрация: 31-03-08
Пользователь №: 36 358



Данные заносить в эти два буффера одновременно, что-ли? Что-то не въеду, пока...

Цитата(Палыч @ Jan 15 2010, 14:23) *
Наверное, опечатка: между первым и восьмым столбцами?
Попробуйте "размазать" этот скачек по всей строке: "зажигайте" столцы не в порядке 1,2,3,..,8, а, например, в каком-то таком: 1,4,6,8,2,5,3,7

Да, конечно между 1 и 8. Пробовал и так, и так. Вообщем абракадабра получается. Мне бы с двойной буфферизацией разобраться. Вроде в этом вся фишка.

Сообщение отредактировал rezident - Jan 16 2010, 19:53
Причина редактирования: Ненужное самоцитирование.
Go to the top of the page
 
+Quote Post
Андрей190
сообщение Jan 16 2010, 06:41
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 24-12-06
Из: Орел
Пользователь №: 23 838



Необходима построчная регенерация.
Для примера попробуйте сдвигать текст вверх-вниз.
В свое время долго боролся, пробовал разные варианты.
Оставил вариант с учетверением пикселов.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Jan 18 2010, 00:07
Сообщение #10


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



CODE
// [8x8] leds x 8, ATMega8, 1MHz, WinAVR

#define SCROLLING_DELAY_MS 150

static uint8_t video_buffer1_linear[64];
static uint8_t video_buffer2_linear[64];

static uint8_t * volatile video_buffer;

static volatile uint8_t ready_to_update;

void timer0_init(void)
{
TCCR0 = 0x00;
TCNT0 = 0x64;
TCCR0 = 0x02;

TIMSK |= 1;
}

ISR(TIMER0_OVF_vect)
{
TCNT0 = 0x64;

uint8_t *vb = video_buffer;
// ..вывод одного столбца на всех индикаторах
// данные берем по указателю vb

ready_to_update = 1;
}

__attribute__((OS_main)) int main(void)
{
//..
memcpy(video_buffer1_linear, ...); // начальное заполнение первого буфера

video_buffer = &video_buffer1_linear[0];

timer0_init();

sei();

for(;;)
{
_delay_ms(SCROLLING_DELAY_MS);

uint8_t tmp = video_buffer1_linear[0];
memcpy(video_buffer2_linear, video_buffer1_linear + 1, 63);
video_buffer2_linear[63] = tmp;

ready_to_update = 0;
while(!ready_to_update);

video_buffer = &video_buffer2_linear[0];

_delay_ms(SCROLLING_DELAY_MS);

uint8_t tmp1 = video_buffer2_linear[0];
memcpy(video_buffer1_linear, video_buffer2_linear + 1, 63);
video_buffer1_linear[63] = tmp1;

ready_to_update = 0;
while(!ready_to_update);

video_buffer = &video_buffer1_linear[0];
}

return 0;
}
rolleyes.gif

Сообщение отредактировал SysRq - Jan 18 2010, 01:19
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение Jan 21 2010, 00:52
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



Двойная буферизация не спасает от скачков между панелями. Бороться можно тремя путями.
Путь 1.
Сделать развертку по строкам, а не по столбцам. Если кол-во строк равно скважности, то такой проблемы не возникает. И при движении текста появляется эффект наклона букв и нет эффекта растяжения/сжатия Для "правильного" наклона вправо развертку нужно начинать с нижней строки. (в дальнейшем предполагаю, что строки нумеруются снизу) Алгоритм обычный - а) вывод с 0-й по 7-ю горизонталь б)сдвиг буфера влево на 1 вертикаль.
Если скважность 1:8, а кол-во строк 16 (2 панели одна над другой, каждая со скважностью 1:8), то при обычном подходе движущееся изображение будет "рваться" между панелями.
Для "правильного" отображения нужно организовать вывод на экран так, светящаяся активная строка развертки верхней панели "подхватывала" развертываемое изображение нижней панели.
Разъясняю:
Допустим, табло высотой в 16 точек состоит из 2х панелей, расположенныйх одна над другой. Каждая панель высотой в 8 точек. Развертка на панелях - снизу вверх, с 0-й по 7-ю строку. Развертка на обеих панелях синхронная, т.е. управление строчными ключами обейх панелей можно объединить. Таким образом, имеем 2 одновременно активных ключа. (2 луча, если проводить аналогию с ЭЛТ)
При отображении строка на верхней панели должна "подхватывать" изображение нижней, т.е. после 7й строки нижней панели 0-вая строка верхней должна продолжать отрисовывать тот же кадр. Так как оба ключа панелей работают одновременно, то нижняя панель в это же время должна рисовать уже следующий кадр изображения (возможно, уже сдвинутый влево на 1 точку). ТО есть мы дожны иметь 2 буфера - для верхней и нижней панели. и сдвиг изображения в буфере верхней панели делать на 1 кадр позже.

Проще говоря, изображение на каждой следующей (верхней) панели должно отставать ровно на 1 кадр развертки от изображения на предыдущей(нижней) панели, т.е. при регенерации 100Гц - на 10 мс. И так с каждой вышестоящей панелью (при высоте в 24,32,40 точек...).
Или выражаясь немного по-иному, каждый луч (лучем называю активный ключ, который пробегает с нижней строки нижней панели к верхней строке верхней панели) должен рисовать свой кадр. На строке высотой 16 точек таких луча 2 и, соответственно, в одно и то же время на строку выводится 2 разных кадра. И на каждый луч нужно иметь свой буфер.


Путь 2. Оставить развертку "по столбцам". Здесь эффекта наклона букв нет. Алгоритм реализации движения, собственно, ничем не отличается от первого пути. Принцип тот же. Только панели стоят боком. Но немного сложнее в реализации, так как здесь двумя или тремя буферами не обойдешся (ширина строки обычно > 24 точек). Насчет, эффекта растяжения/сжатия - ничег не скажу. На моей строке такого не наблюдал. Хотя на строках других производителей он мне даже понравился. Может, не наблюдал из-за того, что расстояние наблюдения строки было слишком малое. А от этого много чего зависит.

Ну, и 3-й путь (мой любимый) - статика. И для светодиодов полезно, и программировать проще некуда smile.gif. И побочных эффектов никаких нет. Благо, стоимость драйверов растворяется в стоимости хороших светодиодов.

З.Ы. "1 кадр развертки" специально выделил для того, чтобы отличать его от одного кадра генерируемого изображения. Т.е. когда одно генерируемое изображение выводится 2,3,4..... кадра.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01463 секунд с 7
ELECTRONIX ©2004-2016