English 中文(简体)
Can you help me to do this algorithm "Shifting a String to right or left"
原标题:

I m working on a project implementing a clock using PIC18, LCD, ... etc and I am using mikroC to implement this project.

However, I am not good at C and I am stuck at certain point. The clock has a menu with several options that will enable the user to set time, alarms, alarm sound, etc. The menu has the following:

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

The clock has 3 pushbuttons, OK,RIGHT, and LEFT. When the clock power-on, it will show Set Time on LCD as default. I want to add a feature that when I press RIGHT pushbutton it should show Add Alarm but gradually not directly. I have 6 items in the menu so I have to do this gradually movement 12 times (6 for right and 6 for left). I have tried this as follows:

 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   ");

This was one movement and to do the others I need large code while the RAM of the PIC is limited. So, Can you guys help me solving this issue?

最佳回答

Here a variation avoiding all the memcpy, str*cpy orgy.

#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);
}

EDIT: shift to right

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);
}

On very small devices, avoiding unnecessary memory moves can be crucial

问题回答

You need something like this:

#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] =   ;                       // And null-terminate.
    Lcd_Out (2, 2, disp);                      // Display it then wait.
    Delay_ms (50);
}

For shifting the other way, simply use:

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

If you re looking for a more complete example, try:

#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] =   ;
        Lcd_Out (2, 2, disp);
        Delay_ms (50);
    }
}

It s untested (other than in my head, which is usually pretty good) so you should consider it a starting point.

Most LCDs themselves support scrolling. So C libraries for LCDs provide functions for scrolling data. I have used PIC18 C library and it provides two functions

void lcd_scroll_left(char n) scrolls LCD screen left n positions.

void lcd_scroll_right(char n) scrolls LCD screen right n positions.

You can consult the documentation of the library that you are using for finding the function names you gotta use.

Microchip PIC18 C library for LCDs





相关问题
How to add/merge several Big O s into one

If I have an algorithm which is comprised of (let s say) three sub-algorithms, all with different O() characteristics, e.g.: algorithm A: O(n) algorithm B: O(log(n)) algorithm C: O(n log(n)) How do ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Enumerating All Minimal Directed Cycles Of A Directed Graph

I have a directed graph and my problem is to enumerate all the minimal (cycles that cannot be constructed as the union of other cycles) directed cycles of this graph. This is different from what the ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签