我正在开发一个使用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
。当时钟开机时,它将在LCD上显示Set Time
作为默认值。我想添加一项功能,当我按下RIGHT
按钮时,它应显示Add Alarm
但不会直接显示 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 ");
。我在菜单中有6个项目,所以我必须逐步进行12次运动(右侧6个,左侧6个)。我试过这个如下:
{{1}}
这是一个动作,为了完成其他动作,我需要大量代码,而PIC的RAM是有限的。那么,你们能帮助我解决这个问题吗?
答案 0 :(得分:6)
你需要这样的东西:
#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);
}
}
这是未经测试的(除了在我脑海中,通常相当不错)所以你应该把它视为一个起点。
答案 1 :(得分: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);
}
在非常小的设备上,避免不必要的内存移动至关重要
答案 2 :(得分:2)
大多数LCD本身都支持滚动。因此,用于LCD的C库提供滚动数据的功能。我使用过PIC18 C库,它提供了两个函数
void lcd_scroll_left(char n)将LCD屏幕向左滚动n个位置。
void lcd_scroll_right(char n)将LCD屏幕向右滚动。
您可以查阅您正在使用的库的文档,以查找您必须使用的函数名称。