16*16 dot matrix, two expanded to 16*32 dot matrix
Anode:

The rest of the cathode remains the same: (A0-A7 is the anode, B0-B7 is the cathode)
Four cascade diagrams: (16*16 dot matrix)

It is wasteful to directly use 16+16 IO ports to control. Chips (MAX7219, 74HC595, etc.) can be used to drive, and they can all be cascaded, which can save a lot of IO ports.
This article uses 74HC595 cascade:

1. Chinese character modulus software:



mode changed to C51

remove these two brackets
Click OK


Copy the modulus at the bottom.
2. Digital modulo
Click directly and take the modulo manually.
1. Open the modulo software

2. Create a new image, change the width and height to 8*8

3. Parameter settings, other options.

4. Configure as shown below

5. Click on the image number to be taken directly on the image

6. After drawing, click the modulo mode, c51 modulo.

7. The figure below is the modulo data.


This code has been tested and can be displayed.
HC595.h
#ifndef HC595
#define HC595
#define HC595_Port_RCC RCC_APB2Periph_GPIOB //clock
#define HC595_PIN GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12 //Pin
#define HC595_PORT GPIOB //port
#define HC595_SH PBout(12) //Latch register
#define HC595_ST PBout(11) //Shift Register
#define HC595_DS PBout(10) //data input
/* Variable definitions */
//uchar duan[][32];
/*Function declaration */
void HC595_Init(void);
void DZ_Chinese_Static_Display(void); // statically display two Chinese characters
void DZ_Chinese_Dynamic_Display(void); // scroll display
void DZ_Num_Static_Display(void);
void DZ_Num_Dynamic_Display(void);
#endif
HC595.c
#include "All.h"
uchar DZ16x32Ram[32][2]; // Open up cache space, two bytes per column,
// Two columns, one column, two rows, one row
// row is 1, column is 0
uchar column1[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf,0x7f,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
}; //first row
uchar column2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
}; //The second column
uchar DZ_16x16Chinese[][32]= {
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x00,0x24,0x10,0x24,0x12,0x24,0x21, //I
0x7F,0xFE,0xC4,0x40,0x44,0x84,0x04,0x08,
0xFF,0x90,0x04,0x60,0x44,0x58,0x35,0x86,
0x04,0x01,0x0C,0x07,0x04,0x00,0x00,0x00,
0x02,0x00,0x0D,0x00,0x49,0x02,0x69,0x0C, //Love
0x59,0x31,0x49,0xC1,0x4F,0x62,0x79,0x54,
0x49,0x48,0x89,0x54,0x99,0x64,0xA9,0x42,
0x89,0x03,0x0A,0x02,0x0C,0x00,0x00,0x00,
0x02,0x00,0x04,0x00,0x1F,0xFF,0xE0,0x00, //you
0x02,0x00,0x04,0x10,0x18,0x20,0xF0,0xC2,
0x10,0x01,0x13,0xFE,0x10,0x00,0x10,0x80,
0x14,0x60,0x18,0x30,0x00,0x00,0x00,0x00,
0x3F,0xF0,0x20,0x20,0x7F,0xF0,0x20,0x00, //what
0x7F,0xFF,0x42,0x10,0x4D,0x88,0x70,0x70,
0x00,0x00,0x47,0xF0,0x44,0x20,0x4F,0xF2,
0x44,0x01,0xFF,0xFF,0x40,0x00,0x00,0x00
};
uchar DZ_8x8Num[][8] = {
0x00,0x7E,0x81,0x81,0x81,0x81,0x7E,0x00, /* 0 */
0x00,0x01,0x01,0x41,0xFF,0x01,0x01,0x00, /* 1 */
0x00,0x41,0x83,0x85,0x89,0x91,0x61,0x00, /* 2 */
0x00,0x42,0x81,0x81,0x99,0xA5,0x42,0x00,/* 3 */
0x00,0x0C,0x14,0x24,0x44,0xFF,0x04,0x00,/* 4 */
0x00,0xE2,0xA1,0xA1,0xA1,0xA1,0xBE,0x00, /* 5 */
0x00,0x7E,0x91,0x91,0x91,0x91,0x5E,0x00, /* 6 */
0x00,0x80,0x80,0x80,0x9F,0xA0,0xC0,0x00, /* 7 */
0x00,0x7E,0x91,0x91,0x91,0x91,0x7E,0x00, /* 8 */
0x00,0x72,0x91,0x91,0x91,0x91,0x7E,0x00, /* 9 */
};
/*4*8 numbers actually display 3*7 but they are too crowded next to each other, so the blank line in the middle becomes 5*/
uchar DZ_4x8Num[][5] = {
0x3E,0x41,0x41,0x3E,0x00, /* 0 */
0x00,0x00,0x7F,0x00,0x00, /* 1 */
0x4F,0x49,0x49,0x79,0x00, /* 2 */
0x49,0x49,0x49,0x7F,0x00, /* 3 */
0x78,0x08,0x08,0x7F,0x00, /* 4 */
0x79,0x49,0x49,0x4F, 0x00, /* 5 */
0x7F,0x49,0x49,0x4F, 0x00, /* 6 */
0x40,0x40,0x40,0x7F,0x00, /* 7 */
0x7F,0x49,0x49,0x7F,0x00, /* 8 */
0x79,0x49,0x49,0x7F, 0x00, /* 9 */
0x00,0x36,0x36,0x00,0x00, /*:10*/
0x00,0x00,0x00,0x00,0x00,/*Do not display 11*/
0x08,0x08,0x08,0x08,0x00,/*-12*/
};
uchar DZ_4x8Num_Buffer[40] ; // Dynamic display of digital buffer
/*3*8 numbers actually display 3*5 but they are too crowded next to each other, so the blank line in the middle becomes 5*/
uchar DZ_3x8Num[][4] = {
0x1F,0x11,0x1F,0x00,/* 0 */
0x00,0x1F,0x00,0x00,/* 1 */
0x17,0x15,0x1D,0x00, /* 2 */
0x15,0x15,0x1F, 0x00, /* 3 */
0x1C,0x04,0x1F,0x00,/* 4 */
0x1D,0x15,0x17, 0x00,/* 5 */
0x1F,0x15,0x17,0x00,/* 6 */
0x10,0x10,0x1F, 0x00,/* 7 */
0x1F,0x15,0x1F,0x00,/* 8 */
0x1D,0x15,0x1F,0x00,/* 9 */
0x00,0x36,0x00,0x00,0x00, /*:*/
};
/* hc595 pin initialization */
void HC595_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(HC595_Port_RCC,ENABLE);//System clock enable
GPIO_InitStructure.GPIO_Pin = HC595_PIN; //Define pin
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//Pin output mode
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//Pin speed
GPIO_Init(HC595_PORT,&GPIO_InitStructure); //Initialize the port
}
//Hc595 transfer data
void Hc595_Send_Byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
HC595_SH=0;//Shift
if(dat&0x80) //
HC595_DS= 1;
else
HC595_DS =0;
dat<<=1;
delay_us(2);
HC595_SH=1;//Shift clock rising edge copy
delay_us(2);
}
}
/* Display two 16*16 characters
one is the number to be displayed in the first 16*16 dot matrix
two is the number to be displayed in the second 16*16 dot matrix
*/
void DZ_16x16_Char(void)
{
uchar i;
for(i = 0; i< 16; i++)
{
/* The second 16*16 dot matrix*/
// 16*16 dot matrix
/* One line at a time, 2 bytes, control bit selection*/
Hc595_Send_Byte(column2[i]); // A second column cathode
Hc595_Send_Byte(column1[i]); // first row
/* Transmit one column at a time, 2 bytes, and display a column of 16 dots*/
Hc595_Send_Byte(DZ16x32Ram[i+16][1]); // second row // display one column of data at a time
Hc595_Send_Byte(DZ16x32Ram[i+16][0]); // first row
/* The first 16*16 dot matrix */
// 16*16 dot matrix
/* One line at a time, 2 bytes, control bit selection*/
Hc595_Send_Byte(column2[i]); // A second column cathode
Hc595_Send_Byte(column1[i]); // first row
/* Transmit one column at a time, 2 bytes, and display a column of 16 dots*/
Hc595_Send_Byte(DZ16x32Ram[i][1]); // second line
Hc595_Send_Byte(DZ16x32Ram[i][0]); // first row
HC595_ST=1; // latch data
delay_us(2);
HC595_ST=0;
}
}
/* Dot matrix static display function*/
void DZ_Chinese_Static_Display(void)
{
uchar j,k,m;
for (m = 0; m < 20; m++)
{
j = 0;
for (k = 0; k < 16; k++) //Display a 16*16 dot matrix
{
DZ16x32Ram[k][1] = DZ_16x16Chinese[0][j+1]; // must be odd
DZ16x32Ram[k][0] = DZ_16x16Chinese[0][j]; // must be an even number
DZ16x32Ram[k+16][1] = DZ_16x16Chinese[1][j+1];
DZ16x32Ram[k+16][0] = DZ_16x16Chinese[1][j];
j+=2;
}
DZ_16x16_Char();
}
}
/* Dot matrix dynamic display function */
void DZ_Chinese_Dynamic_Display(void)
{
uchar i,k,j=0,m;
/* 64 is to display two screens at a time*/
for (i =0 ;i<64;i++) // Cycle display times
{
for(m = 0;m<20;m++) // The speed of scrolling
{
j = 0; // Display one group at a time, clear
for (k = 0; k < 16; k++) //Display a 16*16 dot matrix
{
/*(j+1+2*i): j+1 is guaranteed to be an odd number 2*i, to ensure that two changes each time, or an odd number
(64*2): 64 means the number of times a word needs to be changed, 2 means to scroll to display 4 words on 2 screens*/
DZ16x32Ram[k][1] = DZ_16x16Chinese[0][(j+1+2*i)%(64*2)]; // must be odd
DZ16x32Ram[k][0] = DZ_16x16Chinese[0][(j+2*i)%(64*2)]; // must be an even number
DZ16x32Ram[k+16][1] = DZ_16x16Chinese[0][(32+j+1+2*i)%(64*2)];
DZ16x32Ram[k+16][0] = DZ_16x16Chinese[0][(32+j+2*i)%(64*2)];
j+=2;
}
DZ_16x16_Char();
}
}
}
void DZ_Num_Static_Display(void)
{
uchar j,k,m;
// for (m = 0; m <40; m++) //Control the frequency of refresh
// {
j = 0; // redisplay every time
for (k = 0; k < 5; k++) //Display a 16*16 dot matrix
{
/* The first 8 control the left, the last 8 control the right */
DZ16x32Ram[k][0] = DZ_4x8Num[DS1302_Time_Buffer[4]/16][j]; // up 1
DZ16x32Ram[k+5][0] = DZ_4x8Num[DS1302_Time_Buffer[4]%16][j]; // up 2
DZ16x32Ram[k+10][0] = DZ_4x8Num[10][j]; // up 3
DZ16x32Ram[k+15][0] = DZ_4x8Num[DS1302_Time_Buffer[3]/16][j]; // up 4
DZ16x32Ram[k][1] = DZ_4x8Num[DS1302_Time_Buffer[2]/16][j]; // next 1
DZ16x32Ram[k+5][1] = DZ_4x8Num[DS1302_Time_Buffer[2]%16][j]; // next 2
if((k+9) < 12)
DZ16x32Ram[k+9][1] = DZ_4x8Num[10][j]; // down 3
DZ16x32Ram[k+13][1] = DZ_4x8Num[DS1302_Time_Buffer[1]/16][j]; // down 4
// The second screen
DZ16x32Ram[k+20][0] = DZ_4x8Num[DS1302_Time_Buffer[3]%16][j]; // up 1
DZ16x32Ram[k+25][0] = DZ_4x8Num[11][j]; // up 2
DZ16x32Ram[k+30][0] = DZ_4x8Num[11][j]; // up 3
DZ16x32Ram[k+32][0] = DZ_4x8Num[11][j]; // up 4
DZ16x32Ram[k+18][1] = DZ_4x8Num[DS1302_Time_Buffer[1]%16][j]; // next 1
//DZ16x32Ram[k+22][1] = DZ_4x8Num[10][j]; // next 2
if((k+24) < 28)
DZ16x32Ram[k+24][1] = DZ_3x8Num[DS1302_Time_Buffer[0]/16][j]; // down 3
// if((k+22) < 25)
DZ16x32Ram[k+28][1] = DZ_3x8Num[DS1302_Time_Buffer[0]%16][j]; // down 4
j+=1;
}
DZ_16x16_Char();
// }
}
/*Dynamic cycle display date*/
void DZ_Num_Dynamic_Display(void)
{
uchar j=0,k,m=0,i=0;
//u1_printf("%x ", DZ_4x8Num[DS1302_Time_Buffer[4]/16][k] );
for (k = 0; k < 5; k++) //Display a 16*16 dot matrix
{
DZ_4x8Num_Buffer[k] = DZ_4x8Num[DS1302_Time_Buffer[4]/16][k];
DZ_4x8Num_Buffer[k+5] = DZ_4x8Num[DS1302_Time_Buffer[4]%16][k];
DZ_4x8Num_Buffer[k+10] = DZ_4x8Num[12][k];
DZ_4x8Num_Buffer[k+15] = DZ_4x8Num[DS1302_Time_Buffer[3]/16][k]; // up 1
DZ_4x8Num_Buffer[k+20] = DZ_4x8Num[DS1302_Time_Buffer[3]%16][k];
if((k+26) < 30)
DZ_4x8Num_Buffer[k+26] = DZ_3x8Num[DS1302_Time_Buffer[5]%16][k];
//DZ_4x8Num_Buffer[k+30] = DZ_4x8Num[11][k];
// DZ_4x8Num_Buffer[k+32] = DZ_4x8Num[11][k];
}
for (i = 0 ;i< 32; i++) // Cycles
{
DS1302_Read_Time(); // Read the time each time, the time will be displayed continuously
// u1_printf("%x\r\n", DS1302_Time_Buffer[2]);
for ( m= 0; m < 20; m++) //Control the frequency of refresh
{
j = 0; // redisplay every time
for (k = 0; k < 5; k++) //Display a 16*16 dot matrix
{
/* The first 8 control the left, the last 8 control the right */
DZ16x32Ram[k][0] = DZ_4x8Num_Buffer[(k+i)%32]; // up 1
DZ16x32Ram[k+5][0] = DZ_4x8Num_Buffer[(5+k+i)%32]; // up 2
DZ16x32Ram[k+10][0] = DZ_4x8Num_Buffer[(10+k+i)%32] ; // up 3
DZ16x32Ram[k+15][0] = DZ_4x8Num_Buffer[(15+k+i)%32]; // up 4
DZ16x32Ram[k][1] = DZ_4x8Num[DS1302_Time_Buffer[2]/16][j]; // next 1
DZ16x32Ram[k+5][1] = DZ_4x8Num[DS1302_Time_Buffer[2]%16][j]; // next 2
if((k+9) < 13)
DZ16x32Ram[k+9][1] = DZ_4x8Num[10][j]; // down 3
DZ16x32Ram[k+13][1] = DZ_4x8Num[DS1302_Time_Buffer[1]/16][j]; // down 4
//u1_printf("%x\r\n",DZ16x32Ram[k+13][1]);
// // The second screen
DZ16x32Ram[k+20][0] = DZ_4x8Num_Buffer[(20+k+i)%32]; // up 1
DZ16x32Ram[k+25][0] = DZ_4x8Num_Buffer[(25+k+i)%32]; // up 2
if((k+30) < 32)
DZ16x32Ram[k+30][0] = DZ_4x8Num_Buffer[(30+k+i)%32]; // up 3
// DZ16x32Ram[k+32][0] = DZ_4x8Num_Buffer[32+k]; // up 4
DZ16x32Ram[k+18][1] = DZ_4x8Num[DS1302_Time_Buffer[1]%16][j]; // next 1
// //DZ16x32Ram[k+22][1] = DZ_4x8Num[10][j]; // next 2
if((k+23) < 28)
DZ16x32Ram[k+23][1] = DZ_3x8Num[DS1302_Time_Buffer[0]/16][j]; // next 3
if((k+28) < 32)
DZ16x32Ram[k+28][1] = DZ_3x8Num[DS1302_Time_Buffer[0]%16][j]; // down 4
j+=1;
}
DZ_16x16_Char();
}
}
}
Scrollable display


That's it! There is really not much energy. Sorry.
It took 60 oceans to buy a 16x16 dot matrix screen of ws2812b. I took a fancy to its softness. I thought I could put it in the car and use it later in combination with other sensors to make som...
I tried to use shift register cascade + 38 decoder to achieve the effect of driving 16*16 LED dot matrix screen with 3 control lines. This is the third blog about the working principle of ...
I tried to use shift register cascade + 38 decoder to achieve the effect of driving 16*16 LED dot matrix screen with 3 control lines. This is the first blog about the working principle of ...
LED dot matrix experiment, display point. Understand 16Before 16 LED dot matrix, first understand 88 dot matrix. The 8*8 dot matrix is composed of 64 light-emitting diodes, and each light-emitting d...
In the sharing of this issue, we will share a drawing method called the Cliff origin map. The final effect will be as shown above, which can be completed in 5 minutes. Interested friends will try it t...
I. Introduction At present, the LED display screen uses the font software to generate a good byte sequence and then displays it, and the LED dot matrix writing screen is a new interactive scheme for p...
Given a matrix of m x n elements (m rows, n columns), return all the elements in the matrix in a clockwise spiral order. Example 1: Enter: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,3,6,9,...
topic: Enter a matrix and print out each number in clockwise order from the outside to the inside. For example, the matrix is , The output result is [1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10] solution: ...
Path in the matrix Design a function to determine if there is a path containing a string in the matrix...
Rectangular nested time limit:3000MS | Memory Limit:65535 KB Difficulty:4 description There are n rectangles, each rectangle can be described by A, B, indicating long and wide. Rectangular X (A, ...