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

 
 
> Редактирование строки на ЖКИ., Ввод времени в RTC
alux
сообщение Dec 14 2007, 16:53
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Простая, казалось бы на первый взгляд задача... Но вот уже вторые сутки ломаю голову. Не могу придумать как это лучше сделать. Хочу, как в мобильном телефоне настраивать время. Вот мой кусок кода:
Код
void EditTime_Func(void)
{
  unsigned char temp;
  rtc_get_time(0x99);      //значение времени в yr, mn, dt, dy, hr, min, sec
  ClearScreen();    // display clear      
  GotoXY(0,0);    
  sprintf_P(lcd_buf,"%d/%d/%d %d  %02d:%02d:%02d", yr, mn, dt, dy, hr, min, sec);
  PutStr(lcd_buf);
  w=CharWidth(*plcd_buf)-2;
  start_Timer(TIMER_0, 500, blink, TIMER_CYCLE);

  for(;;)
  {
    temp=key_get();
    switch(temp)          //key_code.scan
    {
        case LEFT:        //k_esc
            {......}
             break;
        case RIGHT:       //k_enter
             {......}
             break;
        case DOWN:        //k_left
             {......}
             break;
        case UP:          //k_right
              {......}
             break;  
        default:          // 0...9
             {......}
             break;            
    }
    
    if(key_code.scan == LEFT)  //выход из функции
    {
       stop_Timer(TIMER_0);
       break;
    }
  }
}

//------------------------------------------------------------------------------
void blink(void)
{
  InvertRect(x, y, w, 9);
}

Идея такая. Вывожу на экран значение времени в виде строки:
"2007/12/24 1 12:32:00"
Ф-ция start_Timer() запускает каждые 0,5 сек ф-цию blink(), которая в свою очередь инвертирует заданный прямоугольник. Т.е. должно мигать текущее знакоместо. Кнопками UP, DOWN выбираю следующее, предыдущее знакоместо. Ввод числа осуществляется с клавиатуры 4х4. Это все у меня работает. Проблема еще в том, что символы имеют переменную ширину. Поэтому после каждого ввода символа необходимо ,наверное, перерисовывать всю строку. После нажатия ENTER новые значения переменных необходимо записать в RTC. Как сделать ввод чисел только в заданные места, т.е. пропускать '/' , ' ' , ':' ? Меня не покидает чувство, что изобретаю велосипед.
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 32)
SasaVitebsk
сообщение Dec 14 2007, 17:27
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Я реализовывал такую задачу. Правда на ассемблере и на х51 процессоре.
Я поступал следующим образом (правда у меня было много меню с различными зонами, возможно несколькими, на экране)

И я строил меню, как структуру, где указывал тип зоны ввода, левый край и размер, а также максимальное и минимальное возможное значение. В самом меню использую псевдо-символы управления курсором по принципу терминала. Это даёт возможность грамотного управления и редактирования. Приведу кусок хидера своей библиотеки.
Код
// Управляющие символы дисплея LCD

#define    CR_BS            8                                // BackSpace        /b
#define    CR_TAB            9                                // TAB                /t
#define    CR_LF            0xa                                // LF                /a
#define    CR_NEW            0xc                                // CLR                /f
#define    CR_ENTER        0xd                                // ENTER            /r
#define    CR_LEFT            0x11                            // LEFT                /x11
#define    CR_RIGHT        0x12                            // RIGHT            /x12
#define    CR_UP            0x13                            // UP                /x13
#define    CR_DOWN            0x14                            // DOWN                /x14
#define    CR_HOME            0x15                            // HOME                /x15
#define    CR_BEEP            0x17                            // BEEP                /x17
#define    CR_CURHIDE        0x18                            // HIDE                /x18
#define    CR_CURSHOW        0x19                            // SHOW                /x19
#define    CR_CURDIRECT    0x1b                            // Direct Cursor    /x1b

// Прототипы    функций

void LCDInit(void);                                        // Инициализация LCD дисплея. Вызывается из    модуля инициализации.
void GotoXY(uint8_t    x,uint8_t y);                        // Установит курсор в позицию X,Y.
int8_t cr_left(void);                                    // Курсор влево.
int8_t cr_right(void);                                    // Курсор вправо.
uint8_t    cr_up(void);                                    // Курсор вверх
uint8_t    cr_down(void);                                    // Курсор вниз.
void cr_home(void);                                        //    в начало строки
int16_t    putchar(int16_t    c_in);                            // Вывести символ    в кодировке    Win. с управляющими    символами
void spliter_init(void);                                // Инициализировать сплитер.
void spliter(uint8_t pos, uint8_t maxpos);                // Отобразить сплитер
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 14 2007, 18:16
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Разделите логически в программе ввод, вывод и редактирование, а потом совместите их. Т.е. с помощью клавиатуры вы будете редактировать какую-то переменную время/дата. И эту же переменную выводить на экран после каждой модификации полностью. Не нужно будет ломать голову как совместить видимую позицию курсора и редактируемый символ.
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 14 2007, 20:32
Сообщение #4


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(rezident @ Dec 14 2007, 20:16) *
Разделите логически в программе ввод, вывод и редактирование, а потом совместите их. Т.е. с помощью клавиатуры вы будете редактировать какую-то переменную время/дата. И эту же переменную выводить на экран после каждой модификации полностью. Не нужно будет ломать голову как совместить видимую позицию курсора и редактируемый символ.

rezident дело говорит. "В одну корзину класть не можно на яйца сверху серп и молот" smile.gif

Всегда делаю различные процедуры для индикации и обработки клавиатуры. Логически эти процедуры связаны только через переменную MenuNumber, которая указывает на номер текущего меню (на тип информации, выводимой на дисплей). Обработчик клавиатуры верхнего уровня ServiceKeys в зависимости от значения MenuNumber и нажатых кнопок производит нужные действия, напр.:
-выбор параметра для редактирования - перемещает мигающее поле на дисплее;
-вход в режим изменения параметра - копирует выделенную переменную в буфер редактора;
-изменение параметра - меняет переменную в буфере редактора;
-выход из режима изменения параметра - сохраняет переменную;

Процедура вывода на дисплей RedrawLCD вызывается раз в 1 сек и после обработки клавиатуры.
Эта процедура по значению MenuNumber выводит на дисплей нужные параметры, беря их или напрямую, или из буфера редактора. Эта процедура и занимается преобразованием бинарных переменных в ASCII коды.
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 15 2007, 09:57
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(Baser @ Dec 15 2007, 00:32) *
Всегда делаю различные процедуры для индикации и обработки клавиатуры. Логически эти процедуры связаны только через переменную MenuNumber, ...

Можете привести для наглядности свой код?
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 15 2007, 16:15
Сообщение #6


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(alux @ Dec 15 2007, 11:57) *
Можете привести для наглядности свой код?

Какой то конкретный код привести вряд ли смогу, это все ненаглядно и громоздко.

Еще некоторые соображения по поводу вашего примера кода. Если вы не применяете RTOS и не запускаете эту процедуру как отдельную задачу, то у вас во время редактирования часов прибор ничего больше не делает (только прерывания). Я применяю несколько другой метод организации обработки клавиатуры и дисплея, который без RTOS обеспечивает выполнение алгоритмов кусками, отдельными состояниями конечного автомата (по сути это работа по флагам).

Общая структура следующая:
- Один таймер выделяется под системный, который обеспечивает регулярное прерывание, в котором выставляется флаг f10ms_Past.
- Этот флаг обрабатывается в основном цикле main, где формируются места, которые выполняются через равные промежутки: 10 мс, 1 сек, другие необходимые.
Код
//--------------------------------------------------------------//
//       10 milliseconds, One and Ten seconds Procedures        //
//--------------------------------------------------------------//
  if (f10ms_Past)                 // 10 ms past
    {
    f10ms_Past = 0;
    ReadKeys();
    RunADC();
    Task1_Service();
    Task2_Service();
    ...................
    if (++TenMilliSecCnt >= 100)  // 1 second past
        {
        TenMilliSecCnt = 0;
        poGreenLED ^= 1;        // Toggle green LED
        RedrawLCD();            // Redraw LCD module
        ....................
        if (++SecCnt >= 10)     // 10 seconds past
            {
            SecCnt = 0;
            .................
            }
        }
    }
//--------------------------------------------------------------//
//          Keys service Conditions Determination               //
//--------------------------------------------------------------//
    if (fShortKey || fLongKey)
        {
        ServiceKey();
        RedrawLCD();
        }
   .....................

- Каждые 10 мс выполняется процедура ReadKeys(); которая является драйвером клавиатуры нижнего уровня и занимается сканированием кнопок, обработкой дребезга, распознает длительность нажатия, автоповтор и т.д. Результат ее работы - значения регистров статуса и флаги нажатия.
- Обработчик клавиатуры верхнего уровня ServiceKeys(); вызывается по наличию флагов. Его работу я уже описал.
- Про функцию вывода на дисплей я уже тоже писал.

Важное замечание: вся эта структура будет хорошо работать только в том случае, если обеспечивается, что время работы любой функции не превышает 10 мс и хотя бы раз за 10 мс выполняется главный цикл. Но я обычно пишу так, что это условие всегда выполняется.
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 15 2007, 20:28
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Baser @ Dec 15 2007, 21:15) *
- Один таймер выделяется под системный, который обеспечивает регулярное прерывание, в котором выставляется флаг f10ms_Past.

А я делаю более логично. В "тиковом" прерывании инкрементирую переменную на величину периода "тика". Получается, что ее значение является временной меткой, выраженной в миллисекундах. 16-и битной переменной хватает для отсчета интервала времени больше минуты, а 32-х битная переменная переполняется только через почти полтора месяца.
Цитата(Baser @ Dec 15 2007, 21:15) *
Важное замечание: вся эта структура будет хорошо работать только в том случае, если обеспечивается, что время работы любой функции не превышает 10 мс и хотя бы раз за 10 мс выполняется главный цикл. Но я обычно пишу так, что это условие всегда выполняется.

Если имеется упомянутая мной выше переменная "миллисекундных тиков", то нет необходимости так строго выдерживать период "суперцикла". Ограничивать период выполнения суперцикла приходится лишь в том, случае в его теле вычисляется, например, управляющее воздействие, которое должно быть обязательно выдано за определенный промежуток времени.
Если же вернуться к теме топика, то при наличии ресурсов в ОЗУ формируется буфер экрана и все изменения, определяемые функциями меню, делаются в нем. Затем весь буфер одной функцией выводится на экран. При необходимости для ускорения вывода можно пропускать элементы изображения, которые не изменились за текущий цикл, а выводить на экран только изменения.
Клавиатура у меня обычно тоже имеет свой буфер в который помещаются заранее определенные коды клавиш. Обрабатываются кнопки, устраняется дребезг, формируются коды клавиш и заполняется буфер в том же самом "тиковом"прерывании.
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 15 2007, 21:49
Сообщение #8


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(rezident @ Dec 15 2007, 22:28) *
А я делаю более логично. В "тиковом" прерывании инкрементирую переменную на величину периода "тика". Получается, что ее значение является временной меткой, выраженной в миллисекундах. 16-и битной переменной хватает для отсчета интервала времени больше минуты, а 32-х битная переменная переполняется только через почти полтора месяца.

При таком решении мне немного не понятно, как можно без дополнительных флагов обеспечивать выполнение периодических процедур главного цикла ОДИН раз за их номинальный период. МК в моменты простоя может все время крутиться в main и пролетать через них сотни раз за время одного "тика" прерывания.
Цитата(rezident @ Dec 15 2007, 22:28) *
Если имеется упомянутая мной выше переменная "миллисекундных тиков", то нет необходимости так строго выдерживать период "суперцикла". Ограничивать период выполнения суперцикла приходится лишь в том, случае в его теле вычисляется, например, управляющее воздействие, которое должно быть обязательно выдано за определенный промежуток времени.

Ну, как показывает практика, даже пропадание 1-2-х 10 мс процедур никак не сказывается на нормальной обработке клавиатуры и дисплея. Дребезг то на уровне 50-70 мс, сами понимаете.
Цитата(rezident @ Dec 15 2007, 22:28) *
Клавиатура у меня обычно тоже имеет свой буфер в который помещаются заранее определенные коды клавиш. Обрабатываются кнопки, устраняется дребезг, формируются коды клавиш и заполняется буфер в том же самом "тиковом" прерывании.

В первых своих работах я тоже делал обработку клавиатуры в прерывании, а потом перестал, потому что нету смысла: обработка неспешная и нечего ей занимать драгоценное время прерываний.
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 15 2007, 22:21
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Baser @ Dec 16 2007, 02:49) *
При таком решении мне немного не понятно, как можно без дополнительных флагов обеспечивать выполнение периодических процедур главного цикла ОДИН раз за их номинальный период. МК в моменты простоя может все время крутиться в main и пролетать через них сотни раз за время одного "тика" прерывания.
Дык у каждого процесса своя переменная заданного периода. Простым вычитанием двух беззнаковых переменных определяется закончился требуемый процессу интервал времени или еще нет.
Код
switch (mnuFlag)
{ case MNU_LEVEL1:
    mnu_time=tickTime;  //фиксируем отметку времени
    mnuFlag=MNU_LEVEL2;
    break;
  case MNU_LEVEL2:
    if ((tickTime-mnu_time)<5000) break; //ждем окончания интервала времени 5сек
    else
    {
      ...
      mnuFlag=MNU_LEVEL3;
    }
    break;
  case MNU_LEVEL3:
    ...
    ....
}

Цитата(Baser @ Dec 16 2007, 02:49) *
Ну, как показывает практика, даже пропадание 1-2-х 10 мс процедур никак не сказывается на нормальной обработке клавиатуры и дисплея.
Ну да, со скоростью 100 раз в секунду ни одна супер-пупер-машинистка долбить по клаве не сможет. biggrin.gif
Цитата(Baser @ Dec 16 2007, 02:49) *
Дребезг то на уровне 50-70 мс, сами понимаете.
Это довольно плохие контакты. Я не припомню, чтобы мы применяли кнопки у которых дребезг превышал 10мс. Обычно не более единиц мс.
Цитата(Baser @ Dec 16 2007, 02:49) *
В первых своих работах я тоже делал обработку клавиатуры в прерывании, а потом перестал, потому что нету смысла: обработка неспешная и нечего ей занимать драгоценное время прерываний.
Хозяин-барин. Все от задачи зависит. Некоторые задачи вообще полностью в "тиковом" прерывании выполняются (исключая конечно же начальную инициализацию).
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 16 2007, 10:01
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(alux @ Dec 14 2007, 18:53) *
Проблема еще в том, что символы имеют переменную ширину....
Как сделать ввод чисел только в заданные места, т.е. пропускать '/' , ' ' , ':' ?
наверное, завести массив структур на каждое редактируемое число, по структуре на редактируемое знакоместо. В структуре хранить смещение и размер редактируемого знакоместа (а возможно и допустимые значения). Размер, равный нулю, говорит о том, что знакоместа кончились.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 16 2007, 10:50
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Тоже делаю временные метки.
Сейчас сделаю отдельную тему и там выложу исходники по вводу с матричной клавиатурой и выводу на дисплей с примерами.
PS: Выложил в библиотеки. Если есть какие вопросы, то можно здесь
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 16 2007, 11:47
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(Сергей Борщ @ Dec 16 2007, 14:01) *
наверное, завести массив структур на каждое редактируемое число, по структуре на редактируемое знакоместо. В структуре хранить смещение и размер редактируемого знакоместа (а возможно и допустимые значения). Размер, равный нулю, говорит о том, что знакоместа кончились.

Сложно все это как-то. Ширина символов у меня хранится в структуре шрифта. Эту ширину можно получить ф-цией CharWidth();Значение этой ф-ции прибавляю или отнимаю к текущей координате X, в которую необходимо переместить мигающий курсор и вводимый символ. Я думаю , может использовать ф-ции strtok или strtol. Только не знаю еще как. В общем, мне нужен пример ф-ции strEdit(); которая редактирует посимвольно строку в зависимости от нажатой кнопки. Неужели никто этого не делал? Только без всяких RTOS.
Цитата(SasaVitebsk @ Dec 16 2007, 14:50) *
PS: Выложил в библиотеки. Если есть какие вопросы, то можно здесь

В каких библиотеках?
P.S. Я немного упростил задачу. Время вывожу в формате:
год : 2007
месяц : 12
дата : 14
день : 1
час : 13
минут : 30
Так даже наглядней будет. Строки переменных времени начинаются с коорд. X=50. Меняется коорд. Y для каждой переменной.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 16 2007, 11:55
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Сергей Борщ @ Dec 16 2007, 12:01) *
завести массив структур...

Усложняешь, Сергей sad.gif Когда нужно было сделать подобный ввод, то не мудурствуя лукаво
- была взята строка-шаблон;
- выведена на дисплей;
- курсор был воткнут на одно из редактируемых полей;
- символ под курсором анализировался на digit/ASCII/separator, то не позволяло вводить символы не характерные для данного шаблона и позволяло перемещаться курсором сквозь символы не являющиеся символами характерными для данного поля;
- при необходимости дополнительно можно было наложить дополнительные ограничения на перемещения курсора в пределах строки.
- полученная таким редактированием строка-шаблон прогонялась обратно через sscanf() и .. и все.

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

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 16 2007, 12:16
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Дык алгоритм-то редактирования простейший.
1 уровень - "бегаем" по строке вправо-влево в заданных размером строки пределах. Если нажата кнопка, отличающаяся от "вправо"/"влево", то "проваливаемся" на второй уровень.
2 уровень - в зависимости от текущего положения курсора, редактируем какую-то конкретную переменную - year, month, day, hour, min, sec. Причем изменение ее (инкремент или декремент) идет на величину кратную положению курсора. Т.е. если редактируем вторую цифру минут, то декремент/инкремент переменной min при нажатии на кнопки "вверх"/"вниз" (или какие там у вас выделены для редактирования?) идет не на 1, а на 10. Естественно тут нужна проверка на выход за разрешенный для данной переменной диапазон значений. Например, 70 минут не бывает. Поэтому min может меняться только в пределах 0-59.
При нажатии на любую другую кнопку, кроме выделенных для редактирования, возвращаемся на первый уровень.
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 16 2007, 12:47
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(rezident @ Dec 14 2007, 22:16) *
Разделите логически в программе ввод, вывод и редактирование, а потом совместите их. Т.е. с помощью клавиатуры вы будете редактировать какую-то переменную время/дата. И эту же переменную выводить на экран после каждой модификации полностью. Не нужно будет ломать голову как совместить видимую позицию курсора и редактируемый символ.

Переменную, наверное, необходимо сделать bin2bcd, чтобы редактировать каждую цифру числа. Пока не представляю как это все реализовать.
Цитата(rezident @ Dec 16 2007, 16:16) *
Дык алгоритм-то редактирования простейший.

Не вижу ничего простейшего! Наоборот. Вы что, в мобильном телефоне тоже так время настраиваете? Т.е. подводите курсор на нужный символ, затем нажимаете на кнопку, отличающаяся от "вправо"/"влево". Затем кнопками "вправо"/"влево" редактируете значение времени??? Если это так, то я вам сочувствую...
Если вы обратили внимание на мой код в первом посте, то у меня кнопки обрабатывается в одном уровне оператором switch. Т.е. если не нажата кнопка "вверх"/"вниз", то по умолчанию обрабатывается нажатие цифровых кнопок (если скан-код нажатой клавиши отличается от 0xff-нет нажатия).
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 16 2007, 12:52
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(alux @ Dec 16 2007, 17:39) *
Не вижу ничего простейшего! Наоборот. Вы что, в мобильном телефоне тоже так время настраиваете? Т.е. подводите курсор на нужный символ, затем нажимаете на кнопку, отличающаяся от "вправо"/"влево". Затем кнопками "вправо"/"влево" редактируете значение времени??? Если это так, то я вам сочувствую...

Ну не обратил я внимания, на то что у вас цифровые клавиши имеются. laughing.gif Привык что у нас в приборах их нету. Сути дела это особо не меняет. Перемещение по строке - один уровень. Ввод/редактирование - другой уровень. Редактируется конкретная переменная, связанная с позицией курсора. Вот и все.
Цитата(alux @ Dec 16 2007, 17:47) *
(если скан-код нажатой клавиши отличается от 0xff-нет нажатия).
У меня вообще-то такого не бывает. Т.е. если клавиша не нажата и/или буфер клавиатуры пуст, то возвращается код NULL, который обычно имеет значение 0x00.
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 16 2007, 13:09
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(zltigo @ Dec 16 2007, 15:55) *
Все это оформлено ввиде достаточно универсальной функции редактирования строки работающей с указателем на редактируемую строку-шаблон, правой-левой границей в строке (это _не_ выделитель поля ввода), позицией курсора ( при первом запуске определеляет типа поля подлежащего редактированию) и, естественно, введенным символом.
Все это использовалось и для ввода времени, и других параметров, и списков-таблиц.

А можно взглянуть на эту вашу "универсальную функцию редактирования строки" ?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 16 2007, 13:13
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(alux @ Dec 16 2007, 14:47) *
А можно взглянуть на эту вашу "универсальную функцию редактирования строки"?

А смысл? Какие пробемы? Поменять символ в указанной позиции строки на введенный предварительно проконтролировав текущий? Менять текущую позицию в строке(перемещать курсор) в зависимости от того, какой символ находится под курсором? Там несколько десятков строк, писалась за один проход (сейчас посмотроел - ну в общем на счет часа я сильно погорячился smile.gif ) и не перечитывалась.
Идея изложена подробно - просто пишите с оглядкой на свое существующее окружение.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 16 2007, 13:26
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Если не жалко, выложите код.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 16 2007, 13:41
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(alux @ Dec 16 2007, 15:26) *
Если не жалко, выложите код.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 16 2007, 15:23
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(alux @ Dec 16 2007, 15:47) *
В каких библиотеках?

http://electronix.ru/forum/index.php?showt...mp;#entry338810

Вот читаю и многократно убеждаюсь, что мои подходы очень похожи и перекликаются с rezident и Сергей Борщ. Жаль что тоже выложить не могу. Как указывал уже там процессор другой и АСМ. На Си было бы значительно проще.

По поводу конкретного вопроса - к сожалению обычно используется более менее универсальные способы таких редакторов. Вот поэтому Вы получаете более менее обобщённые ответы. Чтобы конкретно дату редактировать - мне не приходилось.
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 16 2007, 15:51
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(SasaVitebsk @ Dec 16 2007, 19:23) *
к сожалению обычно используется более менее универсальные способы таких редакторов. Вот поэтому Вы получаете более менее обобщённые ответы.

Извините, не понял что этим сказано. Если используется "более менее универсальные способы" , то это по-вашему плохо?
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 16 2007, 18:03
Сообщение #23


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(rezident @ Dec 16 2007, 00:21) *
Дык у каждого процесса своя переменная заданного периода. Простым вычитанием двух беззнаковых переменных определяется закончился требуемый процессу интервал времени или еще нет.

Понятно, только я прикинул, что по количеству используемых флагов, регистров и всего оверхеда ваш вариант получается примерно равноценен моему. Так что, действительно, хозяин-барин wink.gif
Цитата(rezident @ Dec 16 2007, 00:21) *
Это довольно плохие контакты. Я не припомню, чтобы мы применяли кнопки у которых дребезг превышал 10мс. Обычно не более единиц мс.

Это я неточно выразился, имел в виду что через 50-70 мс нажатия взводится флаг.

Цитата(alux @ Dec 14 2007, 18:53) *
Проблема еще в том, что символы имеют переменную ширину. Поэтому после каждого ввода символа необходимо ,наверное, перерисовывать всю строку.

Я как-то упустил главную мысль вопроса smile.gif
Может речь идет о том, что применяется графический LCD с разноширинными шрифтами?
Если это так, то просто примените моноширинный шрифт (типа courier). Тогда не будет нужды перерисовывать строку во время редактирования.
Цитата(alux @ Dec 16 2007, 14:47) *
Переменную, наверное, необходимо сделать bin2bcd, чтобы редактировать каждую цифру числа. Пока не представляю как это все реализовать.

Если же речь не об этом, а о том каким образом редактировать отдельную цифру в бинарной переменной, то тогда ваша мысль правильная:
- бинарное число читается из часов, преобразуется в BCD или ASCII, выводится на дисплей;
- далее в том же виде (BCD или ASCII) редактируется по одной цифре;
- преобразуется обратно в бинарный вид и сохраняется в часах.
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 16 2007, 18:24
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(Baser @ Dec 16 2007, 22:03) *
Может речь идет о том, что применяется графический LCD с разноширинными шрифтами?
Если это так, то просто примените моноширинный шрифт (типа courier). Тогда не будет нужды перерисовывать строку во время редактирования.

В начале я упоминал, что символы имеют разную ширину. Очевидно, что речь идет об графическом индикаторе. В данном случае 128х64. Я специально потратил два дня на создание этих разноширинных шрифтов. Теперь вы мне предлагаете отказаться от этого только потому, что так было бы проще. 07.gif По-моему, это глупо.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 16 2007, 19:40
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(alux @ Dec 16 2007, 22:24) *
В начале я упоминал, что символы имеют разную ширину. Очевидно, что речь идет об графическом индикаторе. В данном случае 128х64. Я специально потратил два дня на создание этих разноширинных шрифтов. Теперь вы мне предлагаете отказаться от этого только потому, что так было бы проще. 07.gif По-моему, это глупо.

Я, в одном изделии, применяю разные шрифты - моноширинные и разноширинные. И, я высказываю своё личное мнение, мне кажется что вы мешаете всё в кучу. У вас должно быть разделение. Уровень работы со шрифтами и уровень вывода, грубо говоря. Уровень работы со шрифтами - это уровень драйвера дисплея, а уровень вывода текста - уровень прикладной. Это значит что на этом уровне не должно иметь значения как выводится информация. То есть не имеет смысла это обсуждать или имеет смысл завести две темы - два вопроса. (Один из вариантов решения проблемы уровня драйвера вы приводите сами (насколько я понял) - вы регенерируете изображение полностью при его изменении. Могу отметить, что это не единственный способ)

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

Цитата
Извините, не понял что этим сказано. Если используется "более менее универсальные способы" , то это по-вашему плохо?


Нет не плохо. Но иногда универсальность вредит удобству использования. У меня, к примеру, в редакторе используется возможность прямого ввода значения и +/-. Но есть и моменты, которые вам, как мне кажется, не подойдут. С другой стороны, у меня вводится признак типа редактируемого значения. Там есть значение int8, int16, real. Можно добавить и date. Если размер свободной флэш позволяет, то можно использовать универсальные способы.

Жаль что я поздно стал работать с СИ. Иначе и вам бы помог и самому бы сейчас было бы полегче. Наработано было бы больше. smile.gif
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 16 2007, 19:48
Сообщение #26


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(alux @ Dec 16 2007, 20:24) *
В начале я упоминал, что символы имеют разную ширину. Очевидно, что речь идет об графическом индикаторе. В данном случае 128х64. Я специально потратил два дня на создание этих разноширинных шрифтов. Теперь вы мне предлагаете отказаться от этого только потому, что так было бы проще. 07.gif По-моему, это глупо.

Извиняюсь за невнимательность laughing.gif
Если вы категорически не хотите отказываться при редактировании параметров от разноширинных шрифтов, то выход у вас только один. Как вам уже ранее советовали, нужно создать шаблон строки (как в оконном интерфейсе), где жестко заданы поля под ввод параметров. Причем размер поля равен максимальному размеру параметра (самый широкий из возможных наборов символов). И выводить это все на LCD не как одну строку, а как набор полей. Иначе при редактировании у вас будут "дышать" размеры всего текста, что на мой взгляд будет выглядеть ужасно sad.gif
Другой вариант - отказаться от геморроя и применить моноширинный шрифт.
Ваш же пример с мобильником - что-то я не видел там в редакторах разноширинных шрифтов smile.gif
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 17 2007, 08:07
Сообщение #27


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(SasaVitebsk @ Dec 16 2007, 23:40) *
То что вам предложили - а именно использование моноширинного фонта - это не из-за проблем с выводом, а рекомендации для получения "красивой" картинки. Я в этом сам убедился. Дело в том, что при применении разноширинных шрифтов цифры времени будут немного "плясать" по понятной причине, что не очень приятно для глаза...

У разноширинного шрифта одно главное преимущество - компактность. Для меня это самое главное. Я вначале начал с моноширинных. Но текcты меню пришлось писать сокращенно, что не есть хорошо. Например, надпись "hello, world!" моноширинным 7х10_bold занимает 13х8=104 пикселя. Почти весь экран.
В то время как разноширинным - 69. Разница - очевидна. Может вы не заметили, я немного изменил задачу вывода времени. Каждая переменная выводится отдельной строкой. Т.е. при вводе чисел, например, года (2007) картинка меняется на один пиксель, в случае ввода '1'или '4'. Что не так "ужасно", как вы описали.
Возможно, при динамическом выводе результатов измерения (до этого пока дело не дошло) меня это станет раздражать. Мне ничего не стоит добавить в фонт '1' пустой столбец, а в '4' убрать последний и сделать таким образом все числа моноширинными (все остальные у меня имеют ширину 5 байт).
А проблему с вводом чисел я решил. Все равно сделал по-своему wink.gif Спасибо всем за ответы. Хотелось бы побольше конкретики... Отдельное спасибо zltiqo за реальную помощь. На полном серьезе. Он понял меня с первого раза. Есть еще немало вопросов. Но об этом позже...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 17 2007, 16:50
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Вы можете добавить ещё один фонт состоящий только из одних цифр. Такой фонт займёт мало места.
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 18 2007, 19:41
Сообщение #29


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



При выводе на экран строки, например шрифтом 7х10, затирается нижестоящая строка. Оно и понятно, фонт имеет высоту 10, поэтому отправляется по два байта на столбец. Второй байт сдвигается вправо на 6. Поэтому получается пустая полоса под вводимой строкой высотой 6 пикселей. Как решить эту проблему? Перед вводом второго байта читать содержимое экрана, накладывать маску и снова записывать? Геморойно как-то. Делать полную регенерацию экрана? Или есть другие варианты? Кстати, при навигации по пунктам меню немного раздражает обновление экрана в течении секунды. Стоит Атмега32L, 7.3728МГц. У меня только два варианта: перед записью сравнивать с содержимым экрана, и если равно, то не писать. Т.е. писать только измененные строки. Второй вариант - заменить контроллер на Атмега324, 20МГц. Шустрее будет почти в 3 раза? Кстати, сегодня получил подарок в виде посылки бесплатных образцов Атмега324(10шт) и АТ90USB1287(10шт) от св.Николая wink.gif !!! Кстати, всех с наступающим НГ! santa2.gif
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 18 2007, 20:20
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



А какой у вас дисплей/контроллер?
Go to the top of the page
 
+Quote Post
alux
сообщение Dec 18 2007, 21:26
Сообщение #31


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



MT12864J ks0108

Добавлено

Простите за тупой вопрос. Как в переменной обнулить переменное число бит? Допустим, надо обнулить 6 мл. бит. Тогда просто делаем логическое И с 0хс0. А если число бит, которые необходимо обнулить, величина переменная? Первое, что пришло на ум, сдвинуть вправо на Х-бит. Затем влево на Х-бит. А можно ли одним движением это сделать? Это все к тому, что необходимо перед выводом символа на экран складывать с считанным байтом. А высота символов может быть разная.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 19 2007, 15:50
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Примерный смысл дойдёт из конструкции.
Код
maska =0x3;
if((X & 2)==0)
{
   maska = 0x30;
   ColorX <<= 4;
   ch <<= 4;
}
if((X & 1)==0)
{
   maska <<=2;
   ColorX <<=2;
   ch <<=2;
}


Формируется сразу и маска и сдвиг.
Вы, как я понял на границу выравниваетесь. То есть у вас повреждения могут быть внизу. А у меня текст или картинка выводится с любой точки. У меня посложнее - есть градации яркости, но принцип понятен.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 19 2007, 19:21
Сообщение #33


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(alux @ Dec 18 2007, 23:26) *
А если число бит, которые необходимо обнулить, величина переменная?
Если контроллер имеет аппаратную поддержку сдвигов, то можно так: value &= ~ ( (1 << n) - 1); (n - число маскируемых бит). Если не имеет - то массив констант, в котором хранятся маски.
Код
uint8_t const Mask[] = { 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00 };
    value &= Mask[n];


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


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


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