scrolling text message - embedded C

Discussion in 'Programmer's Corner' started by takao21203, Feb 10, 2015.

  1. takao21203

    Thread Starter AAC Fanatic!

    Apr 28, 2012
    I made various LED matrix scrolling message circuits.

    Now I am trying to simplify the algorithm, and shorten the source code.

    Here's the old version:

    Code (Text):
    2.  if(scrollstep_ctr>50)
    3.         {  scrollstep_ctr=0;
    5.             for(i=0;i<scroll_mem_size;i++)display_data[i]=0;
    6.             bitno=0;
    7.             ram_addr=(scroll_dsp_size-1)+ram_ptr;
    9.             bp_bit=0x1;
    10.             for(i=0;i<scroll_dsp_size;i++)
    11.             {
    12.                 led_matrix_off();
    13.                 ram_set_addr(ram_addr--,3);buffer=load_ram(0);
    14.                 led_matrix_on();
    15.                 binmsk=1;
    16.                 bp_byte=0;
    17.                 if(i>4)bp_byte=1;
    18.                 if(i>9)bp_byte=2;
    19.                 for(i3=0;i3<5;i3++)
    20.                 {
    21.                     if(buffer&binmsk)display_data[bp_byte]|=bp_bit;
    22.                     bitno++;
    23.                     binmsk<<=1;
    24.                     bp_byte+=3;
    25.                 }
    26.                 if(bp_bit<0x10)bp_bit<<=1;else bp_bit=0x1;
    27.             }
    28.             ram_ptr++;if(ram_ptr>(scroll_size-(scroll_dsp_size+2)))ram_ptr=0;
    29.         }
    The problems:

    -The font data is stored in a space saving format. Since the height is 5 lines only, the 5 lower bits of a byte are used for font data, and the 3 high bits for the character width.

    -The characters have different width.

    -The LED matrix can have different sizes, not a multiple of 8

    -The data from the font table must be copied in a way bit 1 from vertical line 1 -> display horizontal line 0, pos 0, bit 7; bit 2 -> display horizontal line 1, pos 0, bit 7
    then the next vertical line is bit 6 and so on.
    After each 8 bits on the matrix, +1 to pos. as offset

    And here's the new code

    Code (Text):
    2. void copy_scroll(uint offs,uint bmp_offs, uchar mask_min)
    3. {uchar* ram_ptr;uchar* dsp_ptr;uchar i,i2;
    4.  ram_ptr=bitmap+bmp_offs;dsp_ptr=display_ptr+offs;
    5.  for(i=0x80;(i>0)&&(i>mask_min);i>>=1);
    6.  {for(i2=1;i2<0x20;i2<<=1)
    7.   {if((*ram_ptr++)&i2)*dsp_ptr|=i;else *dsp_ptr&=0xff-i;
    8.    dsp_ptr+=display_bytes_width;
    9. }}}
    11. void copy_scroll_10(){copy_scroll(0,0,0);copy_scroll(1,8,0x20);}
    I havent tested it yet, one of my questions is shifting in for loops. possible in this way?
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    Yes you can put most any legal C statement inside a loop. So your increment can be a shift.
  3. takao21203

    Thread Starter AAC Fanatic!

    Apr 28, 2012
    I didnt realize that previously.

    The 18F assembler version just to do the matrix multiplex was stretching over pages and other people werent able to understand it (using some PIC specific instructions and it was weird too, swapping two sets of the two FSR registers).

    I programmed an ASM version of a scrolling message (same system) once, but that was at the time when I stopped with it. I havent even looked at this source again.

    2) I should clear the memory probably as all of it needs to be rewritten, and the "1" are much less than the "0".
    It saves me the pointer dereferencing 2x in the inner loop, but source size will increase by at least two lines.

    But now I want to try asynchronous refresh / updating, it could happen in the middle of the copying process. I will try both variants. At high frequency its maybe not much visible.

    3) There is something I wonder about. When I do this
    Code (Text):
    1. *dsp_ptr|=i;
    the compiler generates code for dereferencing, then performs the arithmetic, and then writes back the result at the address of the memory reference?

    I'm almost sure it does that, I used
    Code (Text):
    1. *str="A";
    for instance.

    Its different to assembler one Mnemonic after the other, you can spell all kinds of legally possible combinations, and the compiler generates code in terms of operator precedency, and by verifying if it makes sense.
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    I do not see why you question dsp_ptr in #3. The statement should do as you say.

    *str="A"; looks odd to me as "A" is a two byte entity to handle the trailing zero to the string "A". Thus str needs to be a two byte value unless it gets truncated to a byte somehow. (C first assumes the programmer knows what is wanted, even if it is something weird.)

    It may be clearer if you state how str is defined.
  5. takao21203

    Thread Starter AAC Fanatic!

    Apr 28, 2012
    In Embedded C its accepted for char immediate assignments. Sure, for Windows C++ C subset, it isnt. But for different reasons. Zero termination isnt mandatory? Under Windows its a Unicode immediate expression result.

    Anyway, I just wrote it for an example.

    Sure somehow, intuitively I dont question it, I learned it works that way. But I try also to understand what is happening on a lower level, how C compilers work in general, and, here's the point looking at this, find ways to improve source codes.

    I have taken the code to copy the small character bitmaps into one large bitmap, its ugly, written for 16F5x, when the compiler was still very buggy, and it even uses goto, to save some 100 words. But it works well.

    The other function, to copy from the message bitmap to display memory, well you see above, it looks too complicated, and whats the point for me, its too difficult to adapt it /reuse it for different kinds of LED matrix.

    I havent tested the new code yet but I think it roughly does the same thing.
  6. takao21203

    Thread Starter AAC Fanatic!

    Apr 28, 2012
    well it needs to be
    Code (Text):
    1. *str='A';
    of course. I just tested, it only gives a warning, but the disassembly isnt making sense, and 0xFF will be assigned.