、六弦 发表于 2013-6-3 17:51:25

74HC595实现四位数码管显示

本帖最后由 、六弦 于 2013-6-3 18:00 编辑

今天做了个数码管的显示,利用串行转并行的74hc595来驱动四个数码管,用arduino的定时器做了一个时钟,具体实现的功能是:串口与数码管同步时钟,利用串口发送时间数据可以调时。没有数码管也可以下载代码,从串口看输出时钟哦,也可以发送调时指令。(手机像素不好,大家将就着看看吧)。

//*************************************************************
// 实现功能:数码管显示时钟,通过串口设置时间(串口同步时钟)。
// 1.串口波特率设置为:9600
// 2.设置时间格式: Txxxxxx.例:12:34:56   发送:T123456
//*************************************************************

#include <TimerOne.h>
#define uchar unsigned char
#define SI_HdigitalWrite(4, HIGH)
#define SI_LdigitalWrite(4, LOW);
#define RCK_H digitalWrite(5, HIGH);
#define RCK_L digitalWrite(5, LOW);
#define SCK_H digitalWrite(6, HIGH);
#define SCK_L digitalWrite(6, LOW);
#define CS_HdigitalWrite(7, HIGH);
#define CS_LdigitalWrite(7, LOW);

uchar second,minute,hour;
String Rx = "";
uchar count[] =
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};

void port_init(void)
{
   pinMode(4, OUTPUT);
   pinMode(5, OUTPUT);
   pinMode(6, OUTPUT);
   pinMode(7, OUTPUT);
   
   pinMode(8, OUTPUT);
   pinMode(9, OUTPUT);
   pinMode(10, OUTPUT);
   pinMode(11, OUTPUT);
}

//num =0 / 1 / 2 / 3
//mode = HIGH -> open / LOW -> close
void SMG_select(uchar num,uchar mode)
{
if(num<4)
{
      switch(num)
      {
         case 0: num = 8; break;
         case 1: num = 9; break;
         case 2: num = 10;break;
         case 3: num = 11;break;
      }
      digitalWrite(num,mode);
}
}

void write_data(uchar data)
{
uchar i;
CS_H;
for(i=0;i<8;i++)
{
   if((data&0x80)==0x80)SI_H;
   else                   SI_L;
   SCK_H;
   delayMicroseconds(20);
   SCK_L;
   data=data<<1;
}
RCK_L;
delay(1);
RCK_H;
CS_L;
}

void set_time()
{
    while(Serial.available() >0)
    {
      Rx += char( Serial.read() );
      delay(2);
    }
   
    if (Rx.length() >0)
    {
      if(Rx==84)
      {
            hour   = (Rx-0x30)*10 + (Rx-0x30);
            minute = (Rx-0x30)*10 + (Rx-0x30);
            second = (Rx-0x30)*10 + (Rx-0x30);
      }
      Serial.println(" -----------------------");
      Serial.print("|Set Time: ");
      Serial.print(hour,DEC);
      Serial.print(":");
      Serial.print(minute,DEC);
      Serial.print(":");
      Serial.print(second,DEC);
      Serial.println("   |");
      Serial.println(" -----------------------");
      Rx = "";   
    }
}

void setup()
{
Serial.begin(9600);
port_init();
// pinMode(13, OUTPUT);
Timer1.initialize(1000000);
Timer1.attachInterrupt( timerIsr );
}

void timerIsr()
{
    //digitalWrite( 13, digitalRead( 13 ) ^ 1 );
    second++;
    if(second > 59)
    {
      second = 0;
      minute ++;
      if(minute > 59)
      {
      minute = 0;
      hour ++;
      if(hour > 23)   hour = 0;
      }
    }
    Serial.print("Time :");
    Serial.print(hour,DEC);
    Serial.print(":");
    Serial.print(minute,DEC);
    Serial.print(":");
    Serial.println(second,DEC);
}

void loop()
{
    set_time();
   
    SMG_select(0,HIGH);
    write_data(count);
    delayMicroseconds(400);
    SMG_select(0,LOW);
   
    SMG_select(1,HIGH);
    if(second%2) write_data(count + 0x80);
    else         write_data(count);
    delayMicroseconds(400);
    SMG_select(1,LOW);
   
    SMG_select(2,HIGH);
    write_data(count);
    delayMicroseconds(400);
    SMG_select(2,LOW);
   
    SMG_select(3,HIGH);
    write_data(count);
    delayMicroseconds(400);
    SMG_select(3,LOW);
}

FoieDEEEE_仲敬 发表于 2013-6-3 20:15:23

用595驱动4位太勉强了,仔细看第四位数码管和第三位的数字都要混在一起了!595驱动2位倒是不错

太行摄狼 发表于 2013-6-19 22:10:06

应该是ULN2003分时驱动,这样没问题的

bigmango 发表于 2013-6-20 21:19:25

FoieDEEEE_仲敬 发表于 2013-6-3 20:15 static/image/common/back.gif
用595驱动4位太勉强了,仔细看第四位数码管和第三位的数字都要混在一起了!595驱动2位倒是不错

对,感觉不是很实用,如果增加其它的程序就会闪的很厉害.就算最好情况下显示效果都不是很好.

jeanscyz 发表于 2014-2-28 16:50:33

这个不太明白,还要在研究下。

robingao 发表于 2015-10-13 11:13:10

FoieDEEEE_仲敬 发表于 2013-6-3 20:15 static/image/common/back.gif
用595驱动4位太勉强了,仔细看第四位数码管和第三位的数字都要混在一起了!595驱动2位倒是不错

第四位数码管和第三位的数字混在一起了,是因为每移位8bit就锁存一次,因此段选信号会在瞬间作为段显信号,所以明明不该亮起来的段会看起来微微亮,解决方法是段选和段显信号都发送完成之后再锁存。

asblue 发表于 2016-3-2 16:31:57

为什么不用连个595来驱动4位的呢?
页: [1]
查看完整版本: 74HC595实现四位数码管显示