【雕爷学编程】Arduino动手做(81)--- 8位LED数码管模块3

文章介绍了使用Arduino进行一系列传感器和执行器实验,特别是针对8位LED数码管MAX7219模块的实验,包括顺序显示数字、字母和符号。通过LedControl库,详细阐述了如何初始化、设置亮度和显示内容,以及库中各种函数的使用方法。实验代码展示了如何动态打印int值,提供了对Arduino编程和硬件控制的深入理解。
摘要由CSDN通过智能技术生成

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验八十一:8位LED数码管MAX7219模块(支持级联八位串行3个IO口控制)

在这里插入图片描述
在这里插入图片描述

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验八十一: 8位LED数码管MAX7219模块
项目:顺序显示23个数字、字母及符号

实验开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
   实验八十四: 8位LED数码管MAX7219模块
   项目之二:顺序显示23个数字、字母及符号
*/

#include "LedControl.h"
// Arduino 引脚 2 至DIN,4 至Clk,3 至ck,设备数量是1个
LedControl lc = LedControl(2, 4, 3, 1);

char chars[23] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',

                   'A', 'b', 'c', 'd', 'E', 'F', 'H', 'L', 'P',

                   '.', '-', '_'
                 };

void setup() {
  // 初始化 MAX7219 器件
  lc.shutdown(0, false); // 启用显示
  lc.setIntensity(0, 5); // 设置亮度级别(0 为最小值,15 为最大值)
  lc.clearDisplay(0);    // 清除显示寄存器
}

void loop() {
  for (int i = 0; i < 23; i++) {
    lc.setChar(0, 0, chars[i], false);
    delay(300);
  }
}

LedControl库使用说明

该库用于使用MAX7221 and MAX7219驱动的SPI总线88 LED显示屏及7段LED数码管。
定义一个对象最多可以驱动8块8
8LED显示屏(每块64个LED总共512个)或8个7段数码管,需占用三个Arduino的IO口。
如需驱动超过8个设备只能定义多个对象,但需要占用更多的IO口。

库函数:

LedControl(int dataPin, int clkPin, int csPin, int numDevices)

用途:初始化设备,设置DIN(dataPin)、CLK、CS的IO口及连接设备数量(既有多少块屏)并定义一个对象。
参数 :
dataPin 设置DIN口对应的Arduino上的IO口
clockPin 设置CLK口对应的Arduino上的IO口
csPin 设置CS口对应的Arduino上的IO口
numDevices 设置最大设备连接数(也就是8*8LED屏或者7段数码管模块的个数),只能设置1-8,如果需要连接超过8个设备,则需要定义另一个对象并使用另外的IO口。

例:LedControl lc=LedControl(12,11,10,1);
定义了一个名为lc的对象及设置接口DIN:12,CLK:11,CS:10,设备数量为1。

   LedControl lc1=LedControl(9,8,7,8);
    定义了一个名为lc1的对象及设置接口DIN:9,CLK:8,CS:7,设备数量为8。
int getDeviceCount()

用途:查询连接设备数量
返回值: 整数型,返回值为连接设备数量。

void shutdown(int addr, bool status);

在这里插入代码片

用途:设置(节电)模式。
参数:
addr 需设置的设备号,如:第一个设备为0,第二个设备为1等等。
status 如果为true则开启节电模式,为false则关闭。

例:lc.shutdown(0,true);
开启对象lc第一个设备的节电模式。

void setScanLimit(int addr, int limit);

用途:设置设备可显示的行数。
参数:
addr 设备号
limit 可显示的行数,原则上可设置为0-7,如超过7则变为8的余数,如设置为8余0则只显一行,9为两行等等。

例:lc.setScanLimit(0,7);
设置对象lc第一个设备可显示8行。

void setIntensity(int addr, int intensity);

用途:设置亮度。
参数:
addr 设备号
intensity 亮度值0-15

例:lc.setIntensity(0,8);
设置对象lc第一个设备的亮度为8。

void clearDisplay(int addr);

用途:清屏。
参数:
addr 设备号

例:lc.clearDisplay(0);
对象lc第一个设备清屏

以下三个函数为控制LED显示屏用的

void setLed(int addr, int row, int col, boolean state);

用途:设置其中一个LED的开关状态。
参数:
addr 设备号
row 要设置的LED行号,可设置0-7
col 要设置的LED列号,可设置0-7
state 如为true则LED开启,如为false则关闭

void setRow(int addr, int row, byte value);

用途:设置一行8个LED的开关状态
参数:
Addr 设备号
row 行号,可设置0-7
value LED亮灭数据,1为亮,0为灭,可只输入一个或多个数字(小于等于8个),LED按顺序亮灭,未输入部份默认为灭;还可以输入一个255以内的数值来表示LED的亮灭,因为每行或每列的不同LED都有一个1-128之间的值与其对应,对应关系如下表。

在这里插入图片描述

例:lc.setRow(0,0,01000000);
对象lc的第一个设备第一行第二个LED亮,其它灭,

为了方便编辑,最好用数组如:
Byte o[8]={B00011000,
B00100100,
B01000010,
B10000001,
B10000001,
B01000010,
B00100100,
B00011000};
来表示在一个8*8的LDE屏上显示“O”这个字符,调用时为:lc.setRow(0,0,o[0]);来表示第一行的LDE亮灭,
lc.setRow(0,1,o[1]);来表示第二行的LDE亮灭等等

   lc.setRow(0,2,146);
   对象lc的第一个设备第三行第一、四、七LED亮,其它它,计算方法如下:

在这里插入图片描述

这种方法可以简化数据录入,方便图形运算。

<span microsoft="" yahei",="" simsun;"="">void setColumn(int addr, int col, byte value);</span>

用途:设置一列8个LED的开关状态,与setRow输出的图形正好旋转90度。
参数:
addr 设备号
col 列号,可设置0-7
value LED亮灭数据,与setRow相同

下面两个函数是7段数码管用的

void setDigit(int addr, int digit, byte value, boolean dp);

用途:设置数码管显示十六进制数字
参数:
addr 设备号
digit 7段数码管号,可设置0-7
value 显示数据,为十六进制数,0-15(0x00-0x0F),其中0-9为数字,10-15为十六进制字符(0-F)
dp 开关 数码管上的小数点,turn为开,false为关

void setChar(int addr, int digit, char value, boolean dp);

用途:设置数码管显示字符
参数:
addr 设备号
digit 7段数码管号,可设置0-7
value 显示数据,直接输入’0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘0’, ‘A’,‘b’,‘c’,‘d’,‘E’,‘F’,‘H’,‘L’,‘P’,‘.’,‘-’,‘_’,’ '就可以在数码管上显示出来,虽然只能显示有限的字符,但是可以方便使用,请注意英文字母有的是大写有的是小写,不要搞错了,还有最后一个‘ ’是一个空格,别看漏了。
dp 开关数码管上的小数点,turn为开,false为关

创建LED 控件
所有库 API 函数都通过LedControl您必须在项目代码中创建的类型变量调用。
库初始化的典型代码如下所示:

/* 我们从包含库开始 */
#include "LedControl.h"

/*
* 现在我们创建一个新的 LedControl。
* 我们在 Arduino 上使用引脚 12,11 和 10 作为 SPI 接口
* 引脚 12 连接到第一个 MAX7221 的 DATA IN 引脚
* 引脚 11 连接到第一个 MAX7221 的 CLK 引脚
* 引脚 10 连接到第一个 MAX7221 的 LOAD(/CS) 引脚         
* 只有一个 MAX7221 连接到 arduino
*/
LedControl lc1=LedControl(12,11,10,1);

第一步是显而易见的。我们必须包含LedControl-library。
然后我们创建一个 type 实例,LedControl通过它我们与MAX72XX设备对话。an 的初始化需要 4 个参数。前 3 个参数是连接到MAX72XX的 Arduino 上的引脚编号。您可以自由选择 arduino 上的任何数字 IO 引脚,但由于某些引脚也用于串行通信或连接了 LED,因此最好避免引脚 0,1 和 13。这里选择引脚 12 ,11 和 10 在例子中。程序不会以任何方式检查引脚编号是否有效。传递一些愚蠢的东西(pin 123??)会破坏你的应用程序。您不必将引脚初始化为输出或将它们设置为特定状态,库会为您完成。

的第四个参数LedControl(dataPin,clockPin,csPin,numDevices)是与此 一起使用的级联MAX72XX设备的数量LedControl。该库可以从单个LedControl变量寻址多达 8 个设备。您添加到链中的每个设备都暗示了一点性能损失,但是库代码使用的内存量将保持不变,无论您设置多少个设备。由于LedControl不能寻址超过 8 个设备,因此此处只允许 1…8 之间的值。

这是一个新LedControl实例的原型:

/*
* 创建一个新的控制器
* 参数:
* int dataPin Arduino 上数据移出的引脚
* int clockPin 时钟的引脚
* int csPin 发送数据时选择设备的引脚
* int numDevices 可控制的最大设备数
*/
LedControl(int dataPin, int clkPin, int csPin, int numDevices);

无法从您的代码中读取引脚编号,但是有一个函数可以请求连接到LedControl。当您想要遍历连接的MAX72XX设备的完整列表时,这会非常方便。这是一段将所有MAX72XX器件从省电模式切换到正常操作的代码。

#include "LedControl.h"

// 为 5 个设备创建一个新的 LedControl...
LedControl lc1=LedControl(12,11,10,5);

void setup(){
  for(int index=0;index<lc1.getDeviceCount();index++) {
      lc1.shutdown(index,false);
  }
}

我们通过从 0 到 的索引迭代设备列表getDeviceCount()-1。在这段代码中,这将是 0 到 4。索引是每个设备的地址。此地址将是在设备上设置功能或新 (Led-) 值的每个函数的第一个参数。请记住,它getDeviceCount()返回连接的设备数量,但设备的地址从第一个开始,从 0 开始,第二个从 1 开始,getDeviceCount()-1最后一个从 1 开始。这是函数的原型:

/*
* 获取连接到此 LedControl 的最大设备数。
* 回报:
* int 连接到此 LedControl 的设备数量
*/

int LedControl::getDeviceCount();

省电模式
LED 点亮时会消耗相当多的能量。对于电池供电的设备,当用户不需要时,您肯定希望通过关闭整个显示器来节省电量。一个特殊的命令序列可以将MAX72XX置于关断模式。

设备将关闭显示屏上的所有LED,但数据会保留。您甚至可以在关机模式下继续发送新数据。稍后激活设备时,新数据将出现在您的显示器上。以下是7 段显示器上的不可见倒计时示例:

//创建一个新设备
LedControl lc=LedControl(12,11,10,1);

void countDown() {
  int i=9;
  lc.setDigit(0,(byte)i,false);
    //现在我们看到数字'9'
  delay(1000);
   //关闭显示...
  lc.shutdown(0,true);
    //并静默倒计时   
  while(i>1) {
     //数据更新,但不显示
    lc.setDigit(0,(byte)i,false);
    i--;
    delay(1000);
  }
  //当我们再次打开显示器时,我们已经达到了'1'
  lc.shutdown(0,false);
  lc.setDigit(0,(byte)i,false);
}

这是方法的原型 LedControl.shutdown(addr)

/*
* 设置设备的关机(省电)模式
* 参数:
* int addr 要控制的显示器地址
* boolean b 如果为真,设备进入掉电模式。如果 false
* 设备进入正常操作
*/

void shutdown(int addr, bool b);

请注意,MAX72XX总是在关断模式时,Arduino唤醒。

打印号码

7 段显示器最常见的用途是显示数字。我们看到的第一个函数接受一个字节类型的参数并在指定的列上打印相应的数字。有效值的范围从 0…15 开始。0…9 之间的所有值都打印为数字,10…15 之间的值打印为其等效的十六进制数。

任何其他值都将被忽略,这意味着不会打印任何内容。显示屏上的列不会空白,它只会保留其最后一个有效值。列上的小数点可以通过额外的参数打开或关闭。

这是一个小例子,它在一个 4 位数的显示器上打印一个 int 值 (-999…999)。

if (v < -999 || v > 999)
    return;
  if (v < 0) {
    negative = true;
    v = v * -1;
  }
  ones = v % 10;
  v = v / 10;
  tens = v % 10;
  v = v / 10;
  hundreds = v;
  if (negative) {
    //在最左边的列中打印字符 '-'
    lc.setChar(0, 3, '-', false);
  }
  else {
    //在符号列打印一个空白
    lc.setChar(0, 3, ' ', false);
  }
  //现在逐位打印数字
  lc.setDigit(0, 2, (byte)hundreds, false);
  lc.setDigit(0, 1, (byte)tens, false);
  lc.setDigit(0, 0, (byte)ones, false);
}

这是函数的原型:

/*
* 在 7 段显示器上显示(十六进制)数字
* 参数:
* 显示器的地址
* 数字 数字在显示器上的位置 (0..7)
* value 是要显示的值。(0x00..0x0F)
* dp 设置小数点。
*/

void setDigit(int addr, int digit, byte value, boolean dp);

-digit参数必须在0…7范围内,因为MAX72XX可以驱动多达 8 个 7 段显示器。索引像往常一样从 0 开始。

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验八十一: 8位LED数码管MAX7219模块
项目:动态打印一个 int 值 (-999…999)

实验开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
   实验八十四: 8位LED数码管MAX7219模块
   项目之三:打印一个 int 值 (-999..999)
*/

#include "LedControl.h"
// Arduino 引脚 2 至DIN,4 至Clk,3 至ck,设备数量是1个
LedControl lc = LedControl(2, 4, 3, 1);

void setup() {
  // 初始化 MAX7219 器件
  lc.shutdown(0, false); // 启用显示
  lc.setIntensity(0, 5); // 设置亮度级别(0 为最小值,15 为最大值)
  lc.clearDisplay(0);    // 清除显示寄存器
}

void printNumber(int v) {
  int ones;
  int tens;
  int hundreds;
  boolean negative;

  if (v < -999 || v > 999)
    return;
  if (v < 0) {
    negative = true;
    v = v * -1;
  }
  ones = v % 10;
  v = v / 10;
  tens = v % 10;
  v = v / 10;
  hundreds = v;
  if (negative) {
    //在最左边的列中打印字符 '-'
    lc.setChar(0, 3, '-', false);
  }
  else {
    //在符号列打印一个空白
    lc.setChar(0, 3, ' ', false);
  }
  //现在逐位打印数字
  lc.setDigit(0, 2, (byte)hundreds, false);
  lc.setDigit(0, 1, (byte)tens, false);
  lc.setDigit(0, 0, (byte)ones, false);
}

void loop() {
  for (int i = -999; i < 1000; i++) {
    printNumber(i);
    delay(50);
  }
}

Arduino实验场景图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驴友花雕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值