cembeddedstm32

Generate a binary pattern that shifts the bit to right


Here is the pattern I have been trying to generate for a 8x8 matrix display such that each led being lit represents a particular count:

00000001
00000010
00000100
00001000
00010000
00100000
01000000
10000000
10000001
10000010
10000100
10001000
10010000
10100000
11000000
11000001   
...

and so on..... until all the bits become 1.

I was able to shift the the bits from right to left, such that 0x01 becomes 0x80, but how do I hold the MSB in its place and start shifting a new bit from LSB(from right side) as described above?

void MAX7219_SendData(uint8_t address, uint8_t data) {
    uint8_t txData[2] = {address, data};
    MAX7219_CS_Low();
    HAL_SPI_Transmit(&MAX7219_SPI_INSTANCE, txData, 2, HAL_MAX_DELAY);
    MAX7219_CS_High();
}

I use the above function to talk MAX7219 IC via SPI.

I am using MAX7219 matrix display to display a pattern. The MAX7219 contains 8 registers that control eight rows of the display( 8x8 display). For example, if I send 00000001 along with the register address as a 16bit word, it would lit up the top - right LED.So, if I send a binary sequence as shown above, it would like as if light is passing through all the LED’s. Once top row is filled, same should start in the next row and so on… In essence, the matrix will show whatever is put in its registers( each of 8 bits). The refresh frequency is around 500hz as mentioned in the data sheet if it is something that can be helpful.


Solution

  • You can use another variable (val_base in the code below), to hold the base pattern on which you will apply the shifts of the current bit.

    In the code below I used 2 nested loops: one for iterating over the groups of patterns (in each group specific bits on the left are 1), and one for shifting the current bit.

    Note that the number of iterations in the inner loop depends on the outer loop (because every time we advance to the next group, less shifts should be applied).

    #include <stdio.h>
    #include <stdint.h>
    
    
    int main() {
        uint8_t val_base = 0;
        for (int iGroup = 0; iGroup < 8; ++iGroup) {  // iterate over the 8 groups of patterns
            for (int iShift = 0; iShift < (8-iGroup); ++iShift) { // iterate on the patterns in each group
                uint8_t val = (1 << iShift) + val_base;
                printf("%08B\n", val);
            }
            val_base |= (1 << (8 - iGroup - 1));    // for next iteration
        }
    }
    

    Output:

    00000001
    00000010
    00000100
    00001000
    00010000
    
    ...
    
    11111010
    11111100
    11111101
    11111110
    11111111
    

    Live demo

    Note:
    In production code the most efficient thing you can do is probably to create a hard-coded lookup table with all the patterns.
    You can still use the code above to generate this lookup table easily.