【51单片机】7-LED点阵

news2025/1/12 6:06:36

1.LED点阵简介

1.什么是LED点阵

1.外观

2.作用

3.内部构造原理图

点阵的优势:就是8+8个IO口独立控制8*8个LED灯亮灭

2.如何驱动LED点阵--74HC595

2.1 单片机端口直接驱动

要驱动8*8的点阵需要2个IO端口,(16个IO口),要驱动16*16点阵需要4个IO端口(32个IO口)

2.2 使用串转并移位锁存器驱动:类似于队列【串入并出】

SER  10101100 同一个引脚不同的时间送进来,串入(串行输入)--》在一个一个进入的时候其他位是不会改变的

QA   1                同时在不同引脚输出,并出(并行输出)--》一起出去

QB    0

QC   1

QD   0

QE    1

QF   1

QG   0 

QH    0

2.3 为什么使用74HC595可以减少IO口的使用

因为74HC595中有一个输入端口“SER”,这个端口是一个一个的输入,一共输入8个二进制数,在一次性输入完8个二进制数后,将其分配给QA-QH这8个端口,这时候这8给段码端就有了IO口,就不需要再去连接mcu的端口。

使用串转并移位锁存驱动。要驱动16*16点阵只需要4个74HC595+1个IO端口。

实际上只需要(数据口SRE,SCLK,RCLK+4个74HC595就可以点亮点阵)

2.原理图分析

1.POS1-16和NEG1-16分别接移位锁存器并行输出端

(1)POS就是Positive 正极 ,NEG:negetive负极

2.74HC595的接法分析

(1)QA-QH8路并行输出接到点阵的一个端口

(2)【QH’】这个串行输出口接下一个74HC595的串行输入SER(串联顺序按照ABCD)

(3)SER串行输入接:第一个595的SER通过接J24的SER,后面的每一个SER都接入前面的【QH‘】。这样构成了ABCD4个595芯片依次串联。【所以将来编程整个4个74HC595的串行数据都是从J24的SER出来的】

(4)SCLK(SRCLK)接J24的2

(5)RCLK接J24的1

3. 总结

(1)SCLK和RCLK是一样的接法,都接再J24上

(2)总共涉及到的IO端口就3个(J24连接mcu的三个,可以自己连接)

(3)外部接线重点:2个8pin杜邦线+3个端口连接muc接口

4.外部跳线接法

3.LED点阵编程实践

1. 74HC595 的时序分析

(1)芯片与芯片之间的通信,都是通过一定的时序进行的。

(2)时序就是芯片与芯片之间的通信引脚上电平变化以时间轴为参考的变化顺序。

(3)时序是通信双方事先定义好的,通信的发送方必须按照时序来发送有意义的信息,通信的接收方按照时序去接收解析发送方发来的电平变化信息,然后就知道发送方要给我们发送什么东西。

(4)我们编程时候:发送方是单片机,接收方是74HC595。因为595芯片本身是不能编程的,他的时序芯片出厂时候已经设置好,因此我们单片机必须按照595芯片的时序来发送信息

(5)所以我们要先搞清楚74HC595的时序规则。595芯片手册上有它的时序描述(时序图),参考描述就可以明白595芯片的时序规则,然后将其编程语言表达出来即可。

SCLK和RCLK

(6)74HC595的时序的关键:SCLK和RCLK。

SCLK是移位时钟,595芯片再每一个SCKL的上升沿会对SER引脚进行依次采样输入【判断此时是高电平还是低电平】。就向595内部输入1位,如此循环8次就输入了8位二进制。RCLK是锁存时钟,QA-QH的8位并行输出信号再RCLK的上升沿进行一次锁存更新。

RCLK是锁存时钟,QA-QH的8位并行输出信号再RCLK的上升沿进行一次锁存更新。

SCLK和RCLK,SER

SER::进行数据的串行输入

SCLK:提供移位时钟【就是对上升沿的读取,判断是高电平还是低电平】

RCLK:提供锁存时钟【如果SER输入满8位二进制,则就进行一次锁存,第9位进入时,只能通过【QH’】将新进入的二进制移动到下一个74HC595上。】

2.sbit定义位变量

(1)之前的编程都是直接操作一个IO端口,可以用端口号(P0,P1)来整体操作一个IO端口中的8个引脚。但是这种方法不能操作单独一个IO口。

(2)今天需要单独操作一个IO引脚,比如要操作P1.3,但是直接写P1.3C语言不认识,而必须使用sbit关键字来定义一个引脚。

sbit SER = P1^3;//SER引脚名字

#include<reg51.h>

sbit RCLK =P0^0;  //74HC595的串行输入端
sbit SCLK=P0^1;  //锁存时钟
sbit SER=P0^2;  //移位时钟


int main(){
	
	unsigned char i=0;
	//一个值是8位
	unsigned char d1,d2,d3,d4;//要给4个595进行输出端输出的值
	
	//根据原理图可以知道d1和d2是连接正极,所以要输入d1和d2的是0才会亮
	d1=0;
	d2=0;
	//因为根据原理图中可以知道d3和d4连接的是负极,所以输入的d3和d4要为全1才亮
	d3=0xff;
	d4=0xff;
	
	//一开始就将两个置为低电平
	SCLK=0;
	RCLK=0;
	
	for(i=0;i<8;i++){
		
		//SCLK=0;---》可以的
		SER=d1>>7;//将d1的最高bit取出来给SER
		SCLK=0;
		//这句话:是上升沿,只要再上上升沿前出去最后一位,就可以
		SCLK=1;	//这2步制造了一个SCLK上升沿,在此时记录下这个数值,后面推进QA-QH中
		
		//将第二个进来的位数,变成最高位
		d1=d1<<1;
		
	}
	//至此已经再8个SCLK上升沿把d1的8位依次全部发出去了
	//但是还没有进行锁存,所以QA-QH还没有东西
	
	
	for(i=0;i<8;i++){
		
		SER=d2>>7;//将d2的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d2=d2<<1;
		
	}
	//至此已经把d1和d2都已经发出去了,并且d1已经被d2挤到第2个595芯片里面去了
	//此时595A中存放的是d2,595B中存放的是d1
	//但是还没有进行锁存,所以QA-QH还没有东西
	
		for(i=0;i<8;i++){
		
		SER=d3>>7;//将d3的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d3=d3<<1;
		
	}
	//至此已经把d1和d2和d3都已经发出去了,并且d1已经被d2和d3挤到第3个595芯片里面去了
	//此时595A中存放的是d3,595B中存放的是d2,595c中存放的是d1
	//但是还没有进行锁存,所以QA-QH还没有东西
	
		for(i=0;i<8;i++){
		
		SER=d4>>7;//将d4的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d4=d4<<1;
		
	}
	//至此已经把d1和d2和d3和d4都已经发出去了,并且d1已经被d2和d3和d4挤到第4个595芯片里面去了
	//此时595A中存放的是d4,595B中存放的是d3,595C中存放的是d2,595D中存放的是d1,
	//但是还没有进行锁存,所以QA-QH还没有东西
	
	//截至到这里,4个字节的数据d1,d2,d3,d4已经顺着74HC595的SER-》QH‘的串行输出
	//串行输出电路,已经爬满了4个74HC595(最先送出去的到了最后没一个595中)
	//但是到目前为止,4个595的QA-QH还没有出现锁存,点阵自然不会亮
	
	//然后要进行一次锁存,4个595芯片同时再进行锁存,各自锁存住了自己的数据
	RCLK=0;
	RCLK=1;
	//这两句之后595就完成了锁存,d1-d4就会影响4个595芯片的并行输出端,
	//进而会影响LED的正负极的值,然后LED就会亮或者灭
	
	//按照我们写的程序,d1和d2是负极,d3和d4是正极【原理图中有】
	
}

使用函数

#include<reg51.h>

sbit RCLK =P0^0;  //74HC595的串行输入端
sbit SCLK=P0^1;  //锁存时钟
sbit SER=P0^2;  //移位时钟


//如果函数写在main后面,记得声明
void SendData(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);



void SendData(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4){
	
	unsigned char i=0;
	
	//一开始就将两个置为低电平
	SCLK=0;
	RCLK=0;
	
	for(i=0;i<8;i++){
		
		//SCLK=0;---》可以的
		SER=d1>>7;//将d1的最高bit取出来给SER
		SCLK=0;
		//这句话:是上升沿,只要再上上升沿前出去最后一位,就可以
		SCLK=1;	//这2步制造了一个SCLK上升沿,在此时记录下这个数值,后面推进QA-QH中
		
		//将第二个进来的位数,变成最高位
		d1=d1<<1;
		
	}
	//至此已经再8个SCLK上升沿把d1的8位依次全部发出去了
	//但是还没有进行锁存,所以QA-QH还没有东西
	
	
	for(i=0;i<8;i++){
		
		SER=d2>>7;//将d2的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d2=d2<<1;
		
	}
	//至此已经把d1和d2都已经发出去了,并且d1已经被d2挤到第2个595芯片里面去了
	//此时595A中存放的是d2,595B中存放的是d1
	//但是还没有进行锁存,所以QA-QH还没有东西
	
		for(i=0;i<8;i++){
		
		SER=d3>>7;//将d3的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d3=d3<<1;
		
	}
	//至此已经把d1和d2和d3都已经发出去了,并且d1已经被d2和d3挤到第3个595芯片里面去了
	//此时595A中存放的是d3,595B中存放的是d2,595c中存放的是d1
	//但是还没有进行锁存,所以QA-QH还没有东西
	
		for(i=0;i<8;i++){
		
		SER=d4>>7;//将d4的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d4=d4<<1;
		
	}
	//至此已经把d1和d2和d3和d4都已经发出去了,并且d1已经被d2和d3和d4挤到第4个595芯片里面去了
	//此时595A中存放的是d4,595B中存放的是d3,595C中存放的是d2,595D中存放的是d1,
	//但是还没有进行锁存,所以QA-QH还没有东西
	
	//截至到这里,4个字节的数据d1,d2,d3,d4已经顺着74HC595的SER-》QH‘的串行输出
	//串行输出电路,已经爬满了4个74HC595(最先送出去的到了最后没一个595中)
	//但是到目前为止,4个595的QA-QH还没有出现锁存,点阵自然不会亮
	
	//然后要进行一次锁存,4个595芯片同时再进行锁存,各自锁存住了自己的数据
	RCLK=0;
	RCLK=1;
	//这两句之后595就完成了锁存,d1-d4就会影响4个595芯片的并行输出端,
	//进而会影响LED的正负极的值,然后LED就会亮或者灭
	
	//按照我们写的程序,d1和d2是负极,d3和d4是正极【原理图中有】
}

void main(){
	
	//因为d1和d2在595芯片中连接的是正电极,所以我们要输入0才会形成电压差
	//d3和d4是连接负电极,所以我们要输入1才会形成电压差
	SendData(0x00,0x00,0xff,0xff);
}

3.宏定义和的引入和uchar,u8

/**

	使用自定义的宏定义
*/

//自定义宏定义
#define uchar unsigned char   //#define 要尽量靠前,而且没有分号
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int


//如果函数写在main后面,记得声明
//void SendData(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);

void SendData(uchar d1,uchar  d2,uchar d3,uchar d4);

4.对点阵点亮规律探索

P1,P2控制列,P3,P4控制行的

1.编程点亮最上面一排:SendData(0x00,0x00,0x00,0x01)

2.编程点亮最下面一排:SendData(0x00,0x00,0x80,0x00);

3.编程点亮最左面一排:SendData(0xff,0xfe,0xff,0xff)

4.编程点亮最右面一排:SendData(0x7f,0xff,0xff,0xff)

5.点亮上半屏:SendData(0x00,0x00,0x00,0xff)

因为d1和d2在原理图上是对应负极,d3和d4应该输入正极

d1对应着NEG9-16,d2对应着NEG1-8,d3对应着POS9-16,d4对应着POS1-8

#include<reg51.h>
/**

	使用自定义的宏定义
*/

//自定义宏定义
#define uchar unsigned char

sbit RCLK =P0^0;  //74HC595的串行输入端
sbit SCLK=P0^1;  //锁存时钟
sbit SER=P0^2;  //移位时钟


//如果函数写在main后面,记得声明

void SendData(uchar d1,uchar  d2,uchar d3,uchar d4);



void SendData(uchar d1,uchar d2,uchar d3,uchar d4){
	
	uchar i=0;
	
	//一开始就将两个置为低电平
	SCLK=0;
	RCLK=0;
	
	for(i=0;i<8;i++){
		
		//SCLK=0;---》可以的
		SER=d1>>7;//将d1的最高bit取出来给SER
		SCLK=0;
		//这句话:是上升沿,只要再上上升沿前出去最后一位,就可以
		SCLK=1;	//这2步制造了一个SCLK上升沿,在此时记录下这个数值,后面推进QA-QH中
		
		//将第二个进来的位数,变成最高位
		d1=d1<<1;
		
	}
	
	
	for(i=0;i<8;i++){
		
		SER=d2>>7;//将d2的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d2=d2<<1;
		
	}
	
		for(i=0;i<8;i++){
		
		SER=d3>>7;//将d3的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d3=d3<<1;
		
	}
	
		for(i=0;i<8;i++){
		
		SER=d4>>7;//将d4的最高bit取出来给SER
		SCLK=0;
		SCLK=1;	//这2步制造了一个SCLK上升沿
		
		//将第二个进来的位数,变成最高位
		d4=d4<<1;
		
	}
	RCLK=0;
	RCLK=1;
}

void main(){
	SendData(0x00,0x00,0x00,0xff);//亮上半屏
}

6.点亮下半屏:SendData(0x00,0x00,0xff,0x00)

总结

(1)编写硬件控制代码,时序理解是关键。只要时序理解正确的,并且代码按照时序写

4.字模

1.什么是字模

(1)如何记录组成字的LED点阵亮灭信息(16*16点阵一共有256点,显示一共特定的字需要其中有一些点亮而另外一些不亮,如何记录哪些点亮哪一些点不亮?用字模)

(2)字模如何工作?256个点用256个二进制位表示,1表示这个点亮,0表示不亮。256个点就是256个二进制位,也就是256/8=32个字节,所以一个大小位16*16的字的字模的32个字节大小。所以字模的表现形式就是32个unsigned char型数据。

2.字模如何获取

(1)一般通过专门的字模软件去提取,这种软件的可以得到这个字对应的32个字节的字模编码。

(2)字模的结果不是唯一的,和你提取字模的方式有关(横向纵向)

(3)提取字模时是没有标准的,怎么做都是对的或者都是错的,关键是你提取的这个字模的方式和你用来在点阵上显示这个字模的函数必须对应。

3.字模软件的使用

(1)使用方式:

                        第一步:先选择字形(实际开发板多大就选择多大)

                        第二步:选择合适的字体,字号等

                        第三步:选择编码方式和实际取模方式

                        第四步:直接将得到的结果取走

4.字模手工分析和验证

(1)手工对比字模内容和屏幕显示,从进行验证

5.横向取模的显示

因为我们横向取模是一行一行展示

d1和d2是控制列,控制这列要显示哪一个点

d3和d4是控制行,控制要显示哪一行--》则我们可以一行一行的遍历16次(行)

SendData(~code[2*i+1],~code[2*i],hang[2*i],hang[2*i+1])

1.普通方法

1.按照取模软件的结果输入

取模软件得出的结果是:1亮,0灭,但是我们d1和d2是接负极【应该是1灭0亮】,与我们想要的结果相反

2.将取模结果按位取反

原来为1,取反变0;反之

3.将d1与d2位置调换

因为点在最右边,则可能是我们d1和d2的位置取反,则我们试着将其转换过来。

4.多试几行

/*--  文字:  朱  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
	//分析可知:
	//取模软件得出的结果是:1表示亮,0表示灭
uchar zhu[32] = {
0x80,0x00,0x88,0x00,0x88,0x00,0xF8,0x1F,0x84,0x00,0x82,0x00,0x80,0x00,0xFF,0x7F,
0xC0,0x01,0xA0,0x02,0x90,0x04,0x88,0x08,0x84,0x10,0x83,0x60,0x80,0x00,0x80,0x00 };



int main() {
	//显示第一行
	//取模结果与我们想要的相反
	//SendData(0x80, 0x00, 0x00, 0x01);
	//则我们将结果取反
	//SendData(~0x80, ~0x00, 0x00, 0x01);
	//将d1与d2两者的值调换一下
	//SendData(~0x00, ~0x80, 0x00, 0x01);			//第一行
	SendData(~0x00,~0x88,0x00,0x02);				//第二行
	
	SendData(~0x00,~0x88,0x00,0x02);				//第三行
	SendData(~0x00,~0x88,0x00,0x04);				//第四行
	SendData(~0x1F,~0xF8,0x00,0x10);				//第五行
	
	SendData(~0x1F,~0xF8,0x00,0x20);				//第6行
	
	SendData(~0x00,~0x84,0x00,0x40);				//第7行
	
	SendData(~0x00,~0x82,0x00,0x80);				//第8行
}

2.规律

/*--  文字:  朱  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
	//分析可知:
	//取模软件得出的结果是:1表示亮,0表示灭
uchar zhu[32] = {
0x80,0x00,0x88,0x00,0x88,0x00,0xF8,0x1F,0x84,0x00,0x82,0x00,0x80,0x00,0xFF,0x7F,
0xC0,0x01,0xA0,0x02,0x90,0x04,0x88,0x08,0x84,0x10,0x83,0x60,0x80,0x00,0x80,0x00 };

(1)d1和d2用字模来填充,填充时要取反【d1=0x00,d2=0x80】-->因为d1和d2对应的是负极【0亮1灭】与取模软件【1亮0灭】给的相反

(2)d3和d4来选择哪一个行被点亮,而d1和d2选择这行中哪一列被点亮

(3)SendData一次送16个LED的亮灭信息(2字节),所以必须调用256/16=16次SendData函数,才能把整个点阵全部点亮完毕。

(4)每一次调用SendData时,d1-d4变化是有规律的,因此有希望通过函数来调用SendData而不需要手工调用16次。

3.通过数组实现

#include<reg51.h>
/**

	横向取模:使用数组进行字的展示
*/

//自定义宏定义
#define uchar unsigned char

sbit RCLK = P0 ^ 0;  //74HC595的串行输入端
sbit SCLK = P0 ^ 1;  //锁存时钟
sbit SER = P0 ^ 2;  //移位时钟


//如果函数写在main后面,记得声明

void SendData(uchar d1, uchar  d2, uchar d3, uchar d4);



void SendData(uchar d1, uchar d2, uchar d3, uchar d4) {

	uchar i = 0;

	//一开始就将两个置为低电平
	SCLK = 0;
	RCLK = 0;

	for (i = 0;i < 8;i++) {

		//SCLK=0;---》可以的
		SER = d1 >> 7;//将d1的最高bit取出来给SER
		SCLK = 0;
		//这句话:是上升沿,只要再上上升沿前出去最后一位,就可以
		SCLK = 1;	//这2步制造了一个SCLK上升沿,在此时记录下这个数值,后面推进QA-QH中

		//将第二个进来的位数,变成最高位
		d1 = d1 << 1;

	}


	for (i = 0;i < 8;i++) {

		SER = d2 >> 7;//将d2的最高bit取出来给SER
		SCLK = 0;
		SCLK = 1;	//这2步制造了一个SCLK上升沿

		//将第二个进来的位数,变成最高位
		d2 = d2 << 1;

	}

	for (i = 0;i < 8;i++) {

		SER = d3 >> 7;//将d3的最高bit取出来给SER
		SCLK = 0;
		SCLK = 1;	//这2步制造了一个SCLK上升沿

		//将第二个进来的位数,变成最高位
		d3 = d3 << 1;

	}

	for (i = 0;i < 8;i++) {

		SER = d4 >> 7;//将d4的最高bit取出来给SER
		SCLK = 0;
		SCLK = 1;	//这2步制造了一个SCLK上升沿

		//将第二个进来的位数,变成最高位
		d4 = d4 << 1;

	}
	RCLK = 0;
	RCLK = 1;
}

/*--  文字:  朱  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
	//分析可知:
	//取模软件得出的结果是:1表示亮,0表示灭
uchar zhu[32] = {
0x80,0x00,0x88,0x00,0x88,0x00,0xF8,0x1F,0x84,0x00,0x82,0x00,0x80,0x00,0xFF,0x7F,
0xC0,0x01,0xA0,0x02,0x90,0x04,0x88,0x08,0x84,0x10,0x83,0x60,0x80,0x00,0x80,0x00 };

unsigned char hang[32]={
	0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,
	0x00,0x10,0x00,0x20,0x00,040,0x00,0x80,
	0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,
	0x10,0x00,0x20,0x00,0x40,0x00,0x80,0x00,
};

int main() {
	
	uchar i=0;
	//因为每一次调用senddata的时候输入16位,但是一共有256,所以要输入16次
	for(i=0;i<16;i++){
		
		SendData(~zhu[2*i+1],~zhu[2*i],hang[2*i],hang[2*i+1]);//每一次亮一行
	}
	
	
}

4.通过函数实现

void Display(uchar zimu[32],uchar hang[32]){
	
	
	uchar i=0;
	//因为每一次调用senddata的时候输入16位,但是一共有256,所以要输入16次
	for(i=0;i<16;i++){
		
		SendData(~zimu[2*i+1],~zimu[2*i],hang[2*i],hang[2*i+1]);//每一次亮一行
	}
	
	
}

int main() {
	
	Display(zhu,hang);
	
}

6.纵向取模的显示

(d1,d2,d3,d4)

纵向取模则要修改的是列

则d1和d2是控制显示哪一列--》所以我们可以使用一次数16列来进行递归

d3和d4是控制要显示这一列的哪几个点

SendData(lie[2*1],lie[2*i+1],code[i+16],code[i]);

1.使用数组进行展示

普通的显示最左边一列:SendData(0xff,0xfe,0xff,0xff)

#include<reg51.h>
/**

	纵向取模:使用数组进行字的展示
*/

//自定义宏定义
#define uchar unsigned char

sbit RCLK = P0 ^ 0;  //74HC595的串行输入端
sbit SCLK = P0 ^ 1;  //锁存时钟
sbit SER = P0 ^ 2;  //移位时钟


//如果函数写在main后面,记得声明

void SendData(uchar d1, uchar  d2, uchar d3, uchar d4);
void Display(uchar zimu[32],uchar lie[32]);



void SendData(uchar d1, uchar d2, uchar d3, uchar d4) {

	uchar i = 0;

	//一开始就将两个置为低电平
	SCLK = 0;
	RCLK = 0;

	for (i = 0;i < 8;i++) {

		//SCLK=0;---》可以的
		SER = d1 >> 7;//将d1的最高bit取出来给SER
		SCLK = 0;
		//这句话:是上升沿,只要再上上升沿前出去最后一位,就可以
		SCLK = 1;	//这2步制造了一个SCLK上升沿,在此时记录下这个数值,后面推进QA-QH中

		//将第二个进来的位数,变成最高位
		d1 = d1 << 1;

	}


	for (i = 0;i < 8;i++) {

		SER = d2 >> 7;//将d2的最高bit取出来给SER
		SCLK = 0;
		SCLK = 1;	//这2步制造了一个SCLK上升沿

		//将第二个进来的位数,变成最高位
		d2 = d2 << 1;

	}

	for (i = 0;i < 8;i++) {

		SER = d3 >> 7;//将d3的最高bit取出来给SER
		SCLK = 0;
		SCLK = 1;	//这2步制造了一个SCLK上升沿

		//将第二个进来的位数,变成最高位
		d3 = d3 << 1;

	}

	for (i = 0;i < 8;i++) {

		SER = d4 >> 7;//将d4的最高bit取出来给SER
		SCLK = 0;
		SCLK = 1;	//这2步制造了一个SCLK上升沿

		//将第二个进来的位数,变成最高位
		d4 = d4 << 1;

	}
	RCLK = 0;
	RCLK = 1;
}

/*--  文字:  朱  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
unsigned char zhu[32]={
0x80,0xA0,0x90,0x8E,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0x88,0x80,0x80,0x00,
0x20,0x20,0x10,0x08,0x04,0x02,0x01,0xFF,0x01,0x02,0x04,0x08,0x10,0x20,0x20,0x00};



unsigned char lie[32]={
	0xff,0xfe,0xff,0xfd,0xff,0xfb,0xff,0xf7,
	0xff,0xef,0xff,0xdf,0xff,0xbf,0xff,0x7f,
	0xfe,0xff,0xfd,0xff,0xfb,0xff,0xf7,0xff,
	0xef,0xff,0xdf,0xff,0xbf,0xff,0x7f,0xff
	
	
};

void display(uchar zimu[32],uchar lie[32]){
    SendData(lie[2*i],lie[2*i+1],zimu[i+16],zimu[i]);
}

int main() {
	//普通方法
	
	//原来亮最左边一列
	//SendData(0xff,0xfe,0xff,0xff);
	//第一列的上半部分是字符串中的第一个
	//第一列的下半部分是字符串中的第17个
	//SendData(0xff,0xfe,0x80,0x20);//最左边一列
	//调换d3和d4的位置
	//SendData(0xff,0xfe,0x20,0x80);//最左边一列
	
	//使用递归
	uchar i=0;
	for(i=0;i<16;i++){
		SendData(lie[2*i],lie[2*i+1],zhu[i+16],zhu[i]);
		
	}
}

2.总结

(1)获取取模软件输入进来的数组

(2)最左边是:SendData(0xff,0xfe,0xff,0xff)

(3)因为纵向排序是

所以,我们列数的第一个的对应取模软件的第一个数值,第二列应该对应着取模软件的第十七个数值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1037275.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Verilog 教程】5.3Verilog带参数实例化

关键词&#xff1a; defparam&#xff0c;参数&#xff0c;例化&#xff0c;ram 当一个模块被另一个模块引用例化时&#xff0c;高层模块可以对低层模块的参数值进行改写。这样就允许在编译时将不同的参数传递给多个相同名字的模块&#xff0c;而不用单独为只有参数不同的多个模…

【RT】什么是对抗攻击 | 视觉跟踪

现在有机会接触一下针对深度学习神经网络的对抗攻击&#xff0c;并做整理如下&#x1f914; 对于CV攻防&#xff0c;其实去年12月组会听完就浏览过相关文章&#x1f449;面向目标检测的对抗样本综述后门防御, NIPS2022 adversarial attack for tracking CVPR2021 | IoU Attack导…

JS的事件循环(Event Loop)

JS的事件循环 本文是我自己对事件循环的理解和总结&#xff0c;不会有太多的理论知识&#xff0c;已经有太多文章写过了&#xff0c;自己搜索下就能找到很多&#xff1b; 同时&#xff0c;文章中的观点仅是本人自己理解&#xff0c;比较白话&#xff0c;不用太较真啊&#xff0…

数字孪生在灌区信息中的应用

灌区信息是智慧水利的组成部分&#xff0c;对灌区现代化改造的支撑作用和地位尤为重要&#xff0c;对促进水利可持续发展有重要意义。灌区信息化系统主要对对灌区的水情、雨情、土壤墒情、气象等信息进行监测&#xff0c;对重点区域进行视频监控&#xff0c;同时对泵站、闸门进…

C++ VTK三维图像体积计算Qt

程序示例精选 C VTK三维图像体积计算Qt 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《C VTK三维图像体积计算Qt》编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 学习与…

基于SSM的乡镇篮球队管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Windows,macOS,Linux换行标识的前世今生,如何处理文本文件行尾的^M

title: Windows&#xff0c;macOS&#xff0c;Linux换行标识的前世今生&#xff0c;如何处理文本文件行尾的^M / The Past and Present of Line Break Symbols in Windows, macOS, Linux: How to Deal with ^M at the End of Text Files categories: 极客实用技巧 / Geek Prac…

Java面试被问了几个简单的问题,却回答的不是很好

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有需要我的支持&#xff0c;请私信或评论留言&#xff01; 前言 前几天参加了…

定时器之输出捕获

简介 • IC &#xff08; Input Capture &#xff09;输入捕获 • 输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变时&#xff0c;当前 CNT 的值将被锁存到 CCR 中&#xff0c;可用于测量 PWM 波形的频率、占空比、脉冲间隔、电平持续时间等参数 • 每个高级定时器和…

防泄密软件推荐(数据防泄漏软件好用榜前五名)

在当今的数字化时代&#xff0c;数据已经成为企业最宝贵的资产之一。企业需要依赖数据来驱动业务决策、提高运营效率和创新产品。然而&#xff0c;随着数据量的不断增长&#xff0c;数据安全问题也日益凸显。企业需要采取有效的措施来保护敏感数据&#xff0c;防止信息泄露给竞…

5次多项式轨迹规划(博途SCL源代码)

运动控制轨迹规划时,加速度不连续将会使电机抖动,产生机械冲击。凸轮表轨迹规划很多都是基于5次多项式轨迹规划。3次多项式轨迹规划请查看下面文章链接: 3次多项式轨迹规划(PLC SCL代码)_RXXW_Dor的博客-CSDN博客机器人、运动控制等常用的轨迹规划有三次多项式、五次多项式…

第二章 进程与线程 十四、进程互斥的硬件实现方法(中断屏蔽法、TestAndSet指令、Swap指令)

目录 一、中断屏蔽法 3、优点&#xff1a; 4、缺点: 二、TestAndSet指令 3、代码解释 4、优点 5、缺点 三、Swap指令 1、定义 2、代码解释 3、优点 4、缺点 四、总结 一、中断屏蔽法 1、关中断后即不允许当前进程被中断&#xff0c;也必然不会发生进程切换。 2、…

【Tracking】Real-Time Camera Tracking: When is High Frame-Rate Best

paper: Real-Time Camera Tracking: When is High Frame-Rate Best? 0. 摘要&#xff1a; 更高的帧率承诺能更好地跟踪快速运动&#xff0c;但先进的实时视觉系统很少超过标准的10-60Hz范围&#xff0c;因为认为所需的计算量太大。实际上&#xff0c;在利用预测优势的跟踪器…

不添加端口号访问非80网站

自己用树莓派搭了个网站&#xff0c;由于某些原因&#xff0c;不能使用80端口&#xff0c;但又想访问网站时候不要添加端口号。这时候可以更换下DNS服务器&#xff0c;如使用cloudflare&#xff0c;替换成以下两个 参考文章 https://www.cnblogs.com/beidaxmf/p/16744589.html…

常见列表字典排序

一、列表排序 demoList [1, 3, 2, 4, 9 ,7]res sorted(demoList) # 默认升序# 降序 # res sorted(demoList, reverseTrue)print(res)二、字典排序 demoDict {"篮球": 5, "排球": 9, "网球": 6, "足球": 3}# sorted排序 res so…

Python_ithheima_第二阶段

第一章 01-初识对像 02 类的成员方法 03 类和对象 04 构造方法 05 魔术方法 06 封装 07 封装的课后练习题讲解 08 继承的基础语法 pass关键字的功能是“语法补全” 同名成员或方法&#xff0c;谁先来谁优先级高 09 复写父类成员和调用父类成员 10 变量的类型注解 11 函数和方法…

gitee-快速设置

快速设置— 如果你知道该怎么操作&#xff0c;直接使用下面的地址 HTTPS SSH: gitgitee.com:liuzl33078235/esp-idf.git 我们强烈建议所有的git仓库都有一个README, LICENSE, .gitignore文件 初始化 readme 文件 Git入门&#xff1f;查看 帮助 , Visual Studio / TortoiseG…

RabbitMQ 集群 - 普通集群、镜像集群、仲裁队列

目录 一、RabbitMQ 集群 1.1、前言 1.2、普通集群 1.3、镜像集群 1.4、仲裁队列 一、RabbitMQ 集群 1.1、前言 前面我们已经解决了消息可靠性问题&#xff0c;以及延迟消息问题 和 消息堆积问题. 这最后一章&#xff0c;我们就来解决以下 mq 的可用性 和 并发能力. 1.2、…

企业贸易站官网是HTML模板源码,提供完整源代码

企业贸易站官网是HTML模板源码&#xff0c;提供完整源代码二改的是 为了一起学习所以就分享出来了 有能力的可以自己做成主题配合帝国或者WordPress系统 &#xff08;访问密码&#xff1a;2971&#xff09;无需解压密码 源代码&#xff1a;https://url53.ctfile.com/f/20638…

Vue的自定义事件(Custom Events):实现组件间通信的强大工具

Vue的自定义事件&#xff08;Custom Events&#xff09;&#xff1a;实现组件间通信的强大工具 Vue.js是一款流行的JavaScript框架&#xff0c;用于构建交互式的Web应用程序。在Vue中&#xff0c;组件是构建应用程序的基本单元&#xff0c;它们之间的通信对于构建复杂的应用非…