This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

8bit reversal of all the bytes in a string

Hello everybody, Wish you all a very happy new year.

I am facing a problem, I know basically it is a C language problem but I am still not able to catch up the language yet.

I have reversed the data pins of LCD. Now while programming I can reverse the data byte by byte, but the speed of the LCD is quite low.

void LCD_sendstring(unsigned char *strLCD){     // e.g. LCD_sendstring("LCD Tutorial");
    while(*strLCD)                              //till string ends
        LCD_senddata(*strLCD++);                //send characters one by one
}


void LCD_senddata(unsigned char var){           // e.g. LCD_senddata('A');
    LCD_data = reverse(var);
    LCD_rs = 1;                 //Selected data register
    LCD_rw = 0;                 //We are writing
    LCD_en = 1;                 //Enable H->
    LCD_en = 0;
    LCD_busy1();                //Wait for LCD to process the command
}

As the above code reverses each character before sending to LCD, the characters appears slowly on LCD. So I am trying to reverse the whole string before sending to the LCD (LCD_senddata). I have tried the following codes but its not working.


void LCD_sendstring(unsigned char *strLCD){     // e.g. LCD_sendstring("LCD Tutorial");
     reverse_string(strLCD);
        *strLCD =  reverse_string1(strLCD);

        while(*strLCD)                          //till string ends
    LCD_senddata(*strLCD++);                    //send characters one by one
}


void LCD_senddata(unsigned char var){           // e.g. LCD_senddata('A');

    LCD_data = var;
    LCD_rs = 1;                 //Selected data register
    LCD_rw = 0;                 //We are writing
    LCD_en = 1;                 //Enable H->
    LCD_en = 0;
    LCD_busy1();                //Wait for LCD to process the command
}


void reverse_string(char *str){ //junk result
        while(*str){
//              *str=reverse3(*str);
                *str='B';

                str++;
        }
        str = &str;
}



char *reverse_string1(char *str){       //blank result
    int len = strlen(str);
        char *newstr = malloc(len+1);

        while(*str){                    //till string ends
//              *newstr++ = reverse(*str++);
//              *newstr++ = *str++;
                *newstr++ = 'B';
        }
        *newstr = '\0';
    return newstr;
}

In reverse_string I get junk result whereas in reverse_string1 I am getting blank display. Please Help!!!

Parents Reply Children
  • Sir, I have removed the following statement from reverse_string() function

    str = &str;
    

    It seems that there is no effect of using the function. I have to keep reverse() function in LCD_senddata. In reverse_string function even if I change the data to anything.

    void LCD_senddata(unsigned char var){           // e.g. LCD_senddata('A');
        LCD_data = reverse(var); //Function set: 2 Line, 8-bit, 5x7 dots
    //    LCD_data = var; //Function set: 2 Line, 8-bit, 5x7 dots
        LCD_rs = 1; //Selected data register
        LCD_rw = 0; //We are writing
        LCD_en = 1; //Enable H->
        LCD_en = 0;
        LCD_busy1(); //Wait for LCD to process the command
    }
    
    
    
    void LCD_sendstring(unsigned char *strLCD){     // e.g. LCD_sendstring("LCD Tutorial");
    
            reverse_string(strLCD);
        while(*strLCD) //till string ends
        LCD_senddata(*strLCD++); //send characters one by one
    }
    
    
    
    void reverse_string(char *str){ //junk result
            while(*str){
            *str=reverse(*str);
    //              *str='B';
                    str++;
        }
    }
    
    unsigned char reverse(unsigned char b) {
       b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
       b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
       b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
       return b;
    }
    

  • Note that in-place conversion of a string is ok when the input string data is stored in a variable buffer.

    In the case you do

    LCD_sendstring("LCD Tutorial");
    


    then you do not "own" the buffer space where the characters are stored. Most compilers for different architectures will store the string data in write-protected memory and make the program crash if the program tries to make changes. The 8051 doesn't have the same kind of memory access exceptions, but if the string is stored in the code space it is not possible to change it.

    Think about what would happen if you did (and the produced code did support modification of the constant strings):

    for (;;) {
        LCD_sendstring("Hello");
        delay_ms(500);
        LCD_sendstring("world!");
        delay_ms(500);
    }
    


    If the compiler would allow it, and you do in-place bit reversal, then the first iteration would print correctly after having performed one bit reversal. The second iteration would print garbage because you would now have made two bit reversals after each other and so returned back to the original text that expected that the LCD was correctly connected.

    That's why I recommended you to consider a statically allocated, fixed size, buffer to store the converted text string. Just make sure that you make the buffer big enough, or split your output into multiple LCD prints in case the input string is longer than what may fit in your buffer. This would make your print function compatible with both variable data and with constant strings since it doesn't then try to modify the input data.

  • My basic problem is solved!!!

    In LCD_busy function instead of using delay, I used D7 bit to check busy status. Now the LCD operation is quite fast even if the bytes are reversed one by one. Thanks for giving your time.

    One more question please. If I just added two statements in the LCD_sendstring function, boxes appear on the LCD. I declared a string & used strcpy to copy original string to it.

    void LCD_sendstring(unsigned char *strLCD){     // e.g. LCD_sendstring("LCD Tutorial");
            unsigned char *reversed_str;
    //      strcpy(reversed_str, strLCD);
    //      reverse_string(strLCD);
        while(*strLCD)                              //till string ends
        LCD_senddata(*strLCD++);    //send characters one by one
    }
    

    If I comment out the strcpy line it works ok.

  • Note that your new variable is a pointer to characters.

    So you have allocated space to store one memory addrss.
    You haven't allocated space to store any characters.
    So you can't use your pointer as destination for any strcpy().

    Maybe time to pick up a book about the C language, and read up on the similarity (and differences) between pointers and arrays - and that you need memory for the full array content if you want to copy strings. When you manipulate the characters of a string, it's important that you understand exactly where the actual characters are stored.

  • Thanks, it is almost clear to me now.

    One more question pleeeease. We increment pointers (like *strLCD++) in while loop. If again we have to use it in another loop how should we reset the pointer to start of the string?

  • Just store a copy of the original pointer value:

    unsigned char *start = strLCD;
    
    while (*strLCD) {
        funny(*strLCD++);
    }
    
    strLCD = start;
    while (*strLCD) {
        funnier(*strLCD++);
    }