Можете ли вы помочь мне сделать этот алгоритм "Сдвиг строки вправо или влево"
Я работаю над проектом, реализующим часы с использованием 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 ограничено. Итак, вы, ребята, можете помочь мне решить эту проблему?
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);
}
На очень маленьких устройствах исключение ненужных перемещений памяти может иметь решающее значение
Вам нужно что-то вроде этого:
#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);
}
}
Это не проверено (кроме как в моей голове, что обычно довольно хорошо), так что вы должны рассматривать это как отправную точку.
Большинство ЖК-дисплеев поддерживают прокрутку. Таким образом, библиотеки C для LCD предоставляют функции для прокрутки данных. Я использовал библиотеку PIC18 C, и она обеспечивает две функции
void lcd_scroll_left(char n) прокручивает ЖК-экран влево на n позиций.
void lcd_scroll_right (char n) прокручивает ЖК-экран вправо на n позиций.
Вы можете обратиться к документации библиотеки, которую вы используете для поиска имен функций, которые вы должны использовать.