700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Arduino案例实操 -- 点阵屏汉字显示(MAX7219级联)

Arduino案例实操 -- 点阵屏汉字显示(MAX7219级联)

时间:2019-08-26 06:21:13

相关推荐

Arduino案例实操 -- 点阵屏汉字显示(MAX7219级联)

bbbbbbbbbbbbbbbbbbbb@TOC

LED点阵屏

LED点阵屏通过LED(发光二极管)组成,以灯珠亮灭来显示文字、图片、动画、视频等,是各部分组件都模块化的显示器件,通常由显示模块、控制系统及电源系统组成。LED点阵显示屏制作简单,安装方便,被广泛应用于各种公共场合,如汽车报站器、广告屏以及公告牌等。

显示原理bbbb

以简单的8X8点阵为例,它共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一行置1电平,某一列置0电平,则相应的二极管就亮。

模块外围有16个引脚,序号如下。

而内部线序却不与外部引脚一致,点亮点阵屏中的LED需要按照内部线序来操作,如要将第一个点点亮,则9脚接高电平13脚接低电平,则第一个点就亮了;如果要将第一行点亮,则第9脚要接高电平,而(13、3、4、10、6、11、15、16)这些引脚接低电平,那么第一行就会点亮;如要将第一列点亮,则第13脚接低电平,而(9、14、8、12、1、7、2、5)接高电平,那么第一列就会点亮。

8x8点阵屏引脚连接

如上一节介绍,要正常点亮LED点阵需要连接16根线,也就是需要用到16个IO口,根据内部线序正确连接LED点阵的正极引脚和负极引脚(实质上为内部LED点亮的正极引脚与负极引脚);点阵屏的(9, 14, 8, 12, 1, 7, 2, 5)分别连接Arduino控制板的(6,11, 5, 9, 14, 4, 15, 2),这8个引脚为内部LED的正极引脚,点阵屏的(13, 3, 4, 10, 6, 11, 15, 16)分别连接开发板的(10,16, 17, 7, 3, 8, 12, 13),这8个引脚为内部LED的负极引脚。(如果你用的控制板是UNO和NANO这些,模拟引脚A0 - A5 也可以当点阵屏的控制引脚)

8x8点阵屏代码编写

int leds[8] = {6, 11, 5, 9, A0, 4, A1, 2}; //点阵屏正极引脚int gnds[8] = {10, A2, A3, 7, 3, 8, 12, 13}; //点阵屏负极引脚void setup() {for (int i = 0; i < 8; i++){//将所有引脚配置为输出引脚pinMode(leds[i], OUTPUT);pinMode(gnds[i], OUTPUT);digitalWrite(gnds[i], HIGH); //内部LED负极引脚给高电平,熄灭所有LED}}//点亮点阵屏void ledopen(){//将点阵屏正极引脚拉高,负极引脚拉低,开启显示for (int i = 0; i < 8; i++){digitalWrite(leds[i], HIGH);digitalWrite(gnds[i], LOW);}}//熄灭点阵屏void ledclose(){//将点阵屏正极引脚拉低,负极引脚拉高,关闭显示for (int i = 0; i < 8; i++){digitalWrite(leds[i], LOW); digitalWrite(gnds[i], HIGH);}}//逐列扫描void ledCol(){for (int i = 0 ; i < 8; i++){digitalWrite(gnds[i], LOW); for (int j = 0; j < 8; j++){digitalWrite(leds[j], HIGH);delay(40);}digitalWrite(gnds[i], HIGH);ledclean();}}//逐行扫描void ledRow(){for (int i = 0 ; i < 8; i++){digitalWrite(leds[i], HIGH);for (int j = 0; j < 8; j++){digitalWrite(gnds[j], LOW);delay(40);}digitalWrite(leds[i], LOW);ledclean();}}void loop() {ledopen(); //点阵屏打开delay(500);ledclose(); //点阵屏关闭delay(500);ledCol(); //列扫描ledRow(); //行扫描}

8x8点阵屏实验现象

根据程序控制的效果,点阵屏的显示为全亮,全灭,列扫描,行扫描,如下。

MAX7219

传统的点阵模块点亮需要用到16个IO引脚,这对IO口有限的控制板来说负担太大,接线也变得相对复杂,因此有了新的LED点阵屏解决方案 – MAX7219。

MAX7219 是美国MAXIM 公司推出的多位LED 显示驱动器,采用3 线串行接口传送数据,可直接与单片机接口连接,用户能方便修改其内部参数,以实现多位LED 显示。它内含硬件动态扫描电路、BCD译码器、段驱动器和位驱动器。此外,其内部还含有8X8 位静态RAM,用于存放8 个数字的显示数据。显然,它可直接驱动64 段LED点阵显示器。当多片MAX7219 级联时,可控制更多的LED 点阵显示器。显示的数据通过单片机数据处理后,送给MAX7219 显示。

MAX7219/MAX7221是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。 只有一个外部寄存器用来设置各个LED的段电流。 MAX7221与SPI™、 QSPI™以及 MICROWIRE™相兼容,同时它有限制回转电流的段驱动来减少EMI(电磁干扰)。 一个方便的四线串行接口可以联接所有通用的微处理器。 每个数据可以寻址在更新时不需要改写所有的显示。MAX7219/MAX7221同样允许用户对每一个数据选择编码或者不编码。 整个设备包含一个150μA的低功耗关闭模式,模拟和数字亮度控制,一个扫描限制寄存器允许用户显示1-8位数据,还有一个让所有LED发光的检测模式。

MAX7219内部原理框图
MAX7219典型应用框图

关于MAX7219的应用框图如下,控制器连接MAX7219输入端,MAX7219控制端连接8位数码管或者是8x8LED点阵屏。同时也不要被图片的接线所误导,图中DIG 0 - DIG

7是指的MAX7219 DIG0,DIG1,DIG2,DIG3,DIG4,DIG5,DIG6,DIG7这7个引脚,同理SEG A-G,SEG DP也是指的MAX7219的8个引脚。

DIN引脚:串行数据输入端口。在时钟上升沿时数据被载入内部的16位寄存器。 2,3,5-8,10,11 DIG 0–DIG7 八个数据驱动线路置显示器共阴极为低电平。关闭时7219此管脚输出高电平,7221呈现高阻抗。LOAD 引脚(MAX7219): 载入数据。连续数据的后16位在LOAD端的上升沿时被锁定。CS (MAX7221) 片选端。该端为低电平时串行数据被载入移位寄存器。连续数据的后16位在cs端的上升沿时被锁定。CLK 引脚:时钟序列输入端。最大速率为 10MHz.在时钟的上升沿, 数据移入内部移位寄存器。 下降沿时, 数据从DOUT端输出。对MAX7221来说,只有当cs端为低电平时时钟输入才有效。DIG0~DIG7:8位LED位选线,从共阴极LED中吸入电流。SEG A~SEG G 、SEG DP :7段驱动和小数点驱动。

简单来说,MAX7219芯片可以驱动一块8x8的LED点阵,而连接控制板的就只需要3根线,即采用MAX7219方案只需要3根线可以控制一块8x8LED点阵屏。

MAX7219点阵显示模块

MAX7219点阵显示模块,通过16位数据串行输入输出方式完成控制64个LED,全程仅需3个IO口。市面上售卖的MAX7219点阵显示模块有两种规格,如下面的横向级联式:

靠近MAX7219芯片一端的是输入引脚,另一端是级联下一个MAX7219点阵显示模块的输出引脚,同样是5个引脚,只是输入的DIN引脚变为输出的DOUT引脚;可级联多个点阵模块,但基本只能是作为横向级联用。

下面是另一种规格,因为电路板的大小与点阵屏大小一致或略微小于点阵屏,这样就很方便将8x8点阵屏拼接成16x16或是32x32的大点阵屏:

点阵显示模块接线

模块接线。

点阵显示模块示例代码

int clk =3;int cs=4;int din=5;unsigned char disp1[12][8]={{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//0{0x08,0x18,0x28,0x08,0x08,0x08,0x08,0x08},//1{0x7E,0x2,0x2,0x7E,0x40,0x40,0x40,0x7E},//2{0x3E,0x2,0x2,0x3E,0x2,0x2,0x3E,0x0},//3{0x8,0x18,0x28,0x48,0xFE,0x8,0x8,0x8},//4{0x3C,0x20,0x20,0x3C,0x4,0x4,0x3C,0x0},//5{0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C,0x0},//6{0x3E,0x22,0x4,0x8,0x8,0x8,0x8,0x8},//7{0x0,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E},//8{0x3E,0x22,0x22,0x3E,0x2,0x2,0x2,0x3E},//9{0x08,0x7F,0x49,0x49,0x7F,0x08,0x08,0x08},//中{0xFE,0xFE,0x92,0xFE,0x9A,0xFE,0x82,0xFE},//国};void setup(){//设置引脚为输出pinMode(cs,OUTPUT);pinMode(clk,OUTPUT);pinMode(din,OUTPUT);//初始化MAX7219Init_MAX7219();}void loop(){char i,j;//字体扫描显示for(j=0;j<12;j++){for(i=1;i<9;i++){Write_Max7219(i,disp1[j][i-1]);delay(100);}delay(500);} }void Write_Max7219_byte(char DATA) {char i; digitalWrite(cs,0);for(i=8;i>=1;i--){digitalWrite(clk,0);if((DATA&0x80)>7){digitalWrite(din,1);}else{digitalWrite(din,0);}//提取最高位给DIN端口DATA=DATA<<1;//左移一位digitalWrite(clk,1);} }void Write_Max7219(char address,char dat){digitalWrite(cs,0);Write_Max7219_byte(address); //写入地址,即数码管编号Write_Max7219_byte(dat);//写入数据,即数码管显示数字 digitalWrite(cs,1); }void Init_MAX7219(void){Write_Max7219(0x09, 0x00);//译码方式:BCD码Write_Max7219(0x0a, 0x01);//亮度 Write_Max7219(0x0b, 0x07); //扫描界限;8个数码管显示Write_Max7219(0x0c, 0x01); //掉电模式:0,普通模式:1Write_Max7219(0x0f, 0x00);delay(500); //显示测试:1;测试结束,正常显示:0}

点阵显示模块实验现象

按照代码轮流显示数字 “1 - 9” 以及中文 “中”,“国”,如图8x8点阵用于显示的话最好是显示数字及字母,中文的话显示少比划的字会比较直观,显示笔画较多或者复杂文字的话,就会显得有点尬了,可以参考下面的 “国” 字。

16x16点阵屏

用于显示文字用16x16点阵屏更为合适,如下16x16的字模预览图。

市面上级联的点阵屏方案有很多,用于做案例的话基本是用四块8x8的LED拼接成的16x16点阵屏,可以买现成的16x16 LED点阵屏UART控制模块。

或者是自己动手将四块8x8点阵屏拼接起来,但最好是先跑一编程序过后再将四块8x8点阵屏粘起来或者用透明胶圈在一起,否正将出现以下情况,某块8x8的点阵屏跟其他8x8点阵屏的文字朝向不同,或者四块点阵屏是四个朝向,那就很尴尬了,如下图可以看到左上角的8x8点阵方向与其他点阵屏方向不同,导致一个字不能完整的显示出来。

16x16点阵屏编程

不管是8x8或16x16的点阵显示,有字模软件都是可以很方便的生成所需字模,例如16x16所要用到的字模软件,很方便的将多个汉字的字模一起提取出来。

字模提取

需要注意的一点是,字模软件上不管是提取一个汉字或者多个汉字,生成的字模并不是直接就能放进代码里面的,先以一个字为例,“科” 字取模,能得到的一组16进制数组如下:

{0x00,0x24,0x24,0xA4,0xFE,0xA3,0x22,0x00,0x22,0xCC,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x08,0x06,0x01,0xFF,0x00,0x01,0x04,0x04,0x04,0x04,0x04,0xFF,0x02,0x02,0x02}

因为每个汉字都是显示在16x16点阵上,所以每个8x8点阵都需要分担四分之一的汉字显示区域,即是一个汉字生成的数组字模,也需要分成四份,给到四块8x8点阵,将软件生成的单个汉字的32个16进制数组按8个,8个分成4组,如下:

unsigned char disp1[1][8] = {{0x00,0x24,0x24,0xA4,0xFE,0xA3,0x22,0x00},//科1 (左上角8x8点阵显示)};unsigned char disp2[1][8] = {{0x22,0xCC,0x00,0x00,0xFF,0x00,0x00,0x00},//科2 (右上角8x8点阵显示)};unsigned char disp3[1][8] = {{0x00,0x08,0x06,0x01,0xFF,0x00,0x01,0x04},//科3 (左下角8x8点阵显示)};unsigned char disp4[1][8] = {{0x04,0x04,0x04,0x04,0xFF,0x02,0x02,0x02},//科4 (右下角8x8点阵显示)};

如果要显示两个字交替显示的话,字模数组这么写:

unsigned char disp1[2][8] = {{0x00,0x24,0x24,0xA4,0xFE,0xA3,0x22,0x00},//科1 {0x00,0x10,0x10,0x10,0xFF,0x10,0x90,0x08},//技1};unsigned char disp2[2][8] = {{0x22,0xCC,0x00,0x00,0xFF,0x00,0x00,0x00},//科2 {0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x08},//技2};unsigned char disp3[2][8] = {{0x00,0x08,0x06,0x01,0xFF,0x00,0x01,0x04},//科3 {0x00,0x04,0x44,0x82,0x7F,0x01,0x80,0x80},//技3};unsigned char disp4[2][8] = {{0x04,0x04,0x04,0x04,0xFF,0x02,0x02,0x02},//科4 {0x40,0x43,0x2C,0x10,0x28,0x46,0x81,0x80},//技4};

16x16点阵屏代码

提取出字模后直接写代码。

//引脚定义int clk =13;int cs=10;int din=11;//字模数组unsigned char disp1[4][8]={{0x00,0xFE,0x02,0x02,0xFA,0x82,0x82,0xF2},{0x80,0x80,0xFE,0x80,0xFC,0x00,0xFE,0x20},{0x00,0xFC,0x04,0x04,0x04,0xFC,0x40,0x40},{0x00,0x80,0xFE,0x02,0x04,0x00,0x00,0xFE},};unsigned char disp2[4][8]={{0x82,0xA2,0x92,0xFA,0x02,0x02,0xFE,0x02},{0x90,0x8C,0x92,0xE0,0x98,0x84,0x80,0x00},{0xFE,0x40,0x20,0x20,0x12,0x0A,0x06,0x02},{0x10,0x10,0x20,0x20,0xC0,0x30,0x08,0x04},};unsigned char disp4[4][8]={{0x00,0x3F,0x20,0x20,0x2F,0x20,0x20,0x27},{0x00,0x00,0x3F,0x00,0x1F,0x01,0x7F,0x02},{0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10},{0x01,0x00,0x1F,0x10,0x21,0x01,0x01,0x7F},};unsigned char disp3[4][8]={{0x20,0x20,0x20,0x2F,0x20,0x20,0x3F,0x20},{0x04,0x18,0x65,0x02,0x0C,0x30,0x02,0x01},{0x1F,0x10,0x10,0x10,0x12,0x14,0x18,0x10},{0x02,0x04,0x0C,0x03,0x00,0x01,0x06,0x38},};void setup(){pinMode(cs,OUTPUT);pinMode(clk,OUTPUT);pinMode(din,OUTPUT);Init_MAX7219();}void loop(){char i,j;//“国泰民安”轮流显示for(j=0;j<4;j++){for(i=1;i<9;i++){Write_Max7219_1(i,disp1[j][i-1]);Write_Max7219_2(i,disp2[j][i-1]);Write_Max7219_3(i,disp3[j][i-1]);Write_Max7219_4(i,disp4[j][i-1]);}delay(500);} }void Write_Max7219_byte(char DATA) {char i; digitalWrite(cs,0);for(i=8;i>=1;i--){digitalWrite(clk,0);if((DATA&0x80)>0) digitalWrite(din,1);else digitalWrite(din,0);//提取最高位给DIN端口DATA=DATA<<1;//左移一位digitalWrite(clk,1);} }void Write_Max7219_1(char address1,char dat1){digitalWrite(cs,0);Write_Max7219_byte(address1); //写入地址,即数码管编号Write_Max7219_byte(dat1);//写入数据,即数码管显示数字 digitalWrite(cs,1); }void Write_Max7219_2(char address2,char dat2){digitalWrite(cs,0);Write_Max7219_byte(address2); //写入地址,即数码管编号Write_Max7219_byte(dat2); //写入数据,即数码管显示数字 digitalWrite(clk,1);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);digitalWrite(cs,1);}void Write_Max7219_3(char address3,char dat3){digitalWrite(cs,0);Write_Max7219_byte(address3); //写入地址,即数码管编号Write_Max7219_byte(dat3); //写入数据,即数码管显示数字 digitalWrite(clk,1);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);digitalWrite(cs,1);}void Write_Max7219_4(char address4,char dat4){digitalWrite(cs,0);Write_Max7219_byte(address4); //写入地址,即数码管编号Write_Max7219_byte(dat4); //写入数据,即数码管显示数字 digitalWrite(clk,1);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);Write_Max7219_byte(0x00);digitalWrite(cs,1);}void Init_MAX7219(void){Write_Max7219_1(0x09, 0x00); //译码方式:BCD码Write_Max7219_1(0x0a, 0x01);//亮度 Write_Max7219_1(0x0b, 0x07); //扫描界限;8个数码管显示Write_Max7219_1(0x0c, 0x01); //掉电模式:0,普通模式:1Write_Max7219_1(0x0f, 0x00);Write_Max7219_2(0x09, 0x00);//译码方式:BCD码Write_Max7219_2(0x0a, 0x01);//亮度 Write_Max7219_2(0x0b, 0x07); //扫描界限;8个数码管显示Write_Max7219_2(0x0c, 0x01); //掉电模式:0,普通模式:1Write_Max7219_2(0x0f, 0x00);Write_Max7219_3(0x09, 0x00);//译码方式:BCD码Write_Max7219_3(0x0a, 0x01);//亮度 Write_Max7219_3(0x0b, 0x07); //扫描界限;8个数码管显示Write_Max7219_3(0x0c, 0x01); //掉电模式:0,普通模式:1Write_Max7219_3(0x0f, 0x00);Write_Max7219_4(0x09, 0x00);//译码方式:BCD码Write_Max7219_4(0x0a, 0x01);//亮度 Write_Max7219_4(0x0b, 0x07); //扫描界限;8个数码管显示Write_Max7219_4(0x0c, 0x01); //掉电模式:0,普通模式:1Write_Max7219_4(0x0f, 0x00);//显示测试:1;测试结束,正常显示:0delay(500); }

16x16汉字显示

程序效果如下

好了,赶快动手把你的点阵屏也玩起来吧。

8x8汉字取模和16x16汉字取模打包链接 → 字模资源链接

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。