【雕爷学编程】Arduino 手册之高级 I/O 函数 shiftOut()

在这里插入图片描述
在这里插入图片描述
什么是Arduino?
Arduino 是一款开源的电子原型平台,它可以让你用简单的硬件和软件来创建各种创意的项目。无论你是初学者还是专家,Arduino 都能为你提供无限的可能性。你可以用 Arduino 来控制传感器、灯光、马达、机器人、物联网设备等等,只要你能想到的,Arduino 都能帮你实现。

如果你想了解更多关于 Arduino 的信息,你可以访问 Arduino 的官方网站,那里有丰富的资源和教程供你参考。你也可以加入 Arduino 的社区,和来自世界各地的爱好者、学生、设计师和工程师交流心得和经验。此外,你还可以使用 Arduino 的在线编程工具,在云端编写代码并上传到你的开发板上。

Arduino 是一个不断发展和创新的平台,它有着广泛的应用领域和潜力。这里希望本手册能激发你对 Arduino 的兴趣和热情,让你享受 Arduino 带来的创造力和乐趣

在这里插入图片描述

维基百科的定义
Arduino 是一个开源嵌入式硬件平台,用来供用户制作可交互式的嵌入式项目。此外 Arduino 作为一个开源硬件和开源软件的公司,同时兼有项目和用户社群。该公司负责设计和制造Arduino电路板及相关附件。这些产品按照GNU宽通用公共许可证(LGPL)或GNU通用公共许可证(GPL)许可的开源硬件和软件分发的,Arduino 允许任何人制造 Arduino 板和软件分发。 Arduino 板可以以预装的形式商业销售,也可以作为 DIY 套件购买。

Arduino 2005 年时面世,作为意大利伊夫雷亚地区伊夫雷亚互动设计研究所的学生设计,目的是为新手和专业人员提供一种低成本且简单的方法,以建立使用传感器与环境相互作用的装置。初学者和爱好者可用Arduino制造传感器、简单机器人、恒温器和运动检测器等装置。

Arduino 这个名字来自意大利伊夫雷亚的一家酒吧,该项目的一些创始人过去常常会去这家酒吧。 酒吧以伊夫雷亚的 Arduin(Arduin of Ivrea)命名,他是伊夫雷亚边疆伯爵,也是 1002 年至 1014 年期间的意大利国王。

在这里插入图片描述

十五、Arduino高级 I/O 函数 shiftOut()
Arduino高级 I/O shiftOut()是一种用于向数字引脚输出串行数据的函数。它通过将数据位串行地发送到移位寄存器的输入引脚,实现对多个输出引脚的并行控制。shiftOut()函数常用于扩展数字输出引脚,实现控制大量设备或执行并行操作的应用。shiftOut()的作用是让Arduino将一个字节(8位)的数据按照指定的顺序和时序,从一个数据引脚逐位输出到另一个时钟引脚,以便驱动或控制外部的设备或电路,例如移位寄存器、LED点阵、数码管等。

shiftOut()的使用范围有以下几种:
1)当需要向一个数字引脚输出多个二进制位的数据时,例如输出一个字符、一个数字、一个图案等。
2)当需要扩展Arduino的数字输出引脚时,例如使用移位寄存器来控制更多的LED灯、按钮、继电器等。
3)当需要与其他支持串行通信的设备或电路进行数据交换时,例如使用SPI协议来控制其他Arduino、传感器、显示器等。

应用场景:
1)扩展输出引脚:当需要控制大量输出设备时,Arduino的数字输出引脚数量可能不足。通过使用移位寄存器和shiftOut()函数,可以将数据位串行地发送到移位寄存器,并通过移位寄存器的输出引脚控制多个设备,实现输出引脚的扩展。这在LED显示屏、数码管、继电器等需要大量控制信号的应用中非常有用。
2)并行数据传输:有时需要将多个数据位并行传输到其他设备,例如驱动LCD显示屏或发送数据到其他微控制器。通过使用移位寄存器和shiftOut()函数,可以将多个数据位同时发送到目标设备,实现并行数据传输。这在需要高速数据传输或与其他设备进行通信的应用中非常有用。
3)控制输入设备:移位寄存器不仅可以用于输出控制,还可以用于输入控制。通过使用shiftOut()函数,可以从移位寄存器的输出引脚读取输入设备的状态。这在需要同时读取多个开关、按键或传感器状态的应用中非常有用。

使用shiftOut()时,需要注意以下事项:
1)shiftOut()函数的第一个参数是要输出数据的数字引脚的编号,可以是任意一个数字引脚。第二个参数是要输出时钟信号的数字引脚的编号,可以是任意一个数字引脚。第三个参数是要输出数据的顺序,可以是MSBFIRST(最高位先出)或LSBFIRST(最低位先出)。第四个参数是要输出的数据,可以是任意一个字节(8位)的值。
2)shiftOut()函数会根据指定的顺序和时序,将数据从数据引脚逐位输出到时钟引脚。每当时钟引脚从低电平变为高电平时,数据引脚会输出下一位数据。每当时钟引脚从高电平变为低电平时,外部设备或电路会读取当前位数据。这样,一共需要8个时钟周期才能输出完整的一个字节。
3)shiftOut()函数只能用于已经设置为输出模式的数字引脚,否则会导致不可预测的结果。要设置数字引脚的模式,可以使用pinMode()函数。
4)shiftOut()函数只能用于输出串行数据,不能用于接收串行数据。如果要接收串行数据,可以使用shiftIn()函数或其他方法。

以下是Arduino高级 I/O shiftOut()的三个实际运用程序案例:

案例一:使用shiftOut()实现移位寄存器的控制

// 定义三个常量DATA_PIN、CLOCK_PIN、LATCH_PIN,表示分别连接到移位寄存器的数据引脚、时钟引脚和锁存引脚
#define DATA_PIN 2
#define CLOCK_PIN 3
#define LATCH_PIN 4

void setup() {
    
    
  // 将DATA_PIN、CLOCK_PIN、LATCH_PIN三个引脚设为输出模式
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
}

void loop() {
    
    
  // 定义一个局部变量data,表示要输出到移位寄存器的数据,并初始化为0
  byte data = 0;
  
  // 循环从0到255
  for (data = 0; data <= 255; data++) {
    
    
    // 将LATCH_PIN引脚设为低电平,即开始传输数据
    digitalWrite(LATCH_PIN, LOW);
    // 向DATA_PIN和CLOCK_PIN两个引脚输出当前data值,顺序为最高位先出
    shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, data);
    // 将LATCH_PIN引脚设为高电平,即结束传输数据,并将移位寄存器的内容输出到其他设备或电路
    digitalWrite(LATCH_PIN, HIGH);
    // 等待100毫秒
    delay(100);
  }
}

案例二:使用shiftOut()实现LED点阵的显示

// 定义两个常量DATA_PIN、CLOCK_PIN,表示分别连接到LED点阵的数据引脚和时钟引脚
#define DATA_PIN 5
#define CLOCK_PIN 6

// 定义一个数组patterns,表示要显示在LED点阵上的图案,每个图案由8个字节组成,每个字节表示一行的亮灭状态
byte patterns[][8] = {
    
    
  {
    
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 空白
  {
    
    0x3C, 0x42, 0xA5, 0x81, 0xA5, 0x99, 0x42, 0x3C}, // 心形
  {
    
    0x3C, 0x7E, 0xDB, 0xFF, 0xFF, 0xDB, 0x7E, 0x3C}, // 圆形
  {
    
    0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3}, // 方形
};

void setup() {
    
    
  // 将DATA_PIN、CLOCK_PIN两个引脚设为输出模式
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
}

void loop() {
    
    
  // 定义一个局部变量i,表示图案的索引,并初始化为1
  int i = 1;
  
   // 循环遍历图案数组中的每个图案
   for (i = 1; i < sizeof(patterns) / sizeof(patterns[0]); i++) {
    
    
     // 定义一个局部变量j,表示图案中的字节索引,并初始化为0
     int j = 0;
     
     // 循环遍历图案中的每个字节
     for (j = 0; j < sizeof(patterns[i]) / sizeof(patterns[i][j]); j++) {
    
    
       // 向DATA_PIN和CLOCK_PIN两个引脚输出当前字节值,顺序为最高位先出
       shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, patterns[i][j]);
     }
     
     // 等待100毫秒
     delay(100);
   }
}

案例三:控制LED显示屏:

const int dataPin = 2;
const int latchPin = 3;
const int clockPin = 4;

void setup() {
    
    
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
    
    
  byte data = 0b11001100; // 要显示的数据
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, data); // 将数据发送到移位寄存器
  digitalWrite(latchPin, HIGH);
  delay(1000);
}

在此案例中,我们使用移位寄存器和shiftOut()函数来控制LED显示屏。通过将要显示的数据发送到移位寄存器,可以同时控制多个LED的亮灭状态。使用digitalWrite()函数控制锁存引脚(latchPin)将数据传输到LED显示屏。通过循环改变数据,可以实现动态显示效果。

案例四:驱动数码管:

const int dataPin = 2;
const int latchPin = 3;
const int clockPin = 4;

void setup() {
    
    
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
    
    
  int number = 1234; // 要显示的数字
  for (int i = 0; i < 4; i++) {
    
    
    int digit = number % 10; // 获取当前位的数字
    number /= 10; // 去掉最低位
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, digit); // 将数字发送到移位寄存器
    digitalWrite(latchPin, HIGH);
    delay(1000);
  }
}

在此案例中,我们使用移位寄存器和shiftOut()函数来驱动四位数码管。通过将要显示的数字的每一位依次发送到移位寄存器,可以在数码管上显示出数字。通过循环处理每一位数字,可以实现逐位显示的效果。

案例五:与其他微控制器通信:

const int dataPin = 2;
const int latchPin = 3;
const int clockPin = 4;

void setup() {
    
    
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
    
    
  byte dataToSend = 0b10101010; // 要发送的数据
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, dataToSend); // 将数据发送到移位寄存器
  digitalWrite(latchPin, HIGH);
  delay(1000);
}

在此案例中,我们使用移位寄存器和shiftOut()函数与其他微控制器进行通信。通过将要发送的数据位发送到移位寄存器,可以将数据传输到其他设备。这在需要与其他设备进行并行数据传输的应用中非常有用。

案例六:使用shiftOut()实现数码管的显示

// 定义三个常量DATA_PIN、CLOCK_PIN、LATCH_PIN,表示分别连接到数码管的数据引脚、时钟引脚和锁存引脚
#define DATA_PIN 7
#define CLOCK_PIN 8
#define LATCH_PIN 9

// 定义一个数组digits,表示要显示在数码管上的数字,每个数字由一个字节组成,每个字节表示七段的亮灭状态
byte digits[] = {
    
    
   B00111111, // 数字0
   B00000110, // 数字1
   B01011011, // 数字2
   B01001111, // 数字3
   B01100110, // 数字4
   B01101101, // 数字5
   B01111101, // 数字6
   B00000111, // 数字7
   B01111111, // 数字8
   B01101111, // 数字9 
};

void setup() {
    
    
   // 将DATA_PIN、CLOCK_PIN、LATCH_PIN三个引脚设为输出模式
   pinMode(DATA_PIN, OUTPUT);
   pinMode(CLOCK_PIN, OUTPUT);
   pinMode(LATCH_PIN, OUTPUT);
}

void loop() {
    
    
   // 定义一个局部变量number,表示要显示的数字,并初始化为1234
   int number = 1234;
   
   // 定义一个局部数组display,表示要显示的四个数字,并初始化为0
   byte display[4] = {
    
    0};
   
   // 将number分解为四个数字,并存入display数组中
   for (int i = 0; i < 4; i++) {
    
    
      display[i] = number % 10;
      number = number / 10;
   }
   
   // 将LATCH_PIN引脚设为低电平,即开始传输数据
   digitalWrite(LATCH_PIN, LOW);
   
   // 循环遍历display数组中的每个数字
   for (int i = 0; i < 4; i++) {
    
    
      // 向DATA_PIN和CLOCK_PIN两个引脚输出当前数字对应的七段状态,顺序为最低位先出
      shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, digits[display[i]]);
   }
   
    // 将LATCH_PIN引脚设为高电平,即结束传输数据,并将数码管的内容输出到其他设备或电路
    digitalWrite(LATCH_PIN, HIGH);
    
    // 等待1000毫秒
    delay(1000);
}

这些案例展示了shiftOut()函数在不同应用中的使用方法。通过使用移位寄存器和shiftOut()函数,可以实现对多个输出引脚的扩展、并行数据传输以及控制输入设备的功能。这为Arduino在控制和通信方面提供了更大的灵活性和扩展性。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41659040/article/details/132640342