,часы, термометр,ну и соответственно текст ,если перемещать символы со с одного знакоместа на другое то конечно это оч просто и проблем нет,а вот чтоб двигать символы на один пиксель в лева или право бьюсь головой об стол))в низ и вверх тоже оч просто)) а вот в бок( тоесть нужно в один отображаймый байт переписывать какуюто часть одного байта и соседнего байта из буфера в котором уже лежит подготовленная картинка )) не прошу кода хоть намекните на нормальном русском языке,а если кусочек для примера покажите ну просто супер будет))
бегущая сторока Code Vision
доброго времени суток)) вообщем проблема в следующем пишу Бегущею строку ,то есть дисплей 8х64 пикселя
,часы, термометр,ну и соответственно текст ,если перемещать символы со с одного знакоместа на другое то конечно это оч просто и проблем нет,а вот чтоб двигать символы на один пиксель в лева или право бьюсь головой об стол))в низ и вверх тоже оч просто)) а вот в бок( тоесть нужно в один отображаймый байт переписывать какуюто часть одного байта и соседнего байта из буфера в котором уже лежит подготовленная картинка )) не прошу кода хоть намекните на нормальном русском языке,а если кусочек для примера покажите ну просто супер будет))
,часы, термометр,ну и соответственно текст ,если перемещать символы со с одного знакоместа на другое то конечно это оч просто и проблем нет,а вот чтоб двигать символы на один пиксель в лева или право бьюсь головой об стол))в низ и вверх тоже оч просто)) а вот в бок( тоесть нужно в один отображаймый байт переписывать какуюто часть одного байта и соседнего байта из буфера в котором уже лежит подготовленная картинка )) не прошу кода хоть намекните на нормальном русском языке,а если кусочек для примера покажите ну просто супер будет))
- Реклама
- Сообщения: 85
- Зарегистрирован: Пн мар 07, 2011 19:52:52
Всё зависит от кода вашего,как выводите символы, вот я тоже застрял,потом временно забросил,знаю как,но на си сделать пока не сделал,в моем случае примерно так- выводишь строку-16 на X светодиодов,чтоб забегало нужно каждый раз не выводить первый ряд(16 светодиодов),т.е. начинать каждый раз со следующего ряда,но я делаю на статическую индикацию,т.е. у меня одновременно загораются все светодиоды, а на динамику 8 рядов исходник в инете есть.
Двигать влево-вправо очень просто. Допустим, имеется буфер видеопамяти video_ram[MAX_BUF_LEN]. Этот буфер регенерируется на табло например по переполнению таймера.
В случае если вы используете вертикальную упаковку байтов символов:
Если используется горизонтальная упаковка(как в старых досовских фонтах), то надо использовать операции сдвига.
Использование:
Тело ф-ции get_next_byte() не раскрываю т.к. оно целиком зависит от выбранного типа шрифта(пропорциональный, моноширинный), да и вообще от структуры вашей программы.
В случае если вы используете вертикальную упаковку байтов символов:
Код: Выделить всё
void shift_left(void)/*сдвинуть на 1 столбец влево*/
{
char i;
for(i=0;i<MAX_BUF_LEN;i++)
video_ram[i]=video_ram[i+1];
}Использование:
Код: Выделить всё
shift_left();
video_ram[MAX_BUF_LEN-1]=get_next_byte();/*вставить в освободившийся правый столбец новый байт*/
- Сообщения: 782
- Зарегистрирован: Вт апр 26, 2011 18:37:06
Бьюсь челом перед вами, надо попробовать:)
На практике можно не успеть сделать того, что можно хорошо обосновать в теории. Но без практики теория может отдаляться от нее, и когда они встретятся снова - не узнает даже неприкосновенное шампанское профессора в лаборатории. Моя практика: robofeya.ru
- Реклама
шрифт старый ДОСовский, то есть :
1 байт 1 байт 1 байт ........
2 байт 2 байт 2 байт ......
3 байт 3 байт 3 байт
.....
.....
1 знакоместо 2 знакоместо 4 знакоместо
в памяти лежат с лева на право ,с низу в верх то есть 1 байты (1-8) знакместа
далее 2 байты почереди и тд
строка по 8байт выводиться за одни цикл на 8 шт 595
затем 2 затетем теретья....
1 байт 1 байт 1 байт ........
2 байт 2 байт 2 байт ......
3 байт 3 байт 3 байт
.....
.....
1 знакоместо 2 знакоместо 4 знакоместо
в памяти лежат с лева на право ,с низу в верх то есть 1 байты (1-8) знакместа
далее 2 байты почереди и тд
строка по 8байт выводиться за одни цикл на 8 шт 595
затем 2 затетем теретья....
- Сообщения: 85
- Зарегистрирован: Пн мар 07, 2011 19:52:52
У меня вот так-
У меня, чтобы налево двигать,нужно каждый раз выкидывать 2 байта,т.е. не выводить на табло,с массива sym, 2 байта-это у меня 1 вертикальный ряд. Как сделать чтоб забегало ?

Код: Выделить всё
unsigned char str[]={"12345"}; // Это выводимая на табло строка
unsigned char mass[sizeof(str)]; // Массив для переливания
// Переливаем массив str в mass- так надо
void str_to_mass(){
unsigned char k=0, v=sizeof(str)-1;
while (k<sizeof(str)){
mass[v]=str[k];
k++; v--;}}
// Функция извлечения битов из массива знаков
void bits(){unsigned int i,j;
for (i=0; i<32; i++) {
for (j=0; j<8; j++) {
if (sym[x][i] & (1 << j))
{DS = 1;} //записываем в линию данных
else {DS = 0;}
bitvreg; //Дергаем ногой чтоб пропихнуть бит в регистр
}}}
// А вот и массив знаков или шрифт..
flash unsigned char sym[][32]={
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F,
0xFC, 0x3F, 0xFC, 0x3F, 0x0E, 0x70, 0x06, 0x60,
0x06, 0x60, 0x0E, 0x70, 0xFC, 0x3F, 0xFC, 0x3F,
0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0xFE, 0x7F,
0xFE, 0x7F, 0x00, 0x38, 0x00, 0x18, 0x00, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 1
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1E,
0x06, 0x3F, 0x86, 0x7F, 0x86, 0x73, 0xC6, 0x61,
0xE6, 0x60, 0xF6, 0x70, 0x7E, 0x78, 0x3E, 0x38,
0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} // 2 и дальше так..
// Читаем строку и подставляем символы
void read_stroka(){unsigned int i;
for(i=0; i<sizeof(str); i++){
switch(mass[i]){
case '0': {x=0; bits();} ; break;
case '1': {x=1; bits();} ; break;
case '2': {x=2; bits();} ; break;
case '3': {x=3; bits();} ; break;
case '4': {x=4; bits();} ; break;
case '5': {x=5; bits();} ; break;
case '6': {x=6; bits();} ; break;
case '7': {x=7; bits();} ; break;
case '8': {x=8; bits();} ; break;
case '9': {x=9; bits();} ; break;
case 'А': {x=10; bits();} ; break; // и др. так..
}}}
void main (void){
str_to_mass(); // Переливаем массив str в mass
while(1){
read_stroka();
zacelk; //Дергаем ногой и защёлкиваем данные(вывод на табло)
}
}
Последний раз редактировалось ARM7 Сб май 14, 2011 15:03:51, всего редактировалось 1 раз.
блин а я то заморочился с выводом по SPI а так и кногам можно любым прикрутить и всё проще)))
- Сообщения: 1800
- Зарегистрирован: Вт окт 05, 2010 01:08:57
вдруг пригодится
- Вложения
-
- знакогенераторы и готовые шрифты.rar
- (400.65 КБ) 179 скачиваний
KIT
ммм не очень понял проблему....ARM7 писал(а):У меня вот так-У меня, чтобы налево двигать,нужно каждый раз выкидывать 2 байта,т.е. не выводить на табло,с массива sym, 2 байта-это у меня 1 вертикальный ряд. Как сделать чтоб забегало ?Код: Выделить всё
} }![]()
- Сообщения: 85
- Зарегистрирован: Пн мар 07, 2011 19:52:52
Ну код выше-это просто вывод на табло, например если у меня табло будет 16х80 светодиодов-1 знак у меня 16х16- значит умещается только 5 букв или цифр,а если строка длиннее?-а она и будет длиннее-вот как для моего кода сделать так,чтоб получилась бегущая,а не стоящая строка?
ARM7 писал(а):Ну код выше-это просто вывод на табло, например если у меня табло будет 16х80 светодиодов-1 знак у меня 16х16- значит умещается только 5 букв или цифр,а если строка длиннее?-а она и будет длиннее-вот как для моего кода сделать так,чтоб получилась бегущая,а не стоящая строка?
а символы как закодированы расположены?
то есть верхния ( назовем строкой ))) верхния строка символа певый байт,втроя строка второй байт...или как то подругомуmaxpetr1993 писал(а):ARM7 писал(а):Ну код выше-это просто вывод на табло, например если у меня табло будет 16х80 светодиодов-1 знак у меня 16х16- значит умещается только 5 букв или цифр,а если строка длиннее?-а она и будет длиннее-вот как для моего кода сделать так,чтоб получилась бегущая,а не стоящая строка?
а символы как закодированы расположены?
C SPI действительно проще/быстрее выбрасывать в регистры чем простым ногодрыганьем. Пока у вас процик больше ничего не делает кроме как выводит бегущую строку, то его быстродействия хватает. А когда вы доходите до того что надо делать несколько видеобуферов/видеослоев для графических эффектов с их обработкой в реалтайме, то начинаете понимать всю прелесть аппаратных интерфейсов)))ARM7 писал(а):блин а я то заморочился с выводом по SPI а так и кногам можно любым прикрутить и всё проще)))
ARM7 писал(а): switch(mass){
case '0': {x=0; bits();} ; break;
case '1': {x=1; bits();} ; break;
case '2': {x=2; bits();} ; break;
case '3': {x=3; bits();} ; break;
Афигеть... ARM7, а не проще ли было записать x=mass-'0'; Ну или если там выброшены служебные символы, то можно добавить несколько if-ов чтобы "дыр" в кодировке не было... Впрочем если ваш ник соответствует камню на котором работаете, то пока о потребляемой памяти можете не заморачиваться. Но это только пока:)
ARM7 писал(а):как для моего кода сделать так,чтоб получилась бегущая,а не стоящая строка?
Вариант 1. Вы сейчас просто считываете из флеша образы буков. Отведите небольшой видеобуфер как я писал выше и копируйте туда ваши буковки. Потом двигайте.
Вариант 2. Более хитроумный. Организовать несколько счетчиков: на текуще считываемый номер символа, число его прочитанных битов, сколько целых символов отобразилось на табло и т.д. И при считывании из флеша налету сдвигать и накладывать байты. Но пока лучше попробуйте справиться с простым вариантом.
Мда и я погарячился немного с откозом от SPI с ним то проще )))вообщем для сдвига строки в лево и ли право нада писать сдвиговый регистр 64 разряда ))) всё оч просто )) толька КАК??????????

- Сообщения: 85
- Зарегистрирован: Пн мар 07, 2011 19:52:52
-Вот и для простого варианта ума не хватает пока,похоже со своим кодом загнал себя в тупик. А про SPI не думал даже, а там как примерно это делается? Тот код писал для атмеги16, нужно было выводить температуру, время, ну еще какой нибудь текст,про изображения даже и не думал.uk8amk писал(а): попробуйте справиться с простым вариантом.
ну очень просто вызывается по прерыванию ,за один вызов одна строка выплёвывается в апаратный ISP примерно както так))
{
PORTC=0xff;
led_status<<=1;
led_status|=1;
if (led_status==0xff) led_status=0xfe;
i++;
if (i==8) i=0;
temp=spi(scr1[7]);
temp=spi(scr1[6]);
temp=spi(scr1[5]);
temp=spi(scr1[4]);
temp=spi(scr1[3]);
temp=spi(scr1[2]);
temp=spi(scr1[1]);
temp=spi(scr1[0]);
PORTB.6=0;
PORTB.6=1;
PORTB.6=0;
PORTC=led_status;
}
led_status; это просто бегущий ноль ,тоесть строка которая в данный момепнт защелкнута и светится до следующего вызова
PORTB.6=0; это защелка регисторв 595
{
PORTC=0xff;
led_status<<=1;
led_status|=1;
if (led_status==0xff) led_status=0xfe;
i++;
if (i==8) i=0;
temp=spi(scr1[7]);
temp=spi(scr1[6]);
temp=spi(scr1[5]);
temp=spi(scr1[4]);
temp=spi(scr1[3]);
temp=spi(scr1[2]);
temp=spi(scr1[1]);
temp=spi(scr1[0]);
PORTB.6=0;
PORTB.6=1;
PORTB.6=0;
PORTC=led_status;
}
led_status; это просто бегущий ноль ,тоесть строка которая в данный момепнт защелкнута и светится до следующего вызова
PORTB.6=0; это защелка регисторв 595
- Сообщения: 85
- Зарегистрирован: Пн мар 07, 2011 19:52:52
А как SPI может экономить память и ресурсы МК? Ну я заливаю сразу биты в сдвиговые регистры и защелкиваю, а с SPI-то же самое-туда тоже заливать надо биты, потом оттуда в сдвиговые регистры,это займет столько же тактов процессора или больше, наверно.
Нет-нет, SPI не экономит память и в него надо заливать целые байты(применительно к AVR - это байт-ориентированный интерфейс). Вы видимо посылаете байт в SPI, затем в цикле крутитесь и ждете флажка окончания приема. Давайте прикинем(опять же на примере AVR). Для SPI клока: Fspi_max=Fcpu/2. Если используется доп. предделитель, то отношение частот еще больше. Т.е. передача байта закончится никак не раньше 16 тактов и все эти 16 тактов вы крутитесь в цикле. Вы говорите, что формируете этот SPI программно. Отлично, помножим 16 в 2-3 раза. Т.е. к примеру на посылку 10 байт бы убъете 320 - 480 пустых тактов процессора в лучшем случае.
Теперь вспомним, что у SPI(как и у UART) есть прерывание по концу передачи. Мы формируем выходной буфер, быстро туда забрасываем байтики, говорим SPI вперед и забываем про него. В обработчике прерывания записан логический автомат, который сам выбирает следующий байт из очереди. Вот кусок из реальной программы:
(Использован UART в режиме совместимости SPI)
Пока SPI работает, процессор уже успевает подготовить новую порцию данных на выброс. Вот в чем его фишка. Эта тема много глубже развита в камнях с поддержкой DMA, но это уже выходит за пределы возможностей традиционной атмеги.
Теперь вспомним, что у SPI(как и у UART) есть прерывание по концу передачи. Мы формируем выходной буфер, быстро туда забрасываем байтики, говорим SPI вперед и забываем про него. В обработчике прерывания записан логический автомат, который сам выбирает следующий байт из очереди. Вот кусок из реальной программы:
(Использован UART в режиме совместимости SPI)
Код: Выделить всё
interrupt [USART1_TXC] void usart1_tx_isr(void)
{//MSPIM1 interrupt
if(rb_tx_cnt)//rb_tx_cnt>0
{
if(use_inversion)
{
temp=~stream_buffer[++rb_rd_ptr];
UDR1=temp;
temp=~stream_buffer[++rb_rd_ptr];
UDR1=temp;
}
else
{
temp=stream_buffer[++rb_rd_ptr];
UDR1=temp;
temp=stream_buffer[++rb_rd_ptr];
UDR1=temp;
};
rb_tx_cnt-=2;
rb_cnt-=2;
}
else//rb_tx_cnt=0
{
DAT_LATCH1=1;
PWM_R=tmp_r;
PWM_G=tmp_g;
PWM_B=tmp_b;
};
} - Сообщения: 85
- Зарегистрирован: Пн мар 07, 2011 19:52:52
Понятненько, значит SPI берет с указанного массива байты и побитно сует в регистры сдвига бегущей строки(в нашем случае), это почти как у меня, только культурнее
,надо как то попробовать,это даже легче будет мне сделать чтоб забегала строка, похоже.


