Перейти к содержанию
    

7 сегментов и динамическая индикация

Позвольте поднять эту банальную тему в целях поиска окончательного решения проблемы распределения битов, портов и прочих неудобств. Вот один из моих вариантов, тоже в меру кривой, потому что всегда надо переписывать функцию do_screen() и переназначать сегменты и знакоместа. И он сугубо под WinAVR, но это не самое сложное, обеспечить в данном случае портабельность.

 

А кто пошел дальше? Может есть все-таки более элегантные решения, чем то, что у меня?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Позвольте поднять эту банальную тему в целях поиска ...

А кто пошел дальше? Может есть все-таки более элегантные решения, чем то, что у меня?

Не совсем в нему, но... Есть у меня подпрограммка на асме под АВР, с каментами, настраивается все на мой взгляд достаточно просто, дефайнами в начале. Выложить?

Изменено пользователем smac

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не совсем в нему, но... Есть у меня подпрограммка на асме под АВР, с каментами, настраивается все на мой взгляд достаточно просто, дефайнами в начале. Выложить?

Как хотите, у меня тоже эти все варианты в асме есть, благо, не первый день этим страдаю. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Позвольте поднять эту банальную тему в целях поиска окончательного решения проблемы распределения битов, портов и прочих неудобств. Вот один из моих вариантов, тоже в меру кривой, потому что всегда надо переписывать функцию do_screen() и переназначать сегменты и знакоместа. И он сугубо под WinAVR, но это не самое сложное, обеспечить в данном случае портабельность.

 

А кто пошел дальше? Может есть все-таки более элегантные решения, чем то, что у меня?

 

О май гад... В асме это проще выглядит... ;-)

Во всяком случае, мысли впихнуть перекодировку ASCII->LED у меня не возникало..

На семисегментнике ведь много не нарисуешь и в 99% хватает минимума типа Err F-1 F-2..

Постараюсь подумать, как свою мысль перевести на общечеловеческий (Си) язык..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

перед подключением модуля нужно определить маски сегментов (нулевой бит в соотв.разряде) и размер буфера индикации (количество разрядов).

lib.zip

Изменено пользователем ukpyr

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В асме это проще выглядит... ;-)

Вы ж поймите: тут задачи другие. Помимо того, что на индикатор может выводиться с тех пинов, с которых удобнее развести на плате, и не обязательно эти пины будут на одном порте,  так еще появляется соблазн делать программу переносимой на любой МК. На асме выполнима только первая часть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы ж поймите: тут задачи другие. Помимо того, что на индикатор может выводиться с тех пинов, с которых удобнее развести на плате, и не обязательно эти пины будут на одном порте,  так еще появляется соблазн делать программу переносимой на любой МК. На асме выполнима только первая часть.

У нас конструктор печатных плат тоже любит развести платку "как проще". Работаем на С++, поэтому я в этом случае делаю очередной производный класс, в котором определяю "виртуальную" шину, например для того же ЖКИ. А все остальные функции уже используют ее и не требуют изменения в своей реализации. ИМХО сдесь объектно-ориентированный подход очень хорошо ложиться.

А вот с переносимостью пока только в пределах семейства, все-таки организация на физическом уровне может отличаться. MCS51, PIC, AVR, 196, 166. Нужно писать порты под каждую платфому.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно писать порты под каждую платфому.

Если Вы смотрели то, что я выкладывал, то там переносимость обеспечивается отвязкой от прерывания через опрос тиков системного таймера, PROGMEM тоже легко будет на const _flash или чего-то подобного - сделаю, как и чтение этого PROGMEMа. И еще мой вариант учитывает возможный опрос линий возврата клавиатуры:

 

 

#include "keyb.h"
#include "led7.h"
#define T5ms 5000

static timer_t screen_time =0;

if(time_diff(screen_time) > T5ms)

{
 screen_time = get_time();

// в таком случае связи модулей led7 и keyb нет вообще
 do_keyboard(le7s.pos);
// делаем то,что надо с экраном
 do_screen();
}

 

В принципе, можно определить указатель на экран как входной параметр

do_screen(led7_scr_t *screen)

Тогда можно описывать do_screen где угодно - например в главном модуле. Что думаете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В принципе, можно определить указатель на экран как входной параметр

do_screen(led7_scr_t *screen)

Тогда можно описывать do_screen где угодно - например в главном модуле. Что думаете?

Боюсь сморозить чушь (только начинаю изучать), но я обычно (в асме) работу экрана выношу в отдельную, изолированную от всего функцию. У неё нет входных параметров (кроме отображаемого буфера, в который программа пишет необходимые вещи). По прерыванию вызывается процедура экрана, которая сама через указатель из буфера берет байт, перекодирует и выводит в порт. Указатель на буфер и таймер инкрементируется внутри прерывания и программа (основная) не знает, что там экран делает. То же самое с кнопками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 Я в асме делал точно так же - все в прерывании. Но со временем появились и другие варианты. Оно может быть и в прерывании, и в основном цикле, и в функции, в которой собраны все быстрые задачи- чтоб  не "вешать" контроллер во время ожиданий. А в прерываниях находится минимальное время - прочитал/записал в/из буфера и все. Это уж  кому как нравится. Или как позволяет задача.

 

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 Я в асме делал точно так же - все в прерывании. Но со временем появились и другие варианты. Оно может быть и в прерывании, и в основном цикле, и в функции, в которой собраны все быстрые задачи- чтоб  не "вешать" контроллер во время ожиданий. А в прерываниях находится минимальное время - прочитал/записал в/из буфера и все. Это уж  кому как нравится. Или как позволяет задача.
Ключевая здесь последняя фраза. У меня всё сделано на СИ и в прерываниях. Вывести пару байт в порты - много времени не занимает, зато запись в EEPROM, трафик по UART с протоколом modbus и т.п. никак не сказываются на индикации. Я много экспериментировал - если не в прерывания, то получаются взмаргивания индикации - выглядит недостойно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...