Можете ли вы помочь мне сделать этот алгоритм Сдвиг строки вправо или влево

Я работаю над проектом, реализующим часы с использованием PIC18, LCD и т. д., и я использую mikroC для реализации этого проекта.

Однако я плохо разбираюсь в C и застрял на определенном этапе. В часах есть меню с несколькими опциями, которые позволят пользователю установить время, будильники, звук будильника и т. д. В меню есть следующее:

1. Set Time
2. Add Alarm
3. Select Alarm
4. Add New Tone
5. Select Tone
6. EXIT

Часы имеют 3 кнопки: OK, RIGHT и LEFT. Когда часы включаются, по умолчанию на ЖК-дисплее отображается Set Time. Я хочу добавить функцию, когда я нажимаю кнопку RIGHT, она должна показывать Add Alarm, но постепенно, а не напрямую. У меня есть 6 пунктов в меню, поэтому я должен сделать это постепенно движением 12 раз (6 вправо и 6 влево). Я пробовал это следующим образом:

 Lcd_Out(2, 2, "   set Time   ");
 Delay_ms(50);
 Lcd_Out(2, 2, "  set Time    ");
 Delay_ms(50);
 Lcd_Out(2, 2, " set Time     ");
 Delay_ms(50);
 Lcd_Out(2, 2, " et Time      ");
 Delay_ms(50);
 Lcd_Out(2, 2, " t Time       ");
 Delay_ms(50);
 Lcd_Out(2, 2, " Time         ");
 Delay_ms(50);
 Lcd_Out(2, 2, " ime          ");
 Delay_ms(50);
 Lcd_Out(2, 2, " me           ");
 Delay_ms(50);
 Lcd_Out(2, 2, " e            ");
 Delay_ms(50);
 Lcd_Out(2, 2, "              ");
 Delay_ms(50);
 Lcd_Out(2, 2, "              ");
 Delay_ms(50);
 Lcd_Out(2, 2, "              ");
 Delay_ms(50);
 Lcd_Out(2, 2, "              ");
 Delay_ms(50);
 Lcd_Out(2, 2, "            A ");
 Delay_ms(50);
 Lcd_Out(2, 2, "           Ad ");
 Delay_ms(50);
 Lcd_Out(2, 2, "          Add ");
 Delay_ms(50);
 Lcd_Out(2, 2, "         Add  ");
 Delay_ms(50);
 Lcd_Out(2, 2, "        Add A ");
 Delay_ms(50);
 Lcd_Out(2, 2, "       Add Al ");
 Delay_ms(50);
 Lcd_Out(2, 2, "      Add Ala ");
 Delay_ms(50);
 Lcd_Out(2, 2, "     Add Alar ");
 Delay_ms(50);
 Lcd_Out(2, 2, "    Add Alarm ");
 Delay_ms(50);
 Lcd_Out(2, 2, "   Add Alarm  ");
 Delay_ms(50);
 Lcd_Out(2, 2, "  Add Alarm   ");

Это было одно движение, а для остальных мне нужен большой код, а оперативная память PIC ограничена. Итак, ребята, вы можете помочь мне решить эту проблему?


person Eng.Fouad    schedule 02.06.2011    source источник
comment
Прежде всего: вам нужен цикл. Это немедленно решает избыточный беспорядок кода, который у вас есть сейчас.   -  person Cody Gray    schedule 02.06.2011
comment
@Cody Gray: проблема в том, как сдвинуть строку вправо или влево?   -  person Eng.Fouad    schedule 02.06.2011
comment
Как я могу начать вознаграждение за этот вопрос?   -  person Eng.Fouad    schedule 02.06.2011
comment
Вам нужно подождать 2 дня.   -  person user7116    schedule 02.06.2011


Ответы (3)


Вот вариант, позволяющий избежать всех memcpy, str*cpy оргий.

#define STRSZ 14

char str[STRZ*2+1] = "   set Time     Add Alarm   ";  /* The buffer must be writable */

for (i = 0; i <= STR_SZ; i++) {            // Loop
  char save_ch = str[i + STRZ];            // Save the character at the end 
  str[i + STRZ] = 0;                       // Terminate the string
  Lcd_Out (2, 2, str + i);                 
  str[i + STRZ] = save_ch;                 // Restore buffer
  Delay_ms (50);
}

РЕДАКТИРОВАТЬ: сдвиг вправо

for (i = STR_SZ; i >= 0; i--) {            // Loop
  char save_ch = str[i + STRZ];            // Save the character at the end 
  str[i + STRZ] = 0;                       // Terminate the string
  Lcd_Out (2, 2, str + i);                 
  str[i + STRZ] = save_ch;                 // Restore buffer
  Delay_ms (50);
}

На очень маленьких устройствах избегание ненужных перемещений памяти может иметь решающее значение.

person Patrick Schlüter    schedule 02.06.2011
comment
Оно работает! действительно спасибо ... не могли бы вы написать другую часть, где она смещается вправо? - person Eng.Fouad; 02.06.2011

Вам нужно что-то вроде этого:

#define STRSZ 14
//           <------------><------------>
char *str = "   set Time     Add Alarm   ";    // Two 14-char strings.
char disp[STRSZ+1];                            // Buffer for holding display string.
for (i = 0; i <= STR_SZ; i++) {                // Starting character to use.
    memcpy (disp, &(str[i]), STR_SZ);          // Copy the relevant bit.
    disp[STR_SZ] = '\0';                       // And null-terminate.
    Lcd_Out (2, 2, disp);                      // Display it then wait.
    Delay_ms (50);
}

Для переключения в другую сторону просто используйте:

for (i = STR_SZ; i >= 0; i--) {
    // blah blah blah
}

Если вы ищете более полный пример, попробуйте:

#define STR_SZ 14
// PreCond: from and to MUST be 14-character strings. EXACTLY!
// Pass in from and to strings and 1 to go left, 0 to go right.

void transition (char *from, char *to, int goLeft) {
    // Space for transition and display strings.
    char str[STR_SZ * 2 + 1];
    char disp[STR_SZ + 1];

    // Transition variables.
    int pos, start, end, incr;

    // Check preconditions.
    if (strlen (from) != STR_SZ) return;
    if (strlen (to) != STR_SZ) return;

    // Different values for each direction.
    if (goLeft) {
        start = 0; end = STR_SZ + 1; incr = 1;
        strcpy (str, from); strcat (str, to);
    } else {
        start = STR_SZ; end = -1; incr = -1;
        strcpy (str, to); strcat (str, from);
    }

    // Do the transitions.
    for (pos = start; pos != end; pos += incr) {
        // Copy string portion to display then delay.
        memcpy (disp, &(str[i]), STR_SZ);
        disp[STR_SZ] = '\0';
        Lcd_Out (2, 2, disp);
        Delay_ms (50);
    }
}

Он не проверен (кроме как в моей голове, что обычно довольно хорошо), так что вы должны считать его отправной точкой.

person paxdiablo    schedule 02.06.2011
comment
Я пробовал это, но не очень хорошо. Что именно делает memcpy? - person Eng.Fouad; 02.06.2011
comment
Копирует память. Этот конкретный скопирует ровно 14 символов, начиная с позиции i из str, где i будет идти от 0 до 14 (сдвиг влево) или от 14 до 0 (сдвиг вправо). Он копирует его в disp, чтобы его можно было отправить на дисплей. - person paxdiablo; 02.06.2011
comment
это просто замена from на to через некоторое время без какого-либо смещения :\ - person Eng.Fouad; 02.06.2011
comment
@Eng: Тогда ваш Lcd_Out не работает так, как рекламируется, или вы неправильно набрали код (в частности, убедитесь, что фигурные скобки указаны правильно). Если ваш исходный код работал, то и этот должен работать, так как все, что он делает, это сворачивает код в цикл. - person paxdiablo; 03.06.2011

Большинство ЖК-дисплеев сами по себе поддерживают прокрутку. Поэтому библиотеки C для ЖК-дисплеев предоставляют функции для прокрутки данных. Я использовал библиотеку PIC18 C, и она предоставляет две функции.

void lcd_scroll_left(char n) прокручивает ЖК-экран влево на n позиций.

void lcd_scroll_right(char n) прокручивает ЖК-экран вправо на n позиций.

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

Библиотека Microchip PIC18 C для ЖК-дисплеев

person farhanhubble    schedule 02.06.2011