动手学arduino(10)74HC595来控制数码管

有读者可能会问:为什么要用74HC595来控制数码管,是否多此一举?

上例中,用Arduino控制8个数码管,占用8个I/O端口。Arduino UNO只有 20个I/O口,仅数码管一个元件就占用8个端口,太浪费资源了。

使用74HC595的目的就是减少arduino I/O口的使用数量。引入74HC595后,可以用3个数字I/O口控制一个数码管,节约5个I/O口。

(下面一段看不懂没关系)

74HC595具有8位移位寄存器和一个存储器,三态输出功能。 移位寄存器和存储器有相互独立的时钟。数据在SH_cp(移位寄存器时钟输入)的上升沿输入到移位寄存器中,在ST_cp(存储器时钟输入)的上升沿输入到存储寄存器中去。如果两个时钟连在一起,则移位寄存器总是比存储寄存器早一个脉冲。移位寄存器有一个串行移位输入(Ds),和一个串行输出(Q7’),和一个异步的低电平复位,存储寄存器有一个并行8位的,具备三态的总线输出,当使能OE时(为低电平),存储寄存器的数据输出到总线。

动手学arduino(10)74HC595来控制数码管

74HC595接在arduino与数码管之间,起到桥梁作用。连接方法如下:

①数码管的ABCDEFGH依次接芯片的Q7-Q0(依次!),数码管COM1,COM2(3,8)接+5v。
动手学arduino(10)74HC595来控制数码管
②74HC595的16、10脚接5v,13,8脚接地,11,12,14脚接arduino三个端口(本例中为4,5,2),Q0-7接数码管,9脚为扩展引脚,本例中空着。动手学arduino(10)74HC595来控制数码管
图中数码管的限流电阻为560欧姆。如果用220欧姆,仿真时提示74HC595会烧毁,但实际电路中不会出现烧毁芯片的现象。
 

74HC595各引脚功能介绍(看不懂没关系)
GND接地,VCC接5V电源,这个就不用说了。
Q0-Q7这8根引脚是芯片的输出引脚,直接跟数码管的8段引脚相连。
DS是串行输入引脚,所谓串行就是使数据在一根信号线上按顺序一位一位地传输,就像一串糖葫芦。
SHCP是移位寄存器的时钟引脚。SHCP发生一次上升沿的时候,74HC595从DS引脚上取得当前的数据(高/低电平)并把取到的这一位数据保存到移位寄存器里。
当我们向芯片发送数据时,要先在DS引脚上准备好要传送的数据,然后制造一次SHCP引脚的上升沿(先拉低电平再拉高电平),74HC595会在这个上升沿将DS引脚上的数据存入移位寄存器D0,同时D0原来的数据会顺移到D1,D1的数据位移到D2…D6的数据位移到D7。而原先D7的数据已经没有地方储存了,这一位数据会被输出到引脚Q7S上。(注意这里说的不是输出引脚Q0-Q7,而是指内部的8位移位寄存器里每一个“小房间”,芯片手册上并没有给这些小房间编号,这里为了说明方便进行了编号)
STCP是芯片内部另外一个8位锁存寄存器的时钟引脚。当移位寄存器的8位数据全部传输完毕后,制造一次锁存器时钟引脚的上升沿(先拉低电平再拉高电平)。74HC595会在这个上升沿将移位寄存器里的8位数据复制到锁存器中(锁存器里原来的数据将被替换)。注意,到这里为止,这8位数据还只是被保存在锁存器里,并没有输出到数码管上。
OE是输出使能引脚,在其他芯片里也很常见。作用是控制锁存器里的数据是否最终输出到Q0-Q7输出引脚上。低电平时输出,高电平时不输出(既不是高电平,也不是低电平而是高阻态,不通电)。本例为了方便直接接在GND上使其一直保持低电平输出数据。
MR是用来重置内部寄存器的引脚。低电平时重置内部寄存器。本例为了方便直接连接在Vcc上一直保持高电平。
Q7S引脚,串行输出引脚,本例不使用。
 
仿真效果:

 

动手学arduino(8)数码管显示数字

段数码管拥有七个发光二极管用以显示十进制0至9的数字外加小数点,也可以显示英文字母,包括十六进制中的英文 A 至 F(b、d 为小写,其他为大写)。

七段数码管分为共阳极及共阴极,共阳极的七段数码管的正极(或阳极)为八个发光二极管的共有正极,其他接点为独立发光二极管的负极(或阴极),使用者只需把公共的正极接电源,A~H接地就能让七段数码管显示不同的内容。

如显示数字0,除G引脚接高电平,其余各引脚接低电平;若显示数字4,aed接高电平,FGBC接低电平。

动手学arduino(8)数码管显示数字

(图为共阴极数码管,共阳极的为公共端接正极)
由于数码管内发光器件为LED,所以各脚要串一个220欧姆的限流电阻。
动手学arduino(8)数码管显示数字
编写代码,驱动数码管显示数字“4”
动手学arduino(8)数码管显示数字
13~6脚分别接a~h,aed(13、10、9)接高电平,FGBC(12、11、8、7、6)接低电平。
动手学arduino(8)数码管显示数字
此种接法,占用大量端口,代码也冗长。应有更好的方法解决。
 

Arduino基础入门篇14—跳动的数码管

|

    阅读本文大概需要5分钟。

|

本篇介绍数码管显示器件,通过控制一位共阴极数码管动态显示数字0到9来了解数码管的使用。

1. 数码管介绍

数码管,又称LED数码管,是常见的用来显示数字的电子器件。通常由八段发光二极管封装在一起组成“8”字形状,外加一个小数点。数码管每一段都是一个独立的LED,通过控制相应段LED的亮灭使其组成相应数字形状来显示数字。

数码管的8个LED并联在一起,根据公共管脚的不同,分为共阳极数码管和共阴极数码管两种。其区别就是公共管脚是LED灯的正极还是负极。

Arduino基础入门篇14—跳动的数码管
数码管内部结构

如上图,数码管8个段分别命名为A,B,C,D,E,F,G,DP,其封装共10个引脚,其中上下方正中间的是公共极,其他引脚分别对应8个LED的另一端。

2. 实验材料

  • Uno R3开发板

  • 配套USB数据线

  • 面包板及配套连接线

  • 共阴极数码管

  • 1个220Ω限流电阻

Arduino基础入门篇14—跳动的数码管
数码管显示

那么如何让数码管来显示数字呢?比如显示数字0,我们只需要点亮A,B,C,D,E,F段LED,熄灭G,DP段LED即可。

3. 实验步骤

  1. 根据原理图搭建电路。

    数码管的A,B,C,D,E,F,G,DP引脚分别接入开发板的数字管脚7,6,5,10,11,8,9,4。数码管公共端接限流电阻,电阻另一端接GND。

    实验原理图如下图所示:

    Arduino基础入门篇14—跳动的数码管
    实验原理图g

    实物连接图如下图所示:

    Arduino基础入门篇14—跳动的数码管
    实物连接图
  2. 新建sketch,拷贝如下代码替换自动生成的代码并进行保存。

     1/*
    2      NixieTube
    3      控制共阴极数码管显示数字0到9
    4*/

    5
    6//设置控制各段的数字IO脚,具体几号引脚对应哪一段,来源为数码管官方引脚图。
    7int  pin_a  =  7;
    8int  pin_b  =  6;
    9int  pin_c  =  5;
    10int  pin_d  =  10;
    11int  pin_e  =  11;
    12int  pin_f  =  8;
    13int  pin_g  =  9;
    14int  pin_p  =  4;
    15
    16
    17//根据共阴极数码管段码表定义0~9显示的各段开关状态
    18int  numTable[10][8]  =  {
    19    //1为点亮,0为关闭
    20    //a    b    c    d    e    f    g    dp
    21    {11111100 },          //0
    22    {01100000 },          //1
    23    {11011010 },          //2
    24    {11110010 },          //3
    25    {01100110 },          //4
    26    {10110110 },          //5
    27    {10111110 },          //6
    28    {11100000 },          //7
    29    {11111110 },          //8
    30    {11110110 },          //9
    31 };
    32
    33
    34void  setup()
    35
    {
    36    for  (int  i  =  4;   i  <=  11;   i++)
    37    {
    38        pinMode(i,  OUTPUT);   //设置4~11引脚为输出模式
    39    }
    40 }
    41
    42void  loop()
    43
    {
    44    for  (int  i  =  0;   i  <  10;   i++)//以此显示数字0到9
    45    {
    46        digitalWrite(pin_a,  numTable[i][0]);   //设置a  引脚的电平
    47        digitalWrite(pin_b,  numTable[i][1]);   //设置b  引脚的电平
    48        digitalWrite(pin_c,  numTable[i][2]);   //设置c  引脚的电平
    49        digitalWrite(pin_d,  numTable[i][3]);   //设置d  引脚的电平
    50        digitalWrite(pin_e,  numTable[i][4]);   //设置e  引脚的电平
    51        digitalWrite(pin_f,  numTable[i][5]);   //设置f  引脚的电平
    52        digitalWrite(pin_g,  numTable[i][6]);   //设置g  引脚的电平
    53        digitalWrite(pin_p,  numTable[i][7]);   //设置dp引脚的电平
    54        delay(200);
    55    }
    56
    57 }
  3. 连接开发板,设置好对应端口号和开发板类型,进行程序下载。

    Arduino基础入门篇14—跳动的数码管
    程序下载


3. 实验现象

数码管循环显示数字0到9。

Arduino基础入门篇14—跳动的数码管
实验现象

4. 实验分析

程序中定义了一个二位数组用来存储0到9的段码显示。然后在loop中通过for()循环遍历显示0到9,每个数字分别读取对应的段码表来控制相应段LED的亮灭。

根据使用场所和需求的不同,LED被封装成不同类型的数码管,但其基本原理都是相同的,都需要控制每一个LED的亮灭最终拼凑成需要显示的数字、字母甚至是汉字。

Arduino基础入门篇14—跳动的数码管

扫码加入微信公众号:TonyCode


原文始发于微信公众号(

TonyCode

):Arduino基础入门篇14—跳动的数码管

|

Arduino 七段数码管显示方法一

我们要做什么

    我们需要让七段数码管显示数字0到9,而且不需要额外的IC,只使用Arduino+七段数码管(共阴极)+七个330欧电阻+一些跳线

本例用到byte数据类型和位操作运算,请参考下文:

arduino Byte数据类型和按位运算

数码管连接图及电路图

Arduino 七段数码管显示方法一

七段数码管引脚图

Arduino 七段数码管显示方法一

电路图

代码如下:

int pins[]={10,9,8,7,6,5,4,3 };

byte number[] ={

  //ABCDEFG /dp

  B11111100,  // 0

  B01100000,  // 1

  B11011010,  // 2

  B11110010,  // 3

  B01100110,  // 4

  B10110110,  // 5

  B10111110,  // 6

  B11100000,  // 7

  B11111110,  // 8

  B11110110,  // 9

};


void display(int num)

{

  for(int i=0;

i<8;

i++)

   {

     
digitalWrite(pins[i],bitRead(number[num],i));

   
}

}

void setup()

{

  for(int i=0;

i<8;

i++)

   {

      pinMode(pins[i],OUTPUT);

   
}

}


void loop()

{

  for(int i=0;

i<10;

i++){

  display(i);

 
delay(1000);

 
}

}

|

    这里的小数点默认是没有点亮的,如果需要点亮小数点的话,只需要,使用函数bitWrite(numer[num],0,1)就好了。

代码如下:

int pins[]={10,9,8,7,6,5,4,3 };

byte number[] ={

  //ABCDEFG /dp

  B11111100,  // 0

  B01100000,  // 1

  B11011010,  // 2

  B11110010,  // 3

  B01100110,  // 4

  B10110110,  // 5

  B10111110,  // 6

  B11100000,  // 7

  B11111110,  // 8

  B11110110,  // 9

};


void display(int num,bool dot)

{

  if(dot==true)

 {

    bitWrite(number[num],0,1);

   
}

    else

   {

      bitWrite(number[num],0,0);

     
}

  for(int i=0;

i<8;

i++)

   {      

     
digitalWrite(pins[i],bitRead(number[num],i));

   
}

}

void setup()

{

  for(int i=0;

i<8;

i++)

   {

      pinMode(pins[i],OUTPUT);

   
}

}


void loop()

{

  for(int i=0;

i<10;

i++){

  display(i,1);

 
delay(1000);

 
}

    for(int i=0;

i<10;

i++){

  display(i,0);

 
delay(1000);

 
}

}

|