16*16点阵 两个扩展为16*32点阵

tech2022-08-03  139

16*16点阵 两个扩展为16*32点阵

文章目录

一、8*8点阵的管脚图,拉线图:二、16*16点阵的74HC595级联图:三、点阵的软件取模:四、 原理图五、 代码:六、效果图

一、8*8点阵的管脚图,拉线图:

阳极的:

阴极的其他的都不变:(A0-A7是阳极 ,B0-B7是阴极) 四个级联图:(16*16点阵)

直接用16+16个IO口控制比较浪费,可以采用芯片(MAX7219,74HC595等)来驱动,都可以级联,可以节省很多IO口。 本文采用74HC595级联:

二、16*16点阵的74HC595级联图:

三、点阵的软件取模:

1.汉字取模软件: 模式改为C51 这两个括号去掉 点确定 复制底下的就是取的模。

2. 数字取模 直接点点,手动取模。 1.打开取模软件 2.新建图像,宽高改为8*8 3.参数设置,其他选项。

4.按下图配置 5.直接在图像上点击要取的图像数字 6.画好后,点击取模方式,c51取模。

7.下图即为取模数据。

四、 原理图

五、 代码:

这个代码经过测试,可以显示。 HC595.h

#ifndef HC595 #define HC595 #define HC595_Port_RCC RCC_APB2Periph_GPIOB //时钟 #define HC595_PIN GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12 //引脚 #define HC595_PORT GPIOB //端口 #define HC595_SH PBout(12) //锁存寄存器 #define HC595_ST PBout(11) //移位寄存器 #define HC595_DS PBout(10) //数据输入 /* 变量定义 */ //uchar duan[][32]; /*函数声明 */ void HC595_Init(void); void DZ_Chinese_Static_Display(void); // 静态显示两个汉字 void DZ_Chinese_Dynamic_Display(void); // 滚动显示 void DZ_Num_Static_Display(void); void DZ_Num_Dynamic_Display(void); #endif

HC595.c

#include "All.h" uchar DZ16x32Ram[32][2]; // 开辟缓存空间,每列两个字节, // 二列、一列、二行、一行 // 行是1, 列是0 uchar column1[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf,0x7f, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, }; //第一列 uchar column2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f, }; //第二列 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, //我 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, //爱 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, //你 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, //啊 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的数字,实际显示3*7 但是挨着一起,太挤,故中间空一行变为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,/*不显示11*/ 0x08,0x08,0x08,0x08,0x00,/*-12*/ }; uchar DZ_4x8Num_Buffer[40] ; // 动态显示数字缓存 /*3*8的数字,实际显示3*5 但是挨着一起,太挤,故中间空一行变为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管脚初始化 */ void HC595_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(HC595_Port_RCC,ENABLE);//系统时钟使能 GPIO_InitStructure.GPIO_Pin = HC595_PIN; //定义管脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//管脚输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//管脚的速度 GPIO_Init(HC595_PORT,&GPIO_InitStructure); //初始化端口 } //Hc595传输数据 void Hc595_Send_Byte(uchar dat) { uchar i; for(i=0;i<8;i++) { HC595_SH=0;//移位 if(dat&0x80) // HC595_DS= 1; else HC595_DS =0; dat<<=1; delay_us(2); HC595_SH=1;//移位 时钟上升沿拷贝 delay_us(2); } } /* 显示两个16*16的字符 one 为第一个16*16点阵要显示的数字 two 为第二个16*16点阵要显示的数字 */ void DZ_16x16_Char(void) { uchar i; for(i = 0; i< 16; i++) { /* 第二个16*16点阵*/ // 16*16点阵 /* 一次传输一行,2个字节,控制位选*/ Hc595_Send_Byte(column2[i]); // A 第二列 阴极 Hc595_Send_Byte(column1[i]); // 第一列 /* 一次传输一列,2个字节,显示一列16个点阵*/ Hc595_Send_Byte(DZ16x32Ram[i+16][1]); // 第二行 // 一次显示一列数据 Hc595_Send_Byte(DZ16x32Ram[i+16][0]); // 第一行 /* 第一个16*16点阵 */ // 16*16点阵 /* 一次传输一行,2个字节,控制位选*/ Hc595_Send_Byte(column2[i]); // A 第二列 阴极 Hc595_Send_Byte(column1[i]); // 第一列 /* 一次传输一列,2个字节,显示一列16个点阵*/ Hc595_Send_Byte(DZ16x32Ram[i][1]); // 第二行 Hc595_Send_Byte(DZ16x32Ram[i][0]); // 第一行 HC595_ST=1; // 锁存数据 delay_us(2); HC595_ST=0; } } /* 点阵静态显示函数*/ void DZ_Chinese_Static_Display(void) { uchar j,k,m; for (m = 0; m < 20; m++) { j = 0; for (k = 0; k < 16; k++) //显示一个16*16的点阵 { DZ16x32Ram[k][1] = DZ_16x16Chinese[0][j+1]; // 必须是奇数 DZ16x32Ram[k][0] = DZ_16x16Chinese[0][j]; // 必须是偶数 DZ16x32Ram[k+16][1] = DZ_16x16Chinese[1][j+1]; DZ16x32Ram[k+16][0] = DZ_16x16Chinese[1][j]; j+=2; } DZ_16x16_Char(); } } /* 点阵动态显示函数 */ void DZ_Chinese_Dynamic_Display(void) { uchar i,k,j=0,m; /* 64是一次显示两屏*/ for (i =0 ;i<64;i++) // 循环显示次数 { for(m = 0;m<20;m++) // 滚动显示的快慢 { j = 0; // 每次显示一组,清零 for (k = 0; k < 16; k++) //显示一个16*16的点阵 { /*(j+1+2*i) :j+1确保是奇数 2*i,确保每次变动两个,还是个奇数 (64*2): 64表示是一个字需要变动的次数,2代表要滚动显示2屏4个字*/ DZ16x32Ram[k][1] = DZ_16x16Chinese[0][(j+1+2*i)%(64*2)]; // 必须是奇数 DZ16x32Ram[k][0] = DZ_16x16Chinese[0][(j+2*i)%(64*2)]; // 必须是偶数 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++) //控制刷新的频率 // { j = 0; // 每次都重新显示 for (k = 0; k < 5; k++) //显示一个16*16的点阵 { /* 前8个控制左边的,后8个控制右边的*/ DZ16x32Ram[k][0] = DZ_4x8Num[DS1302_Time_Buffer[4]/16][j]; // 上1 DZ16x32Ram[k+5][0] = DZ_4x8Num[DS1302_Time_Buffer[4]%16][j]; // 上2 DZ16x32Ram[k+10][0] = DZ_4x8Num[10][j]; // 上3 DZ16x32Ram[k+15][0] = DZ_4x8Num[DS1302_Time_Buffer[3]/16][j]; // 上4 DZ16x32Ram[k][1] = DZ_4x8Num[DS1302_Time_Buffer[2]/16][j]; // 下1 DZ16x32Ram[k+5][1] = DZ_4x8Num[DS1302_Time_Buffer[2]%16][j]; // 下2 if((k+9) < 12) DZ16x32Ram[k+9][1] = DZ_4x8Num[10][j]; // 下3 DZ16x32Ram[k+13][1] = DZ_4x8Num[DS1302_Time_Buffer[1]/16][j]; // 下4 // 第二块屏幕 DZ16x32Ram[k+20][0] = DZ_4x8Num[DS1302_Time_Buffer[3]%16][j]; // 上1 DZ16x32Ram[k+25][0] = DZ_4x8Num[11][j]; // 上2 DZ16x32Ram[k+30][0] = DZ_4x8Num[11][j]; // 上3 DZ16x32Ram[k+32][0] = DZ_4x8Num[11][j]; // 上4 DZ16x32Ram[k+18][1] = DZ_4x8Num[DS1302_Time_Buffer[1]%16][j]; // 下1 //DZ16x32Ram[k+22][1] = DZ_4x8Num[10][j]; // 下2 if((k+24) < 28) DZ16x32Ram[k+24][1] = DZ_3x8Num[DS1302_Time_Buffer[0]/16][j]; // 下3 // if((k+22) < 25) DZ16x32Ram[k+28][1] = DZ_3x8Num[DS1302_Time_Buffer[0]%16][j]; // 下4 j+=1; } DZ_16x16_Char(); // } } /*动态循环显示日期*/ 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++) //显示一个16*16的点阵 { 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]; // 上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++) // 循环次数 { DS1302_Read_Time(); // 每次读取一次时间 ,时间会连贯显示 // u1_printf("%x\r\n", DS1302_Time_Buffer[2]); for ( m= 0; m < 20; m++) //控制刷新的频率 { j = 0; // 每次都重新显示 for (k = 0; k < 5; k++) //显示一个16*16的点阵 { /* 前8个控制左边的,后8个控制右边的*/ DZ16x32Ram[k][0] = DZ_4x8Num_Buffer[(k+i)%32]; // 上1 DZ16x32Ram[k+5][0] = DZ_4x8Num_Buffer[(5+k+i)%32]; // 上2 DZ16x32Ram[k+10][0] = DZ_4x8Num_Buffer[(10+k+i)%32] ; // 上3 DZ16x32Ram[k+15][0] = DZ_4x8Num_Buffer[(15+k+i)%32]; // 上4 DZ16x32Ram[k][1] = DZ_4x8Num[DS1302_Time_Buffer[2]/16][j]; // 下1 DZ16x32Ram[k+5][1] = DZ_4x8Num[DS1302_Time_Buffer[2]%16][j]; // 下2 if((k+9) < 13) DZ16x32Ram[k+9][1] = DZ_4x8Num[10][j]; // 下3 DZ16x32Ram[k+13][1] = DZ_4x8Num[DS1302_Time_Buffer[1]/16][j]; // 下4 //u1_printf("%x\r\n",DZ16x32Ram[k+13][1]); // // 第二块屏幕 DZ16x32Ram[k+20][0] = DZ_4x8Num_Buffer[(20+k+i)%32]; // 上1 DZ16x32Ram[k+25][0] = DZ_4x8Num_Buffer[(25+k+i)%32]; // 上2 if((k+30) < 32) DZ16x32Ram[k+30][0] = DZ_4x8Num_Buffer[(30+k+i)%32]; // 上3 // DZ16x32Ram[k+32][0] = DZ_4x8Num_Buffer[32+k]; // 上4 DZ16x32Ram[k+18][1] = DZ_4x8Num[DS1302_Time_Buffer[1]%16][j]; // 下1 // //DZ16x32Ram[k+22][1] = DZ_4x8Num[10][j]; // 下2 if((k+23) < 28) DZ16x32Ram[k+23][1] = DZ_3x8Num[DS1302_Time_Buffer[0]/16][j]; // 下3 if((k+28) < 32) DZ16x32Ram[k+28][1] = DZ_3x8Num[DS1302_Time_Buffer[0]%16][j]; // 下4 j+=1; } DZ_16x16_Char(); } } }

六、效果图

可滚动显示

就写到这吧!实在是精力不多。抱歉。

最新回复(0)