【51单片机】7-LED点阵

【51单片机】7-LED点阵_第1张图片

1.LED点阵简介

1.什么是LED点阵

1.外观

【51单片机】7-LED点阵_第2张图片

2.作用

3.内部构造原理图

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

【51单片机】7-LED点阵_第3张图片

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

2.1 单片机端口直接驱动

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

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

【51单片机】7-LED点阵_第4张图片

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

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

QB    0

QC   1

QD   0

QE    1

QF   1

QG   0 

QH    0

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

【51单片机】7-LED点阵_第5张图片

因为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负极

【51单片机】7-LED点阵_第6张图片

2.74HC595的接法分析

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

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

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

【51单片机】7-LED点阵_第7张图片

【51单片机】7-LED点阵_第8张图片

(4)SCLK(SRCLK)接J24的2

(5)RCLK接J24的1

【51单片机】7-LED点阵_第9张图片

3. 总结

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

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

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

4.外部跳线接法

【51单片机】7-LED点阵_第10张图片

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引脚名字

【51单片机】7-LED点阵_第11张图片

#include

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

/**
	点亮整个LED灯
*/

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

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);

【51单片机】7-LED点阵_第12张图片

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

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

【51单片机】7-LED点阵_第13张图片

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

【51单片机】7-LED点阵_第14张图片

【51单片机】7-LED点阵_第15张图片

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

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

#include
/**

	使用自定义的宏定义
*/

//自定义宏定义
#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)

7.点亮四个角:SendData(0x7f,0xfe,0x80,0x01)

	//亮四角的四颗
	//四颗:则d1对应9-16列,要求亮16列【最大的那个】(0亮1灭)
	//d2对应1-8列,要求亮第一列【最小的那个】(0亮1灭)
	//d3对应9-16行,要求亮最后一行【最大的那个】(1亮0灭)
	//d4对应1-8行,要求最上一行【最小的那个】(1亮0灭)
	SendData(0x7f,0xfe,0x80,0x01);

总结

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

(2)d1-d4都是最低bit位表示编号小是数字,比如d4的bit0对应1

(3)d3和d4是正极,1亮0灭;d1和​​​​​​​d2是负极,1灭0亮。

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])

【51单片机】7-LED点阵_第16张图片

1.普通方法

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

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

【51单片机】7-LED点阵_第17张图片

【51单片机】7-LED点阵_第18张图片

2.将取模结果按位取反

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

【51单片机】7-LED点阵_第19张图片

【51单片机】7-LED点阵_第20张图片

3.将d1与d2位置调换

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

【51单片机】7-LED点阵_第21张图片

【51单片机】7-LED点阵_第22张图片

4.多试几行

【51单片机】7-LED点阵_第23张图片

/*--  文字:  朱  --*/
/*--  宋体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.通过数组实现

【51单片机】7-LED点阵_第24张图片

#include
/**

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

//自定义宏定义
#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]);

【51单片机】7-LED点阵_第25张图片

1.使用数组进行展示

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

#include
/**

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

//自定义宏定义
#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)因为纵向排序是【51单片机】7-LED点阵_第26张图片

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

你可能感兴趣的:(51单片机,嵌入式硬件,单片机)